diff --git a/examples/01-agent-code-skill/04.1-chat-planner-coder.ts b/examples/01-agent-code-skill/04.1-chat-planner-coder.ts index d11daacc..5087c6fc 100644 --- a/examples/01-agent-code-skill/04.1-chat-planner-coder.ts +++ b/examples/01-agent-code-skill/04.1-chat-planner-coder.ts @@ -1,7 +1,7 @@ import { Agent, Chat, Component, Model, TAgentMode, TLLMEvent } from '@smythos/sdk'; import chalk from 'chalk'; import * as readline from 'readline'; -import { EmitUnit, PluginAPI, PluginBase, TokenLoom } from 'tokenloom'; +import { EmitUnit, PluginBase, TokenLoom } from 'tokenloom'; //Show the tasks list and status to the user at every step before performing the tasks, and also give a tasks status summary after tasks. //When you display the tasks list to a user show it in a concise way with a summary and checkboxes for each task. diff --git a/examples/03-agent-workflow-components/01-workflow.ts b/examples/03-agent-workflow-components/01-workflow.ts index 81652d3e..b18a730d 100644 --- a/examples/03-agent-workflow-components/01-workflow.ts +++ b/examples/03-agent-workflow-components/01-workflow.ts @@ -16,6 +16,7 @@ async function main() { const mdSkill = agent.addSkill({ name: 'MarketData', description: 'Use this skill to get comprehensive market data and statistics for a cryptocurrency', + status_message: 'Getting market data...', }); //Defining the inputs of the skill diff --git a/examples/agents-data/crypto-info-agent.smyth b/examples/agents-data/crypto-info-agent.smyth index 9adcde84..5fb57c45 100644 --- a/examples/agents-data/crypto-info-agent.smyth +++ b/examples/agents-data/crypto-info-agent.smyth @@ -1 +1 @@ -{"version":"1.0.0","id":"cmbhu1l6c2qgv12er6xei99vz","name":"Crypto Info Agent","teamId":"9","parentTeamId":"9","components":[{"id":"CS001","name":"APIEndpoint","outputs":[{"name":"headers","color":"#3C89F9","index":0,"default":true},{"name":"body","color":"#3C89F9","index":1,"default":true},{"name":"query","color":"#3C89F9","index":2,"default":true},{"name":"query.query","color":"#3C89F9","index":3,"default":false}],"inputs":[{"name":"query","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"endpoint":"search_coins","description":"Search for cryptocurrencies by name or symbol","method":"GET","ai_exposed":true,"advancedModeEnabled":true,"endpointLabel":"","summary":""},"top":"0px","left":"50px","width":"","height":"","displayName":"APIEndpoint","title":"Search Coins","aiTitle":"","description":"Search for coins by name or symbol"},{"id":"CS002","name":"APICall","outputs":[{"name":"Response","color":"#3C89F9","index":0,"default":true},{"name":"Headers","color":"#3C89F9","index":1,"default":true},{"name":"Response.coins","color":"#3C89F9","index":2,"default":false}],"inputs":[{"name":"search_query","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"method":"GET","url":"https://api.coingecko.com/api/v3/search?query={{search_query}}","contentType":"application/json","oauthService":"None","scope":"","authorizationURL":"","tokenURL":"","clientID":"","clientSecret":"","requestTokenURL":"","accessTokenURL":"","userAuthorizationURL":"","consumerKey":"","consumerSecret":""},"top":"0px","left":"500px","width":"","height":"","displayName":"APICall","title":"CoinGecko Search","aiTitle":"","description":"Call CoinGecko search API"},{"id":"CS003","name":"APIOutput","outputs":[{"name":"Output","color":"#3C89F9","index":0,"default":true}],"inputs":[{"name":"coins","type":"Any","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"format":"minimal"},"top":"0px","left":"950px","width":"","height":"","displayName":"APIOutput","title":"Search Results","aiTitle":"","description":"Format search results"},{"id":"CP001","name":"APIEndpoint","outputs":[{"name":"headers","color":"#3C89F9","index":0,"default":true},{"name":"body","color":"#3C89F9","index":1,"default":true},{"name":"query","color":"#3C89F9","index":2,"default":true},{"name":"query.coin_id","color":"#3C89F9","index":3,"default":false}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"endpoint":"get_price","description":"Get the current price of a cryptocurrency in USD","method":"GET","ai_exposed":true,"advancedModeEnabled":true,"endpointLabel":"","summary":""},"top":"387px","left":"50px","width":"","height":"","displayName":"APIEndpoint","title":"Get Price","aiTitle":"","description":"Get current price in USD"},{"id":"CP002","name":"APICall","outputs":[{"name":"Response","color":"#3C89F9","index":0,"default":true},{"name":"Headers","color":"#3C89F9","index":1,"default":true}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"method":"GET","url":"https://api.coingecko.com/api/v3/simple/price?ids={{coin_id}}&vs_currencies=usd","contentType":"application/json","oauthService":"None","scope":"","authorizationURL":"","tokenURL":"","clientID":"","clientSecret":"","requestTokenURL":"","accessTokenURL":"","userAuthorizationURL":"","consumerKey":"","consumerSecret":""},"top":"387px","left":"500px","width":"","height":"","displayName":"APICall","title":"CoinGecko Price","aiTitle":"","description":"Call CoinGecko price API"},{"id":"CP003","name":"APIOutput","outputs":[{"name":"Output","color":"#3C89F9","index":0,"default":true}],"inputs":[{"name":"price_data","type":"Any","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"format":"minimal"},"top":"387px","left":"950px","width":"","height":"","displayName":"APIOutput","title":"Price Data","aiTitle":"","description":"Format price data"},{"id":"CM001","name":"APIEndpoint","outputs":[{"name":"headers","color":"#3C89F9","index":0,"default":true},{"name":"body","color":"#3C89F9","index":1,"default":true},{"name":"query","color":"#3C89F9","index":2,"default":true},{"name":"query.coin_id","color":"#3C89F9","index":3,"default":false}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"endpoint":"get_market_info","description":"Get detailed market information for a cryptocurrency","method":"GET","ai_exposed":true,"advancedModeEnabled":true,"endpointLabel":"","summary":""},"top":"774px","left":"50px","width":"","height":"","displayName":"APIEndpoint","title":"Market Info","aiTitle":"","description":"Get market information"},{"id":"CM002","name":"APICall","outputs":[{"name":"Response","color":"#3C89F9","index":0,"default":true},{"name":"Headers","color":"#3C89F9","index":1,"default":true},{"name":"Response.market_data","color":"#3C89F9","index":2,"default":false}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"method":"GET","url":"https://api.coingecko.com/api/v3/coins/{{coin_id}}?localization=false&tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false","contentType":"application/json","oauthService":"None","scope":"","authorizationURL":"","tokenURL":"","clientID":"","clientSecret":"","requestTokenURL":"","accessTokenURL":"","userAuthorizationURL":"","consumerKey":"","consumerSecret":""},"top":"774px","left":"500px","width":"","height":"","displayName":"APICall","title":"CoinGecko Market","aiTitle":"","description":"Call CoinGecko market data API"},{"id":"CM003","name":"APIOutput","outputs":[{"name":"Output","color":"#3C89F9","index":0,"default":true}],"inputs":[{"name":"market_data","type":"Any","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"format":"minimal"},"top":"774px","left":"950px","width":"","height":"","displayName":"APIOutput","title":"Market Data","aiTitle":"","description":"Format market data"}],"connections":[{"sourceId":"CS001","sourceIndex":3,"targetId":"CS002","targetIndex":0},{"sourceId":"CS002","sourceIndex":2,"targetId":"CS003","targetIndex":0},{"sourceId":"CP001","sourceIndex":3,"targetId":"CP002","targetIndex":0},{"sourceId":"CP002","sourceIndex":0,"targetId":"CP003","targetIndex":0},{"sourceId":"CM001","sourceIndex":3,"targetId":"CM002","targetIndex":0},{"sourceId":"CM002","sourceIndex":2,"targetId":"CM003","targetIndex":0}],"description":"","shortDescription":"","behavior":"I am a cryptocurrency information assistant that uses the CoinGecko API. I can help you search for cryptocurrencies by name or symbol, check current prices in USD, and get detailed market information for specific coins. I will provide accurate and up-to-date information from CoinGecko's database. If you're looking for crypto market data, just ask me about any coin and I'll retrieve the information for you.","ui":{"panzoom":{"currentPan":{"x":378.032470703125,"y":-260.9026702880859},"currentZoom":0.5},"agentCard":{"left":"-745px","top":"112px"}},"introMessage":"Hi, I'm Crypto Info Agent. How can I help you today?","templateInfo":{"id":"crypto-info-agent-mbhwct4hp","name":"Crypto Info Agent","description":"","icon":"","category":"","publish":false,"color":"#000000","imageUrl":"","docLink":"","videoLink":"","valueProposition":""}} \ No newline at end of file +{"version":"1.0.0","id":"cmbhu1l6c2qgv12er6xei99vz","name":"Crypto Info Agent","teamId":"9","parentTeamId":"9","components":[{"id":"CS001","name":"APIEndpoint","outputs":[{"name":"headers","color":"#3C89F9","index":0,"default":true},{"name":"body","color":"#3C89F9","index":1,"default":true},{"name":"query","color":"#3C89F9","index":2,"default":true},{"name":"query.query","color":"#3C89F9","index":3,"default":false}],"inputs":[{"name":"query","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"endpoint":"search_coins","status_message":"Coin search ...", "description":"Search for cryptocurrencies by name or symbol","method":"GET","ai_exposed":true,"advancedModeEnabled":true,"endpointLabel":"","summary":""},"top":"0px","left":"50px","width":"","height":"","displayName":"APIEndpoint","title":"Search Coins","aiTitle":"","description":"Search for coins by name or symbol"},{"id":"CS002","name":"APICall","outputs":[{"name":"Response","color":"#3C89F9","index":0,"default":true},{"name":"Headers","color":"#3C89F9","index":1,"default":true},{"name":"Response.coins","color":"#3C89F9","index":2,"default":false}],"inputs":[{"name":"search_query","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"method":"GET","url":"https://api.coingecko.com/api/v3/search?query={{search_query}}","contentType":"application/json","oauthService":"None","scope":"","authorizationURL":"","tokenURL":"","clientID":"","clientSecret":"","requestTokenURL":"","accessTokenURL":"","userAuthorizationURL":"","consumerKey":"","consumerSecret":""},"top":"0px","left":"500px","width":"","height":"","displayName":"APICall","title":"CoinGecko Search","aiTitle":"","description":"Call CoinGecko search API"},{"id":"CS003","name":"APIOutput","outputs":[{"name":"Output","color":"#3C89F9","index":0,"default":true}],"inputs":[{"name":"coins","type":"Any","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"format":"minimal"},"top":"0px","left":"950px","width":"","height":"","displayName":"APIOutput","title":"Search Results","aiTitle":"","description":"Format search results"},{"id":"CP001","name":"APIEndpoint","outputs":[{"name":"headers","color":"#3C89F9","index":0,"default":true},{"name":"body","color":"#3C89F9","index":1,"default":true},{"name":"query","color":"#3C89F9","index":2,"default":true},{"name":"query.coin_id","color":"#3C89F9","index":3,"default":false}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"endpoint":"get_price","status_message":"Getting Price ...","description":"Get the current price of a cryptocurrency in USD","method":"GET","ai_exposed":true,"advancedModeEnabled":true,"endpointLabel":"","summary":""},"top":"387px","left":"50px","width":"","height":"","displayName":"APIEndpoint","title":"Get Price","aiTitle":"","description":"Get current price in USD"},{"id":"CP002","name":"APICall","outputs":[{"name":"Response","color":"#3C89F9","index":0,"default":true},{"name":"Headers","color":"#3C89F9","index":1,"default":true}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"method":"GET","url":"https://api.coingecko.com/api/v3/simple/price?ids={{coin_id}}&vs_currencies=usd","contentType":"application/json","oauthService":"None","scope":"","authorizationURL":"","tokenURL":"","clientID":"","clientSecret":"","requestTokenURL":"","accessTokenURL":"","userAuthorizationURL":"","consumerKey":"","consumerSecret":""},"top":"387px","left":"500px","width":"","height":"","displayName":"APICall","title":"CoinGecko Price","aiTitle":"","description":"Call CoinGecko price API"},{"id":"CP003","name":"APIOutput","outputs":[{"name":"Output","color":"#3C89F9","index":0,"default":true}],"inputs":[{"name":"price_data","type":"Any","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"format":"minimal"},"top":"387px","left":"950px","width":"","height":"","displayName":"APIOutput","title":"Price Data","aiTitle":"","description":"Format price data"},{"id":"CM001","name":"APIEndpoint","outputs":[{"name":"headers","color":"#3C89F9","index":0,"default":true},{"name":"body","color":"#3C89F9","index":1,"default":true},{"name":"query","color":"#3C89F9","index":2,"default":true},{"name":"query.coin_id","color":"#3C89F9","index":3,"default":false}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"endpoint":"get_market_info","description":"Get detailed market information for a cryptocurrency","method":"GET","ai_exposed":true,"advancedModeEnabled":true,"endpointLabel":"","summary":""},"top":"774px","left":"50px","width":"","height":"","displayName":"APIEndpoint","title":"Market Info","aiTitle":"","description":"Get market information"},{"id":"CM002","name":"APICall","outputs":[{"name":"Response","color":"#3C89F9","index":0,"default":true},{"name":"Headers","color":"#3C89F9","index":1,"default":true},{"name":"Response.market_data","color":"#3C89F9","index":2,"default":false}],"inputs":[{"name":"coin_id","type":"String","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"method":"GET","url":"https://api.coingecko.com/api/v3/coins/{{coin_id}}?localization=false&tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false","contentType":"application/json","oauthService":"None","scope":"","authorizationURL":"","tokenURL":"","clientID":"","clientSecret":"","requestTokenURL":"","accessTokenURL":"","userAuthorizationURL":"","consumerKey":"","consumerSecret":""},"top":"774px","left":"500px","width":"","height":"","displayName":"APICall","title":"CoinGecko Market","aiTitle":"","description":"Call CoinGecko market data API"},{"id":"CM003","name":"APIOutput","outputs":[{"name":"Output","color":"#3C89F9","index":0,"default":true}],"inputs":[{"name":"market_data","type":"Any","friendlyInputType":"","coreInputType":"","color":"#F35063","optional":false,"index":0,"default":false}],"data":{"format":"minimal"},"top":"774px","left":"950px","width":"","height":"","displayName":"APIOutput","title":"Market Data","aiTitle":"","description":"Format market data"}],"connections":[{"sourceId":"CS001","sourceIndex":3,"targetId":"CS002","targetIndex":0},{"sourceId":"CS002","sourceIndex":2,"targetId":"CS003","targetIndex":0},{"sourceId":"CP001","sourceIndex":3,"targetId":"CP002","targetIndex":0},{"sourceId":"CP002","sourceIndex":0,"targetId":"CP003","targetIndex":0},{"sourceId":"CM001","sourceIndex":3,"targetId":"CM002","targetIndex":0},{"sourceId":"CM002","sourceIndex":2,"targetId":"CM003","targetIndex":0}],"description":"","shortDescription":"","behavior":"I am a cryptocurrency information assistant that uses the CoinGecko API. I can help you search for cryptocurrencies by name or symbol, check current prices in USD, and get detailed market information for specific coins. I will provide accurate and up-to-date information from CoinGecko's database. If you're looking for crypto market data, just ask me about any coin and I'll retrieve the information for you.","ui":{"panzoom":{"currentPan":{"x":378.032470703125,"y":-260.9026702880859},"currentZoom":0.5},"agentCard":{"left":"-745px","top":"112px"}},"introMessage":"Hi, I'm Crypto Info Agent. How can I help you today?","templateInfo":{"id":"crypto-info-agent-mbhwct4hp","name":"Crypto Info Agent","description":"","icon":"","category":"","publish":false,"color":"#000000","imageUrl":"","docLink":"","videoLink":"","valueProposition":""}} \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json index 0f3e4ba4..d09776ab 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@smythos/sre", - "version": "1.5.63", + "version": "1.5.64", "description": "Smyth Runtime Environment", "author": "Alaa-eddine KADDOURI", "license": "MIT", diff --git a/packages/core/src/Components/APICall/APICall.class.ts b/packages/core/src/Components/APICall/APICall.class.ts index d4d5f957..4112af74 100644 --- a/packages/core/src/Components/APICall/APICall.class.ts +++ b/packages/core/src/Components/APICall/APICall.class.ts @@ -117,8 +117,8 @@ export class APICall extends Component { // To support both old and new OAuth configuration, we check for both oauth_con_id and oauthService. logger.debug('checking oauth config', config?.data?.oauth_con_id, config?.data?.oauthService); if ( - (config?.data?.oauth_con_id !== undefined && config?.data?.oauth_con_id !== '' && config?.data?.oauth_con_id !== 'None') || - (config?.data?.oauthService !== '' && config.data.oauthService !== 'None') + (config?.data?.oauth_con_id && config.data.oauth_con_id !== 'None') || + (config?.data?.oauthService && config.data.oauthService !== 'None') ) { const additionalParams = extractAdditionalParamsForOAuth1(reqConfig); const oauthHeaders = await generateOAuthHeaders(agent, config, reqConfig, logger, additionalParams); diff --git a/packages/core/src/helpers/Conversation.helper.ts b/packages/core/src/helpers/Conversation.helper.ts index 005e0152..70aa8d82 100644 --- a/packages/core/src/helpers/Conversation.helper.ts +++ b/packages/core/src/helpers/Conversation.helper.ts @@ -52,6 +52,7 @@ export class Conversation extends EventEmitter { private _reqMethods; private _toolsConfig; + private _toolStatusMap: Record = {}; private _endpoints; private _baseUrl; @@ -459,7 +460,9 @@ export class Conversation extends EventEmitter { //await beforeFunctionCall(llmMessage, toolsData[tool.index]); // TODO [Forhad]: Make sure toolsData[tool.index] and tool do the same thing this.emit('beforeToolCall', { tool, args }, llmMessage); //deprecated - this.emit(TLLMEvent.ToolCall, { tool, _llmRequest: llmMessage }); + + const status = tool.name ? this._toolStatusMap?.[tool.name] : undefined; + this.emit(TLLMEvent.ToolCall, { tool, status, _llmRequest: llmMessage }); const toolArgs = { type: tool?.type, @@ -981,6 +984,16 @@ export class Conversation extends EventEmitter { this.systemPrompt = `Assistant Name : ${this.assistantName}\n\n${this.systemPrompt}`; } + this._toolStatusMap = agentData?.data?.components + ?.filter((component) => component.name === 'APIEndpoint') + .reduce((map, component) => { + if (component?.data?.endpoint) { + map[component.data.endpoint] = + component?.data?.status_message || `Calling ${component?.data?.endpointLabel || component.data.endpoint}`; + } + return map; + }, {}); + const spec = await agentDataConnector.getOpenAPIJSON(agentData, 'http://localhost/', this._agentVersion, true).catch((error) => null); return this.patchSpec(spec); } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index ca3f5d4a..ef2aad17 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@smythos/sdk", - "version": "1.1.4", + "version": "1.1.6", "description": "SRE SDK", "keywords": [ "smythos", diff --git a/packages/sdk/src/Agent/Agent.class.ts b/packages/sdk/src/Agent/Agent.class.ts index 941bab97..ff462175 100644 --- a/packages/sdk/src/Agent/Agent.class.ts +++ b/packages/sdk/src/Agent/Agent.class.ts @@ -203,6 +203,7 @@ class AgentCommand { conversation.on(TLLMEvent.ToolCall, toolCallHandler); conversation.on(TLLMEvent.ToolResult, toolResultHandler); + conversation.on(TLLMEvent.Usage, usageHandler); conversation.on(TLLMEvent.End, endHandler); conversation.on(TLLMEvent.Error, errorHandler); conversation.on(TLLMEvent.Content, contentHandler); diff --git a/packages/sdk/src/Components/Skill.ts b/packages/sdk/src/Components/Skill.ts index 7276dc49..0d8ad31f 100644 --- a/packages/sdk/src/Components/Skill.ts +++ b/packages/sdk/src/Components/Skill.ts @@ -7,10 +7,10 @@ function normalizeEndpointName(name: string) { return name.replace(/[^a-zA-Z0-9]/g, '_'); } - export type TSkillSettings = { name: string; endpoint?: string; + status_message?: string; ai_exposed?: boolean; description?: string; method?: 'GET' | 'POST' | 'PUT' | 'DELETE'; @@ -30,6 +30,7 @@ export function Skill(settings?: TSkillSettings, agent?: Agent) { settings: { ...settingsWithoutName, endpoint: normalizeEndpointName(settings?.endpoint || settings?.name), + status_message: settings?.status_message || '', ai_exposed: settings?.ai_exposed || true, method: settings?.method || 'POST', }, diff --git a/packages/sdk/src/LLM/Chat.class.ts b/packages/sdk/src/LLM/Chat.class.ts index e7c20b6a..6e562564 100644 --- a/packages/sdk/src/LLM/Chat.class.ts +++ b/packages/sdk/src/LLM/Chat.class.ts @@ -137,6 +137,7 @@ class ChatCommand { this._conversation.on(TLLMEvent.ToolCall, toolCallHandler); this._conversation.on(TLLMEvent.ToolResult, toolResultHandler); + this._conversation.on(TLLMEvent.Usage, usageHandler); this._conversation.on(TLLMEvent.End, endHandler); this._conversation.on(TLLMEvent.Error, errorHandler); this._conversation.on(TLLMEvent.Content, contentHandler);