UNPKG

@nomyx/assistant

Version:

A powerful assistant library and cli for your AI projects. works with Vertex AI (Claude and Gemini)

90 lines (89 loc) 3.71 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.chat = chat; const axios_1 = __importDefault(require("axios")); const tools_1 = require("./tools"); async function chat(config, messages, options, tools) { const url = config.getApiUrl(); const convertedMessages = (0, tools_1.convertMessages)(messages); const requestBody = { model: config.model, messages: convertedMessages.filter(msg => msg.role !== 'system'), max_tokens: options.maxTokens || 4000, temperature: options.temperature, }; // Combine all system messages into a single system parameter const systemMessages = convertedMessages.filter(msg => msg.role === 'system'); if (systemMessages.length > 0) { requestBody.system = systemMessages.map(msg => msg.content).join('\n\n'); } if (tools && tools.length > 0) { const toolNames = tools.map(tool => tool.name).join(', '); requestBody.system = (requestBody.system || '') + `\n\nYou have access to the following tools: ${toolNames}. Use them when necessary.`; const convertedTools = tools.map(tool => (0, tools_1.convertToolSchema)(tool.getSchema())); requestBody.tools = convertedTools; } try { const response = await axios_1.default.post(url, requestBody, { headers: { 'Content-Type': 'application/json', 'x-api-key': config.apiKey, 'anthropic-version': '2023-06-01', }, }); return await createProviderResponse(response.data, tools || []); } catch (error) { if (axios_1.default.isAxiosError(error) && error.response) { throw new Error(`Anthropic API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`); } throw error; } } async function createProviderResponse(data, tools) { const response = { content: '', toolCalls: [], usage: { promptTokens: data.usage?.input_tokens || 0, completionTokens: data.usage?.output_tokens || 0, totalTokens: (data.usage?.input_tokens || 0) + (data.usage?.output_tokens || 0) }, }; for (const item of data.content) { if (item.type === 'text') { response.content += item.text; } else if (item.type === 'tool_use') { const toolUse = item; const toolCall = { name: toolUse.name, arguments: toolUse.input, }; response.toolCalls && response.toolCalls.push(toolCall); const tool = tools.find(t => t.name === toolUse.name); if (tool) { try { const result = await tool.execute(toolUse.input, {}); response.content += `\n\nTool ${toolUse.name} result: ${typeof result === 'string' ? result : JSON.stringify(result)}`; } catch (error) { response.content += `\n\nError executing tool ${toolUse.name}: ${error}`; } } else { response.content += `\n\nError: Tool not found: ${toolUse.name}`; } } } // Update usage tokens with the latest data from the response response.usage = { promptTokens: data.usage?.input_tokens || 0, completionTokens: data.usage?.output_tokens || 0, totalTokens: (data.usage?.input_tokens || 0) + (data.usage?.output_tokens || 0) }; return response; }