here
This commit is contained in:
@@ -24,7 +24,21 @@ class OllamaProvider {
|
||||
temperature: this.config.temperature || 1,
|
||||
top_p: this.config.topP || 0.95,
|
||||
top_k: this.config.topK || 64,
|
||||
num_predict: this.config.maxOutputTokens || 8192,
|
||||
num_predict: this.config.maxOutputTokens || 2048,
|
||||
};
|
||||
}
|
||||
|
||||
__jsonFormat() {
|
||||
return {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
text: { type: 'string' },
|
||||
delay: { type: 'number' }
|
||||
},
|
||||
required: ['text', 'delay']
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,15 +60,19 @@ class OllamaProvider {
|
||||
}
|
||||
];
|
||||
|
||||
// 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`,
|
||||
{
|
||||
model: this.model,
|
||||
messages: messages,
|
||||
stream: false,
|
||||
format: 'json', // Request JSON response
|
||||
options: this.__settings()
|
||||
},
|
||||
requestBody,
|
||||
{
|
||||
timeout: this.config.timeout || 30000,
|
||||
headers: {
|
||||
@@ -63,6 +81,11 @@ class OllamaProvider {
|
||||
}
|
||||
);
|
||||
|
||||
// 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',
|
||||
@@ -72,8 +95,8 @@ class OllamaProvider {
|
||||
|
||||
this.messages.push({
|
||||
role: 'model',
|
||||
parts: [{ text: response.data.message.content }],
|
||||
content: response.data.message.content
|
||||
parts: [{ text: rawContent }],
|
||||
content: rawContent
|
||||
});
|
||||
|
||||
// Return in a format compatible with the Ai class
|
||||
@@ -83,6 +106,16 @@ class OllamaProvider {
|
||||
}
|
||||
};
|
||||
} 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}`);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const { CJbot } = require('../../model/minecraft');
|
||||
|
||||
function createRouter() {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/api/ai/status', (req, res) => {
|
||||
try {
|
||||
const result = {};
|
||||
for (const [name, bot] of Object.entries(CJbot.bots)) {
|
||||
const ai = bot.plunginsLoaded['Ai'];
|
||||
if (!ai) continue;
|
||||
const config = ai.__getConfig();
|
||||
result[name] = {
|
||||
connected: bot.isReady,
|
||||
provider: config.provider || 'unknown',
|
||||
model: config.model || 'unknown',
|
||||
interval: ai.intervalLength,
|
||||
promptName: ai.promptName || 'unknown',
|
||||
active: !!ai.intervalStop,
|
||||
};
|
||||
}
|
||||
res.json({ bots: result });
|
||||
} catch (error) {
|
||||
console.error('API Error /api/ai/status:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
const webUI = {
|
||||
tabId: 'ai',
|
||||
tabLabel: 'AI',
|
||||
tabOrder: 30,
|
||||
html: `
|
||||
<div id="aiArea">
|
||||
<div style="padding:20px;color:#6b7280;text-align:center">Loading AI status...</div>
|
||||
</div>
|
||||
`,
|
||||
css: `
|
||||
.ai-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:16px}
|
||||
.ai-card{background:#111827;border:1px solid #374151;border-radius:8px;padding:16px;transition:border-color .2s}
|
||||
.ai-card:hover{border-color:#a78bfa}
|
||||
.ai-card h3{font-size:1em;color:#a78bfa;margin-bottom:12px;display:flex;align-items:center;gap:8px}
|
||||
.ai-info{font-size:.85em;color:#9ca3af;margin:4px 0}
|
||||
.ai-info .ai-label{color:#6b7280;display:inline-block;min-width:80px}
|
||||
.ai-info .ai-value{color:#e5e7eb}
|
||||
.ai-status-badge{padding:2px 8px;border-radius:10px;font-size:.75em;font-weight:600}
|
||||
.ai-status-badge.active{background:#059669;color:#fff}
|
||||
.ai-status-badge.inactive{background:#6b7280;color:#fff}
|
||||
.ai-empty{padding:40px 20px;color:#6b7280;text-align:center;font-size:.9em}
|
||||
`,
|
||||
onTabActive: 'onAiTabActive',
|
||||
js: `
|
||||
let aiInterval=null;
|
||||
|
||||
function onAiTabActive() {
|
||||
loadAiStatus();
|
||||
if (!aiInterval) aiInterval = setInterval(() => { if (currentTab === 'ai') loadAiStatus(); }, 10000);
|
||||
}
|
||||
|
||||
async function loadAiStatus() {
|
||||
try {
|
||||
const r = await fetch('/api/ai/status');
|
||||
if (!r.ok) { document.getElementById('aiArea').innerHTML='<div class="ai-empty">Failed to load AI status</div>'; return; }
|
||||
const d = await r.json();
|
||||
renderAiStatus(d.bots || {});
|
||||
} catch(e) {
|
||||
document.getElementById('aiArea').innerHTML='<div class="ai-empty">Failed to load AI status</div>';
|
||||
}
|
||||
}
|
||||
|
||||
function renderAiStatus(bots) {
|
||||
const area = document.getElementById('aiArea');
|
||||
const names = Object.keys(bots);
|
||||
if (names.length === 0) {
|
||||
area.innerHTML='<div class="ai-empty">No bots with AI loaded</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
area.innerHTML = '<div class="ai-grid">' + names.map(name => {
|
||||
const ai = bots[name];
|
||||
const badge = ai.active
|
||||
? '<span class="ai-status-badge active">Active</span>'
|
||||
: '<span class="ai-status-badge inactive">Inactive</span>';
|
||||
|
||||
return '<div class="ai-card">' +
|
||||
'<h3><span class="bot-status ' + (ai.connected ? 'online' : 'offline') + '"></span> ' + escHtml(name) + ' ' + badge + '</h3>' +
|
||||
'<div class="ai-info"><span class="ai-label">Provider:</span> <span class="ai-value">' + escHtml(ai.provider) + '</span></div>' +
|
||||
'<div class="ai-info"><span class="ai-label">Model:</span> <span class="ai-value">' + escHtml(ai.model) + '</span></div>' +
|
||||
'<div class="ai-info"><span class="ai-label">Interval:</span> <span class="ai-value">' + ai.interval + 's</span></div>' +
|
||||
'<div class="ai-info"><span class="ai-label">Prompt:</span> <span class="ai-value">' + escHtml(ai.promptName) + '</span></div>' +
|
||||
'</div>';
|
||||
}).join('') + '</div>';
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
module.exports = { createRouter, webUI };
|
||||
Reference in New Issue
Block a user