overseer v2 6 (tool actions, text chat)

This commit is contained in:
legop3
2026-05-04 00:14:32 -04:00
parent 5e2c836cf2
commit 15fedc7c77
7 changed files with 16 additions and 6 deletions
+1
View File
@@ -16,6 +16,7 @@ llmCommentary:
overseerControl: overseerControl:
enabled: false enabled: false
observeOnly: true observeOnly: true
alwaysRunModel: false
name: "The Overseer" name: "The Overseer"
model: "qwen2.5:7b-instruct" model: "qwen2.5:7b-instruct"
ollamaServer: "http://127.0.0.1:11434" ollamaServer: "http://127.0.0.1:11434"
+1 -1
View File
@@ -12,7 +12,7 @@ function sendSystemMessage(text, options = {}) {
const normalized = normalizeUserText(text); const normalized = normalizeUserText(text);
const clean = normalized.trim(); const clean = normalized.trim();
if (!clean) return null; if (!clean) return null;
const safe = clean.length > 256 ? `${clean.slice(0, 253)}...` : clean; const safe = clean;
const message = buildMessage(null, safe, { const message = buildMessage(null, safe, {
nickname: String(options.nickname || 'The Overseer'), nickname: String(options.nickname || 'The Overseer'),
role: 'user', role: 'user',
@@ -67,7 +67,7 @@ function buildModelMessages({ systemPrompt, stateUpdate, conversationMessages, a
messages.push({ messages.push({
role: 'user', role: 'user',
content: content:
'Use tool calls when needed. If no tool is needed, either respond with one short chat line or SKIP.', 'Use tool calls when needed. If no tool is needed, respond with one short in-character chat line.',
}); });
return messages; return messages;
} }
@@ -38,6 +38,7 @@ const model = String(overseerConfig.model || '').trim();
const ollamaUrl = String(overseerConfig.ollamaUrl || overseerConfig.ollamaServer || '').trim(); const ollamaUrl = String(overseerConfig.ollamaUrl || overseerConfig.ollamaServer || '').trim();
const gateIntervalMs = normalizeMs(Number(overseerConfig.gateIntervalMs), DEFAULT_GATE_INTERVAL_MS); const gateIntervalMs = normalizeMs(Number(overseerConfig.gateIntervalMs), DEFAULT_GATE_INTERVAL_MS);
const heartbeatMs = normalizeMs(Number(overseerConfig.heartbeatMs), DEFAULT_HEARTBEAT_MS); const heartbeatMs = normalizeMs(Number(overseerConfig.heartbeatMs), DEFAULT_HEARTBEAT_MS);
const alwaysRunModel = Boolean(overseerConfig.alwaysRunModel);
const ollamaClient = ollamaUrl ? new Ollama({ host: ollamaUrl }) : null; const ollamaClient = ollamaUrl ? new Ollama({ host: ollamaUrl }) : null;
const runtime = { const runtime = {
@@ -60,6 +61,7 @@ let status = {
promptPath: PROMPT_PATH, promptPath: PROMPT_PATH,
gateIntervalMs, gateIntervalMs,
heartbeatMs, heartbeatMs,
alwaysRunModel,
running: false, running: false,
inFlight: false, inFlight: false,
phase: 'idle', phase: 'idle',
@@ -125,6 +127,7 @@ function buildRosterSummary() {
} }
function computeTriggerReason() { function computeTriggerReason() {
if (alwaysRunModel) return 'loop_tick';
const recent = getRecentMessages(1, { includeSystem: false }); const recent = getRecentMessages(1, { includeSystem: false });
const last = recent[recent.length - 1]; const last = recent[recent.length - 1];
if (last && Date.now() - Number(last.ts || 0) < 5000) { if (last && Date.now() - Number(last.ts || 0) < 5000) {
@@ -166,6 +169,13 @@ function inferDecision({ toolCalls, chatText }) {
return 'SKIP'; return 'SKIP';
} }
function normalizeChatDraft(text) {
const next = String(text || '').trim();
if (!next) return null;
if (next.toUpperCase() === 'SKIP') return null;
return next;
}
async function runDecision(triggerReason) { async function runDecision(triggerReason) {
const runId = runtime.tickCount; const runId = runtime.tickCount;
updateStatus({ phase: 'context_build', currentRunId: runId, lastTriggerReason: triggerReason, lastError: null, lastErrorDetails: null }); updateStatus({ phase: 'context_build', currentRunId: runId, lastTriggerReason: triggerReason, lastError: null, lastErrorDetails: null });
@@ -223,7 +233,7 @@ async function runDecision(triggerReason) {
const rawOutput = String(payload?.message?.content || ''); const rawOutput = String(payload?.message?.content || '');
const toolCalls = normalizeToolCalls(payload); const toolCalls = normalizeToolCalls(payload);
const chatDraft = rawOutput.trim() || null; const chatDraft = normalizeChatDraft(rawOutput);
const decision = inferDecision({ toolCalls, chatText: chatDraft }); const decision = inferDecision({ toolCalls, chatText: chatDraft });
const generationMs = Math.max(0, Date.now() - generationStart); const generationMs = Math.max(0, Date.now() - generationStart);
@@ -22,6 +22,7 @@ function buildAdminState(status, runHistory) {
ollamaUrl: status.ollamaUrl, ollamaUrl: status.ollamaUrl,
gateIntervalMs: status.gateIntervalMs, gateIntervalMs: status.gateIntervalMs,
heartbeatMs: status.heartbeatMs, heartbeatMs: status.heartbeatMs,
alwaysRunModel: status.alwaysRunModel,
observeOnly: status.observeOnly, observeOnly: status.observeOnly,
promptPath: status.promptPath, promptPath: status.promptPath,
}, },
@@ -5,7 +5,7 @@ module.exports = {
parameters: { parameters: {
type: 'object', type: 'object',
properties: { properties: {
text: { type: 'string', minLength: 1, maxLength: 220 }, text: { type: 'string', minLength: 1 },
}, },
required: ['text'], required: ['text'],
additionalProperties: false, additionalProperties: false,
@@ -1,4 +1,3 @@
const chatSay = require('./chatSay');
const memoryRead = require('./memoryRead'); const memoryRead = require('./memoryRead');
const memoryWrite = require('./memoryWrite'); const memoryWrite = require('./memoryWrite');
const liftUp = require('./liftUp'); const liftUp = require('./liftUp');
@@ -11,7 +10,6 @@ const haSetEntity = require('./haSetEntity');
const buttonBoxAddCount = require('./buttonBoxAddCount'); const buttonBoxAddCount = require('./buttonBoxAddCount');
const TOOL_DEFINITIONS = [ const TOOL_DEFINITIONS = [
chatSay,
memoryRead, memoryRead,
memoryWrite, memoryWrite,
liftUp, liftUp,