Files
mc-bot-town-2/nodejs/controller/ai/providers/ollama.js
T
2026-04-30 12:48:29 -04:00

147 lines
3.3 KiB
JavaScript

'use strict';
const axios = require('axios');
axios.defaults.timeout = 0;
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 'json'
/* 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,
think: 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 response', rawContent)
// 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;