UNPKG

donobu

Version:

Create browser automations with an LLM agent and replay them as Playwright scripts.

230 lines 8.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VercelAiGptClient = void 0; const GptClient_1 = require("./GptClient"); const Logger_1 = require("../utils/Logger"); const GptModelNotFoundException_1 = require("../exceptions/GptModelNotFoundException"); const GptPlatformAuthenticationFailedException_1 = require("../exceptions/GptPlatformAuthenticationFailedException"); const GptPlatformInternalErrorException_1 = require("../exceptions/GptPlatformInternalErrorException"); const GptPlatformNotReachableException_1 = require("../exceptions/GptPlatformNotReachableException"); const ai_1 = require("ai"); /** * A GPT client implemented using the Vercel AI SDK. */ class VercelAiGptClient extends GptClient_1.GptClient { /** * Create a new instance. */ constructor(model) { super({ type: 'VERCEL_AI', provider: model.provider, modelName: model.modelId, }); this.model = model; } async ping() { try { await (0, ai_1.generateText)({ model: this.model, prompt: 'ping', temperature: 0, maxTokens: 1, }); } catch (error) { if (error instanceof Error && error.message.includes('not found')) { throw new GptModelNotFoundException_1.GptModelNotFoundException(this.config.type, this.model.modelId); } else { throw await this.mapErrorToDonobuException(error); } } } async getMessage(messages) { try { const coreMessages = this.convertToCoreMessages(messages); const result = await (0, ai_1.generateText)({ model: this.model, messages: coreMessages, temperature: 0, }); return { type: 'assistant', text: result.text, promptTokensUsed: result.usage.promptTokens, completionTokensUsed: result.usage.completionTokens, }; } catch (error) { throw await this.mapErrorToDonobuException(error); } } async getStructuredOutput(messages, jsonSchema) { try { const coreMessages = this.convertToCoreMessages(messages); const result = await (0, ai_1.generateObject)({ model: this.model, messages: coreMessages, schema: (0, ai_1.jsonSchema)(jsonSchema), temperature: 0, output: 'object', }); return { type: 'structured_output', output: result.object, promptTokensUsed: result.usage.promptTokens, completionTokensUsed: result.usage.completionTokens, }; } catch (error) { throw await this.mapErrorToDonobuException(error); } } async getToolCalls(messages, tools) { try { const coreMessages = this.convertToCoreMessages(messages); // Convert ToolOption to Vercel AI SDK Tool format const vercelTools = {}; for (const tool of tools) { vercelTools[tool.name] = { parameters: { _type: Object, parse: (value) => value, jsonSchema: () => tool.inputSchema, }, description: tool.description, }; } // Generate text with tool calls const result = await (0, ai_1.generateText)({ model: this.model, messages: coreMessages, tools: vercelTools, temperature: 0, toolChoice: 'required', // Force the model to use a tool }); // Map the tool calls to the expected format const proposedCalls = result.toolCalls.map((tc) => { return { name: tc.toolName, parameters: tc.args, toolCallId: tc.toolCallId, }; }); return { type: 'proposed_tool_calls', proposedToolCalls: proposedCalls, promptTokensUsed: result.usage.promptTokens, completionTokensUsed: result.usage.completionTokens, }; } catch (error) { throw await this.mapErrorToDonobuException(error); } } /** * Convert GptMessage array to CoreMessage array for Vercel AI SDK */ convertToCoreMessages(messages) { return messages.map((msg) => { const msgType = msg.type; if (msgType === 'system') { return { role: 'system', content: msg.text, }; } if (msgType === 'user') { // Convert user message items to content const content = msg.items.length === 1 && msg.items[0].type === 'text' ? msg.items[0].text // If it's just text, use string shorthand : msg.items.map((item) => { if (item.type === 'text') { return { type: 'text', text: item.text, }; } else if (item.type === 'png') { // Convert PNG to base64 for image parts return { type: 'image', image: item.bytes, mimeType: 'image/png', }; } throw new Error(`Unsupported user message item type: ${JSON.stringify(item)}`); }); return { role: 'user', content, }; } if (msgType === 'assistant') { return { role: 'assistant', content: msg.text, }; } if (msgType === 'tool_call_result') { return { role: 'tool', content: [ { type: 'tool-result', toolCallId: msg.toolCallId, toolName: msg.toolName, result: msg.data, }, ], }; } if (msgType === 'proposed_tool_calls') { // Convert proposed tool calls to assistant message with tool calls const content = msg.proposedToolCalls.map((tc) => ({ type: 'tool-call', toolCallId: tc.toolCallId || '', toolName: tc.name, args: tc.parameters, })); return { role: 'assistant', content, }; } if (msgType === 'structured_output') { // Convert structured output to text format return { role: 'assistant', content: JSON.stringify(msg.output, null, 2), }; } throw new Error(`Unsupported message type: ${msgType}`); }); } /** * Maps an error to a DonobuException */ async mapErrorToDonobuException(error) { Logger_1.appLogger.error(`Vercel AI SDK error: ${error}`); if (error instanceof Error) { // Check for authentication errors if (error.message.includes('authentication') || error.message.includes('unauthorized')) { return new GptPlatformAuthenticationFailedException_1.GptPlatformAuthenticationFailedException(this.config.type); } // Check for connectivity errors if (error.message.includes('network') || error.message.includes('connection')) { return new GptPlatformNotReachableException_1.GptPlatformNotReachableException(this.config.type); } } // Default to internal error return new GptPlatformInternalErrorException_1.GptPlatformInternalErrorException(error instanceof Error ? error.message : 'Unknown error with Vercel AI SDK'); } } exports.VercelAiGptClient = VercelAiGptClient; //# sourceMappingURL=VercelAiGptClient.js.map