contextual-agent-sdk
Version:
SDK for building AI agents with seamless voice-text context switching
150 lines • 5.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseLLMProvider = void 0;
const ConversationManager_1 = require("../conversation/ConversationManager");
const ToolConverter_1 = require("../tools/ToolConverter");
class BaseLLMProvider {
conversationManager;
constructor() {
this.conversationManager = new ConversationManager_1.ConversationManager();
}
supportsTools() {
return false;
}
supportsStreaming() {
return false;
}
createConversation(systemPrompt) {
return this.conversationManager.createConversation(systemPrompt);
}
async generateWithTools(options) {
if (!this.supportsTools()) {
throw new Error(`${this.type} provider does not support tool calling`);
}
let messages = options.messages;
if (options.conversation) {
messages = this.conversationManager.getConversationHistory(options.conversation.id);
}
const toolDescriptions = options.tools?.map(tool => `Tool: ${tool.function.name} - ${tool.function.description}`).join('\n') || '';
const enhancedMessages = [...messages];
if (toolDescriptions) {
const systemMessage = enhancedMessages.find(m => m.role === 'system');
if (systemMessage) {
systemMessage.content += `\n\nAvailable tools:\n${toolDescriptions}`;
}
else {
enhancedMessages.unshift({
role: 'system',
content: `Available tools:\n${toolDescriptions}`
});
}
}
const response = await this.generateResponse({
...options,
messages: enhancedMessages
});
return {
...response,
toolCalls: [],
stopReason: 'stop',
conversation: options.conversation
};
}
async *streamResponse(options) {
if (!this.supportsStreaming()) {
throw new Error(`${this.type} provider does not support streaming`);
}
const response = await this.generateResponse(options);
yield {
type: 'content',
content: response.content
};
yield {
type: 'done',
done: true
};
}
async *streamWithTools(options) {
if (!this.supportsStreaming() || !this.supportsTools()) {
throw new Error(`${this.type} provider does not support streaming with tools`);
}
const response = await this.generateWithTools(options);
if (response.toolCalls && response.toolCalls.length > 0) {
for (const toolCall of response.toolCalls) {
yield {
type: 'tool_call',
toolCall
};
}
}
if (response.content) {
yield {
type: 'content',
content: response.content
};
}
yield {
type: 'done',
done: true
};
}
async handleToolLoop(conversation, tools) {
if (!this.supportsTools()) {
throw new Error(`${this.type} provider does not support tool calling`);
}
const maxIterations = 10;
let iteration = 0;
while (iteration < maxIterations) {
iteration++;
const response = await this.generateWithTools({
conversation,
tools: ToolConverter_1.ToolConverter.toOpenAIFunctions(tools),
messages: this.conversationManager.getConversationHistory(conversation.id)
});
if (!response.toolCalls || response.toolCalls.length === 0) {
return response;
}
const toolResults = await ToolConverter_1.ToolConverter.executeToolCalls(response.toolCalls, tools, ToolConverter_1.ToolConverter.createToolContext(conversation.metadata?.agentId || 'unknown', conversation.id, conversation.metadata?.userId));
this.conversationManager.addToolCalls(conversation.id, response.toolCalls);
this.conversationManager.addToolResults(conversation.id, response.toolCalls.map((call, index) => ({
callId: call.id,
result: toolResults[index]
})));
const criticalFailure = toolResults.find(result => !result.success && result.metadata?.critical);
if (criticalFailure) {
return {
...response,
content: `Tool execution failed: ${criticalFailure.error}`,
stopReason: 'stop'
};
}
}
throw new Error(`Tool execution loop exceeded maximum iterations (${maxIterations})`);
}
formatMessagesForProvider(messages) {
return messages.map(msg => ({
role: msg.role,
content: msg.content
}));
}
extractToolCallsFromResponse(response) {
return [];
}
async isAvailable() {
try {
await this.test?.();
return true;
}
catch {
return false;
}
}
async test() {
await this.generateResponse({
messages: [{ role: 'user', content: 'Test' }],
maxTokens: 10
});
}
}
exports.BaseLLMProvider = BaseLLMProvider;
//# sourceMappingURL=BaseLLMProvider.js.map