UNPKG

braiin

Version:

Behavioral Reasoning AI for Intelligent Navigation

151 lines (150 loc) 7.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Orchestrator = void 0; const string_factory_1 = require("../factory/string.factory"); const timer_1 = require("../service/timer"); const llm_1 = require("../model/llm"); class Orchestrator { constructor(agents, config) { this.globalContext = ''; const { optionalPrompt, temperature = 0, apiKey, serverUrl = 'https://api.openai.com/v1/chat/completions', model = 'gpt-4o', stepsInterval } = config; this.stepsInterval = stepsInterval; this.questioner = async (systemPrompt, prompt, history, callback) => { const messages = [ { role: 'system', content: systemPrompt }, ...history, { role: 'user', content: prompt } ]; const response = await fetch(serverUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` }, body: JSON.stringify({ model, messages, stream: callback ? true : false, max_tokens: 8192, temperature }) }); if (callback) { if (!response.body) { callback('[[END]]'); return; } const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { value, done } = await reader.read(); if (done) break; const chunk = decoder.decode(value, { stream: true }); chunk.split('\n').forEach(line => { if (line.startsWith('data: ')) { const jsonStr = line.replace('data: ', '').trim(); if (jsonStr === '[DONE]') return; try { const json = JSON.parse(jsonStr); const text = json.choices?.[0]?.delta?.content; text && callback(text); } catch (error) { console.error('Error parsing JSON response'); } } }); } callback('[[END]]'); } else { const finalResponse = await response.json(); return finalResponse; } }; this.agents = agents; this.globalContext = 'You are a useful agent that the purpose is to answer questions about a specific topic.' + 'For that purpose you have a set of agents that are specialized in different topic in order to help you solve each task: ' + JSON.stringify(agents.map(agent => ({ name: agent.name, description: agent.description, tools: agent.getTools().map(tl => tl.tag) }))) + '.' + 'Each agent has different tools to solve one specific task, you will have to ask the dedicated agent each time what are its tools and how to use them before calling them.' + 'To get the agent\'s tools descriptions just send me the following json {"action": "describe","agent": "agent\'name"}.' + 'If you want to use a specific tool, send me the following json: {"agent":"agent\'s name","tool":"agent\'s tag","input":"agent\'s input"} and I will do the task for you.' + 'Loop through all this until you have the final answer.' + 'If you can\'t resolve the task, just send me the following json: {"tool":"none","input":"explication on why you cannot help"}.' + 'If you have the final answer, send me the following: {"tool":"finished","input":"the final result"}.' + 'Don\'t explain the process of what you are doing, just do it and always exchange json objects with me and always use the language I am using to communicate with you.' + optionalPrompt || ''; } async chain(prompt, history, logCallback) { this.stepsInterval && await (0, timer_1.freeze)(this.stepsInterval); const answer = await this.questioner(this.globalContext, prompt, history); if (answer?.error) { return `An error occured when calling the LLM ${answer.error.message}`; } const actualResponse = answer ? (0, string_factory_1.removeInfoStrings)(answer.choices[0].message.content).trim() : ''; logCallback && logCallback(actualResponse); if (actualResponse.startsWith('{')) { const { action, agent, tool, input } = JSON.parse(actualResponse); if (action === 'describe') { const actualAgent = this.agents.find(agt => agt.name === agent); if (actualAgent) { return await this.chain(JSON.stringify(actualAgent.getTools()), [ ...history, { role: llm_1.LLMMessageRole.USER, content: prompt }, { role: llm_1.LLMMessageRole.ASSISTANT, content: actualResponse }, ], logCallback); } else { logCallback && logCallback('No matching agent found for this task'); return 'No matching agent found for this task'; } } else { if (agent) { const actualAgent = this.agents.find(agt => agt.name === agent); if (actualAgent) { const actualTool = actualAgent.getTools().find(tl => tl.tag === tool); if (actualTool) { const toolResponse = await actualTool.call(input); return this.chain(toolResponse, [ ...history, { role: llm_1.LLMMessageRole.USER, content: prompt }, { role: llm_1.LLMMessageRole.ASSISTANT, content: actualResponse }, { role: llm_1.LLMMessageRole.USER, content: `tool response: ${toolResponse}` } ], logCallback); } else { logCallback && logCallback('No matching tool found for this task'); return 'No matching tool found for this task'; } } else { logCallback && logCallback('No matching agent found for this task'); return 'No matching agent found for this task'; } } else { return input; } } } return 'Data in wrong format ' + actualResponse; } async executeTask(prompt, history, logCallback) { return this.chain(prompt, [ ...(history || []) ], logCallback); } async askLLM(systemPrompt, prompt, history, logCallback) { return this.questioner(systemPrompt, prompt, history || [], logCallback); } } exports.Orchestrator = Orchestrator;