discourse/plugins/discourse-ai/lib/ai_tool_scripts/presets/stock_quote.js
Sam 10d109e4c8
FEATURE: add credential bindings for AI tools (#37891)
Introduce a "secret contracts" system that lets AI tools
declare required credentials by alias and bind them to
existing AiSecret records via a new join table.

Key changes:
- New `ai_tool_secret_bindings` table and AiToolSecretBinding
  model linking AiTool to AiSecret by alias
- `secret_contracts` JSONB column on ai_tools for declaring
  required credential aliases
- `secrets.get(alias)` API available in tool scripts at
  runtime, with preloaded secret caching
- Admin UI for managing credential contracts and bindings on
  the tool editor form, with status badges on the tool list
- Tool presets (stock_quote, image generation) updated to use
  `secrets.get()` instead of hardcoded placeholder keys
- Secrets list editor shows tool usages alongside LLM and
  embedding usages
- Test modal supports passing secret bindings and rendering
  custom_raw output
- Validation, error handling, and i18n for contracts/bindings
- Persona import/export updated to include secret_contracts

---------

Co-authored-by: Keegan George <kgeorge13@gmail.com>
Co-authored-by: awesomerobot <kris.aubuchon@discourse.org>
2026-02-20 07:56:15 +11:00

33 lines
1 KiB
JavaScript
Vendored

/* eslint-disable no-undef, no-unused-vars */
function invoke(params) {
const apiKey = secrets.get("alphavantage_api_key");
const url = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${params.symbol}&apikey=${apiKey}`;
const result = http.get(url);
if (result.status !== 200) {
return { error: "Failed to fetch stock quote" };
}
const data = JSON.parse(result.body);
if (data["Error Message"]) {
return { error: data["Error Message"] };
}
const quote = data["Global Quote"];
if (!quote || Object.keys(quote).length === 0) {
return { error: "No data found for the given symbol" };
}
return {
symbol: quote["01. symbol"],
price: parseFloat(quote["05. price"]),
change: parseFloat(quote["09. change"]),
change_percent: quote["10. change percent"],
volume: parseInt(quote["06. volume"], 10),
latest_trading_day: quote["07. latest trading day"],
};
}
function details() {
return "<a href='https://www.alphavantage.co'>Stock data provided by AlphaVantage</a>";
}