'use strict'; const axios = require('axios'); class OllamaProvider { constructor(config) { this.config = config; this.baseUrl = config.baseUrl || 'http://localhost:11434'; this.model = config.model || 'llama3.2'; this.messages = []; } async start(history) { // Convert Gemini-style history to Ollama format if needed this.messages = history || []; if (this.config.prompt) { console.log('Ollama provider initialized with model:', this.model); } } __settings() { return { temperature: this.config.temperature || 1, top_p: this.config.topP || 0.95, top_k: this.config.topK || 64, num_predict: this.config.maxOutputTokens || 2048, }; } __jsonFormat() { return { type: 'array', items: { type: 'object', properties: { text: { type: 'string' }, delay: { type: 'number' } }, required: ['text', 'delay'] } }; } async chat(message, retryCount = 0) { try { // Build conversation from prompt + history const messages = [ { role: 'system', content: this.config.prompt || 'You are a helpful assistant.' }, ...this.messages.map(msg => ({ role: msg.role === 'model' ? 'assistant' : 'user', content: msg.parts ? msg.parts.map(p => p.text).join('') : (msg.content || '') })), { role: 'user', content: message } ]; // console.log('Ollama messages', messages) const requestBody = { model: this.model, messages: messages, stream: false, format: this.__jsonFormat(), options: this.__settings() }; // console.log('Ollama request:', JSON.stringify(requestBody, null, 2)); const response = await axios.post( `${this.baseUrl}/api/chat`, requestBody, { timeout: this.config.timeout || 30000, headers: { 'Content-Type': 'application/json' } } ); // Log raw response for debugging const rawContent = response.data.message.content; // console.log('Ollama raw response:', JSON.stringify(rawContent)); // console.log('Ollama raw response length:', rawContent?.length); // Update history this.messages.push({ role: 'user', parts: [{ text: message }], content: message }); this.messages.push({ role: 'model', parts: [{ text: rawContent }], content: rawContent }); // Return in a format compatible with the Ai class return { response: { text: () => response.data.message.content } }; } catch (error) { // Log detailed error information const errorDetails = { message: error.message, status: error.response?.status, data: error.response?.data, url: error.config?.url, retryCount: retryCount }; console.log('Ollama API error details:', errorDetails); if (retryCount > 3) { throw new Error(`Ollama API error after ${retryCount} retries: ${error.message}`); } // Retry after delay await new Promise(resolve => setTimeout(resolve, 500 * (retryCount + 1))); return await this.chat(message, retryCount + 1); } } setPrompt(prompt) { this.config.prompt = prompt; } getResponse(result) { return result.response.text(); } async close() { this.messages = []; } } module.exports = OllamaProvider;