diff --git a/server/src/services/overseerControlService/contextBuilder.js b/server/src/services/overseerControlService/contextBuilder.js index dec83a03..e09f6e22 100644 --- a/server/src/services/overseerControlService/contextBuilder.js +++ b/server/src/services/overseerControlService/contextBuilder.js @@ -26,21 +26,29 @@ function buildToolState({ mode, homeAssistantState, neatoState, liftState }) { } function buildConversation({ recentMessages, name }) { - const rows = []; + const messages = []; (recentMessages || []).forEach((entry) => { const text = String(entry?.text || '').trim(); if (!text) return; - const who = entry?.system ? (entry?.nickname || name || 'Overseer') : (entry?.nickname || 'user'); - rows.push(`${who}: ${text}`); + const isAssistant = Boolean(entry?.bot || entry?.system); + const nickname = String(entry?.nickname || (isAssistant ? name || 'Overseer' : 'user')).trim(); + if (isAssistant) { + messages.push({ role: 'assistant', content: text }); + return; + } + messages.push({ role: 'user', content: `${nickname}: ${text}` }); }); - return rows; + return messages; } -function buildModelMessages({ systemPrompt, stateUpdate, transcriptRows, availableTools, blockedTools }) { +function buildModelMessages({ systemPrompt, stateUpdate, conversationMessages, availableTools, blockedTools }) { const messages = []; messages.push({ role: 'system', content: systemPrompt }); messages.push({ role: 'user', content: `STATE_UPDATE\n${stateUpdate}` }); - transcriptRows.forEach((row) => messages.push({ role: 'user', content: row })); + (conversationMessages || []).forEach((message) => { + if (!message || !message.role || !message.content) return; + messages.push(message); + }); messages.push({ role: 'user', content: `available_tools:\n${availableTools.map((tool) => `- ${tool}`).join('\n') || '- none'}`, diff --git a/server/src/services/overseerControlService/index.js b/server/src/services/overseerControlService/index.js index 1b9470d5..68d4830b 100644 --- a/server/src/services/overseerControlService/index.js +++ b/server/src/services/overseerControlService/index.js @@ -144,18 +144,23 @@ async function runDecision(triggerReason) { const stateUpdate = toStateUpdate({ mode, homeAssistantState, neatoState, liftState, roster, triggerReason }); const toolState = buildToolState({ mode, homeAssistantState, neatoState, liftState }); - const human = getRecentMessages(MAX_CHAT_CONTEXT, { includeSystem: false }); - const bots = getRecentMessages(100, { includeSystem: true }).filter((entry) => entry?.system).slice(-MAX_BOT_CONTEXT); - const transcriptRows = buildConversation({ recentMessages: [...human, ...bots].slice(-(MAX_CHAT_CONTEXT + MAX_BOT_CONTEXT)), name }); + const recentConversation = getRecentMessages(MAX_CHAT_CONTEXT + MAX_BOT_CONTEXT, { includeSystem: true }); + const conversationMessages = buildConversation({ recentMessages: recentConversation, name }); const systemPrompt = await readPrompt(); - const modelMessages = buildModelMessages({ systemPrompt, stateUpdate, transcriptRows, availableTools: toolState.available, blockedTools: toolState.blocked }); + const modelMessages = buildModelMessages({ + systemPrompt, + stateUpdate, + conversationMessages, + availableTools: toolState.available, + blockedTools: toolState.blocked, + }); updateStatus({ phase: 'awaiting_model', lastSystemPrompt: systemPrompt, lastStateUpdate: stateUpdate, - lastTranscript: transcriptRows, + lastTranscript: conversationMessages, lastAvailableTools: toolState.available, lastBlockedTools: toolState.blocked, lastModelMessages: modelMessages,