mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
86 lines
3.5 KiB
JavaScript
86 lines
3.5 KiB
JavaScript
const { evaluateTools } = require('./tools');
|
|
|
|
function normalizeNeatoIssue(value) {
|
|
const raw = String(value || '').trim();
|
|
if (!raw) return 'none';
|
|
if (raw.includes('200')) return 'none';
|
|
return raw;
|
|
}
|
|
|
|
function toStateUpdate({ mode, homeAssistantState, neatoState, liftState, roster, triggerReason }) {
|
|
const lines = [];
|
|
lines.push(`trigger: ${triggerReason || 'heartbeat'}`);
|
|
lines.push(`mode: ${mode || 'unknown'}`);
|
|
lines.push(`home_assistant_connected: ${homeAssistantState?.connected ? 'yes' : 'no'}`);
|
|
lines.push(`lights_locked_on: ${homeAssistantState?.lightPolicy?.lockedOn ? 'yes' : 'no'}`);
|
|
lines.push(`lift: ${liftState?.connected ? 'connected' : 'offline'} busy=${liftState?.busy ? 'yes' : 'no'}`);
|
|
const neatoError = normalizeNeatoIssue(neatoState?.telemetry?.robotError);
|
|
const neatoAlert = normalizeNeatoIssue(neatoState?.telemetry?.robotAlert);
|
|
lines.push(
|
|
`neato: ${neatoState?.connected ? 'connected' : 'offline'} state=${neatoState?.telemetry?.robotState || 'unknown'} error=${neatoError} alert=${neatoAlert}`,
|
|
);
|
|
const entities = Array.isArray(homeAssistantState?.entities) ? homeAssistantState.entities : [];
|
|
if (entities.length) {
|
|
lines.push('home_assistant_entities:');
|
|
entities.slice(0, 24).forEach((entity) => {
|
|
lines.push(`- ${entity.id} (${entity.type || 'entity'}) state=${entity.state || 'unknown'} available=${entity.available ? 'yes' : 'no'}`);
|
|
});
|
|
}
|
|
const roverLines = (Array.isArray(roster) ? roster : []).slice(0, 6).map((rover) => {
|
|
const roverId = rover?.id || 'unknown';
|
|
const drivers = Array.isArray(rover?.drivers) ? rover.drivers.filter(Boolean) : [];
|
|
const driver = drivers.length ? drivers.join(',') : 'none';
|
|
const status = rover?.statusTag || 'unknown';
|
|
return `- ${roverId} status=${status} drivers=${driver}`;
|
|
});
|
|
if (roverLines.length) {
|
|
lines.push('rovers:');
|
|
lines.push(...roverLines);
|
|
}
|
|
return lines.join('\n');
|
|
}
|
|
|
|
function buildToolState({ mode, homeAssistantState, neatoState, liftState }) {
|
|
return evaluateTools({ mode, homeAssistantState, neatoState, liftState });
|
|
}
|
|
|
|
function buildConversation({ recentMessages, name }) {
|
|
const messages = [];
|
|
(recentMessages || []).forEach((entry) => {
|
|
const text = String(entry?.text || '').trim();
|
|
if (!text) return;
|
|
const isAssistant = Boolean(entry?.bot);
|
|
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 messages;
|
|
}
|
|
|
|
function buildModelMessages({ systemPrompt, stateUpdate, memorySummary, conversationMessages, availableTools, blockedTools }) {
|
|
const messages = [];
|
|
messages.push({ role: 'system', content: systemPrompt });
|
|
const metadataSections = [];
|
|
metadataSections.push(`STATE_UPDATE\n${stateUpdate}`);
|
|
if (memorySummary) metadataSections.push(`MEMORY_UPDATE\n${memorySummary}`);
|
|
metadataSections.push(
|
|
`tool_constraints:\n${blockedTools.map((entry) => `- blocked: ${entry.tool} reason=${entry.reason}`).join('\n') || '- none'}`,
|
|
);
|
|
messages.push({ role: 'user', content: metadataSections.join('\n\n') });
|
|
(conversationMessages || []).forEach((message) => {
|
|
if (!message || !message.role || !message.content) return;
|
|
messages.push(message);
|
|
});
|
|
return messages;
|
|
}
|
|
|
|
module.exports = {
|
|
toStateUpdate,
|
|
buildToolState,
|
|
buildConversation,
|
|
buildModelMessages,
|
|
};
|