UNPKG

adk-typescript

Version:

TypeScript port of Google's Agent Development Kit (ADK)

220 lines (219 loc) 8.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LlmRequest = void 0; /** * LLM request class that allows passing in tools, output schema and system * instructions to the model. */ class LlmRequest { /** * Creates a new LLM request. */ constructor() { /** * The model name. */ this.model = undefined; /** * The contents to send to the model. */ this.contents = []; /** * The tools dictionary. * Maps tool names to tool instances. * @private Not serialized when converting to JSON */ this.toolsDict = {}; this.config = { temperature: undefined, topP: undefined, topK: undefined, maxOutputTokens: undefined, candidateCount: undefined, stopSequences: undefined, systemInstruction: undefined, tools: [], responseSchema: undefined, responseMimeType: undefined, thinkingConfig: undefined }; this.liveConnectConfig = {}; } /** * Appends instructions to the system instruction. * @param instructions The instructions to append. */ appendInstructions(instructions) { if (!instructions || instructions.length === 0) { return; } if (this.config.systemInstruction) { this.config.systemInstruction += '\n\n' + instructions.join('\n\n'); } else { this.config.systemInstruction = instructions.join('\n\n'); } } /** * Appends tools to the request. * @param tools The tools to append. */ appendTools(tools) { if (!tools || tools.length === 0) { console.log('no tools to append'); return; } const declarations = []; for (const tool of tools) { let declaration = null; // Use the public getDeclaration method which internally calls _getDeclaration if (typeof tool.getDeclaration === 'function') { declaration = tool.getDeclaration(); } if (declaration) { // Store tool name to avoid duplicates this.toolsDict[tool.name] = tool; // Check if we already have this declaration to avoid duplicates const existingDeclaration = declarations.find(d => d.name === declaration?.name); if (!existingDeclaration) { declarations.push(declaration); } } } if (declarations.length > 0) { // Find an existing tool entry with functionDeclarations (camelCase format) let toolEntry = this.config.tools.find(t => Array.isArray(t.functionDeclarations)); // Also check for snake_case format for backward compatibility if (!toolEntry) { toolEntry = this.config.tools.find(t => Array.isArray(t.functionDeclarations)); // Convert to camelCase if found if (toolEntry && toolEntry.functionDeclarations) { toolEntry.functionDeclarations = toolEntry.functionDeclarations; // Use type assertion to avoid TypeScript error toolEntry.functionDeclarations = undefined; } } if (toolEntry) { // We need to use 'as any' since functionDeclarations isn't in the type const existingDeclarations = toolEntry.functionDeclarations || []; // Add new declarations, avoiding duplicates for (const declaration of declarations) { // Check if a declaration with the same name already exists const existingIndex = existingDeclarations.findIndex((existing) => existing.name === declaration.name); if (existingIndex === -1) { // Only add if it doesn't exist already existingDeclarations.push(declaration); } } // Update the declarations toolEntry.functionDeclarations = existingDeclarations; } else { // Create a new tool entry with camelCase format this.config.tools.push({ functionDeclarations: declarations }); } } } /** * Sets the output schema for the request. * @param baseModel The schema class to set the output schema to. */ setOutputSchema(baseModel) { this.config.responseSchema = baseModel; this.config.responseMimeType = 'application/json'; } /** * Get the tools dictionary for this request. * @returns The tools dictionary */ getToolsDict() { return { ...this.toolsDict }; } /** * Adds a function declaration to the tools. * @param functionDef The function definition to add */ addFunction(functionDef) { if (!functionDef) { return; } // Find an existing tool entry with functionDeclarations (camelCase format) const toolEntry = this.config.tools.find(t => Array.isArray(t.functionDeclarations)); if (toolEntry) { // We need to use 'as any' since functionDeclarations isn't in the type const existingDeclarations = toolEntry.functionDeclarations || []; // Check if a declaration with the same name already exists const existingIndex = existingDeclarations.findIndex((existing) => existing.name === functionDef.name); if (existingIndex === -1) { // Only add if it doesn't exist already existingDeclarations.push(functionDef); } // Update the declarations toolEntry.functionDeclarations = existingDeclarations; } else { // Create a new tool entry with camelCase format this.config.tools.push({ functionDeclarations: [functionDef] }); } } /** * Converts this LlmRequest to a plain object for API requests. * @returns A plain object representation of this request */ toRequestObject() { const result = { contents: this.contents, model: this.model }; // Add configuration if it exists if (this.config && Object.keys(this.config).length > 0) { result.generationConfig = {}; // Copy over generation config properties if (this.config.temperature !== undefined) { result.generationConfig.temperature = this.config.temperature; } if (this.config.topP !== undefined) { result.generationConfig.topP = this.config.topP; } if (this.config.topK !== undefined) { result.generationConfig.topK = this.config.topK; } if (this.config.maxOutputTokens !== undefined) { result.generationConfig.maxOutputTokens = this.config.maxOutputTokens; } if (this.config.candidateCount !== undefined) { result.generationConfig.candidateCount = this.config.candidateCount; } if (this.config.stopSequences !== undefined) { result.generationConfig.stopSequences = this.config.stopSequences; } // Add system instructions if present if (this.config.systemInstruction) { result.systemInstruction = this.config.systemInstruction; } // Add tools if present if (this.config.tools && this.config.tools.length > 0) { result.tools = this.config.tools; } // Add response schema if present if (this.config.responseSchema) { result.generationConfig.responseSchema = this.config.responseSchema; result.generationConfig.responseMimeType = this.config.responseMimeType || 'application/json'; } // Add thinking config if present if (this.config.thinkingConfig) { result.thinkingConfig = this.config.thinkingConfig; } } // Add live connect config if present if (this.liveConnectConfig && Object.keys(this.liveConnectConfig).length > 0) { result.liveConnectConfig = this.liveConnectConfig; } return result; } } exports.LlmRequest = LlmRequest;