This commit is contained in:
legop3
2026-02-25 13:33:03 -05:00
parent 20e89839fe
commit 30671332af
2 changed files with 81 additions and 31 deletions
+4 -4
View File
@@ -7,10 +7,10 @@ Output contract:
Conversation format you will receive: Conversation format you will receive:
- System message (this prompt). - System message (this prompt).
- User run_meta message. - User RUN META message (plain text bullets).
- Ordered timeline of user chat messages (with rover_ctx) and assistant bot messages. - Ordered timeline of user CHAT messages and assistant bot messages.
- Optional user snapshot message(s) inserted in the timeline. - Optional user SNAPSHOT message(s) inserted in the timeline.
- Final user snapshot_final message with full current rover state. - Final user SNAPSHOT FINAL message with full current rover state.
Decision policy: Decision policy:
- SKIP is the default. - SKIP is the default.
+77 -27
View File
@@ -15,14 +15,14 @@ const DEFAULT_FREQUENCY_MS = 0;
const MIN_FREQUENCY_MS = 0; const MIN_FREQUENCY_MS = 0;
const JITTER_MS = 0; const JITTER_MS = 0;
const MAX_ROVERS = 6; const MAX_ROVERS = 6;
const MAX_CHAT_MESSAGES = 6; const MAX_CHAT_MESSAGES = 4;
const MAX_BOT_MESSAGES = 1; const MAX_BOT_MESSAGES = 1;
const MAX_OUTPUT_CHARS = 140; const MAX_OUTPUT_CHARS = 140;
const SKIP_TOKEN = 'SKIP'; const SKIP_TOKEN = 'SKIP';
const ACTIVITY_WINDOW_MS = 30000; const ACTIVITY_WINDOW_MS = 30000;
const ACTIVITY_BUCKET_MS = 1000; const ACTIVITY_BUCKET_MS = 1000;
const SELF_TALK_WINDOW_MS = 30 * 60 * 1000; const SELF_TALK_WINDOW_MS = 30 * 60 * 1000;
const MAX_CONTEXT_EVENTS = 100; const MAX_CONTEXT_EVENTS = 10;
const NO_ACTIVE_DRIVER_DELAY_MS = 5000; const NO_ACTIVE_DRIVER_DELAY_MS = 5000;
const NO_ACTIVE_DRIVER_LOG_COOLDOWN_MS = 30000; const NO_ACTIVE_DRIVER_LOG_COOLDOWN_MS = 30000;
@@ -383,6 +383,13 @@ function buildSnapshot() {
}); });
} }
const currentSnapshot = {
rovers,
};
if (!hasRecentChat) {
currentSnapshot.chat_recent = chatRecent;
}
return { return {
run_meta: { run_meta: {
version: 'commentary_v2', version: 'commentary_v2',
@@ -392,10 +399,7 @@ function buildSnapshot() {
driving_rovers: driverEntries.map(([roverId]) => String(roverId)), driving_rovers: driverEntries.map(([roverId]) => String(roverId)),
}, },
event_stream: eventStream, event_stream: eventStream,
current_snapshot: { current_snapshot: currentSnapshot,
rovers,
chat_recent: chatRecent,
},
}; };
} }
@@ -427,6 +431,68 @@ function parseModelOutput(rawContent) {
}; };
} }
function formatRunMetaMessage(runMeta = {}) {
const focus = runMeta?.last_message_focus || null;
const focusText = focus
? `topic=${focus.topic || 'none'} rover=${focus.rover_id || 'none'}`
: 'none';
const drivingRovers = Array.isArray(runMeta?.driving_rovers) && runMeta.driving_rovers.length
? runMeta.driving_rovers.join(', ')
: 'none';
return [
'RUN META',
`- active drivers: ${Number(runMeta?.active_driver_count) || 0}`,
`- driving rovers: ${drivingRovers}`,
`- bot posts last 30m: ${Number(runMeta?.self_talk_recent_30m) || 0}`,
`- last bot focus: ${focusText}`,
].join('\n');
}
function formatRoverCtx(ctx) {
if (!ctx || typeof ctx !== 'object') return 'none';
const activity = ctx.activity_30s || {};
return `status=${ctx.status_tag || 'unknown'} battery_low=${Boolean(ctx.battery_low)} wheels_off_ground=${Boolean(ctx.wheels_off_ground)} docked=${Boolean(ctx.docked)} charging=${Boolean(ctx.charging)} move30=${Number(activity.distance_m) || 0}m turn30=${Number(activity.turn_deg) || 0}deg bumps30=${Number(activity.bumps) || 0}`;
}
function formatChatEventMessage(event) {
return [
'CHAT',
`nick: ${event.nickname || 'unknown'}`,
`text: ${event.text || ''}`,
`rover: ${event.rover_id || 'none'}`,
`rover_now: ${formatRoverCtx(event.rover_ctx)}`,
].join('\n');
}
function formatRoverSnapshotLine(rover = {}) {
const activity = rover.activity_30s || {};
return `${rover.id || 'unknown'}: driver=${rover.driver_nickname || 'none'} status=${rover.status_tag || 'unknown'} battery_low=${Boolean(rover.battery_low)} wheels_off_ground=${Boolean(rover.wheels_off_ground)} docked=${Boolean(rover.docked)} charging=${Boolean(rover.charging)} move30=${Number(activity.distance_m) || 0}m turn30=${Number(activity.turn_deg) || 0}deg bumps30=${Number(activity.bumps) || 0}`;
}
function formatSnapshotMessage(event) {
const rovers = Array.isArray(event?.rovers) ? event.rovers : [];
const lines = ['SNAPSHOT', `reason: ${event?.reason || 'none'}`];
rovers.forEach((rover) => {
lines.push(formatRoverSnapshotLine(rover));
});
return lines.join('\n');
}
function formatSnapshotFinalMessage(currentSnapshot = {}) {
const rovers = Array.isArray(currentSnapshot?.rovers) ? currentSnapshot.rovers : [];
const lines = ['SNAPSHOT FINAL'];
rovers.forEach((rover) => {
lines.push(formatRoverSnapshotLine(rover));
});
if (Array.isArray(currentSnapshot?.chat_recent) && currentSnapshot.chat_recent.length) {
lines.push('chat_recent:');
currentSnapshot.chat_recent.forEach((entry) => {
lines.push(`- ${entry.nickname || 'unknown'}: ${entry.text || ''}`);
});
}
return lines.join('\n');
}
async function readSystemPrompt() { async function readSystemPrompt() {
const prompt = await fsp.readFile(PROMPT_PATH, 'utf8'); const prompt = await fsp.readFile(PROMPT_PATH, 'utf8');
const trimmed = prompt.trim(); const trimmed = prompt.trim();
@@ -449,10 +515,7 @@ async function generateCommentary(systemPrompt, snapshot) {
messages.push({ role: 'system', content: systemPrompt }); messages.push({ role: 'system', content: systemPrompt });
messages.push({ messages.push({
role: 'user', role: 'user',
content: JSON.stringify({ content: formatRunMetaMessage(snapshot?.run_meta || {}),
type: 'run_meta',
run_meta: snapshot?.run_meta || {},
}),
}); });
const timeline = Array.isArray(snapshot?.event_stream) ? snapshot.event_stream : []; const timeline = Array.isArray(snapshot?.event_stream) ? snapshot.event_stream : [];
timeline.forEach((event) => { timeline.forEach((event) => {
@@ -467,34 +530,21 @@ async function generateCommentary(systemPrompt, snapshot) {
if (event.type === 'chat') { if (event.type === 'chat') {
messages.push({ messages.push({
role: 'user', role: 'user',
content: JSON.stringify({ content: formatChatEventMessage(event),
type: 'chat',
nickname: event.nickname || 'unknown',
text: event.text || '',
rover_id: event.rover_id || null,
rover_ctx: event.rover_ctx || null,
}),
}); });
return; return;
} }
if (event.type === 'snapshot') { if (event.type === 'snapshot') {
messages.push({ messages.push({
role: 'user', role: 'user',
content: JSON.stringify({ content: formatSnapshotMessage(event),
type: 'snapshot',
reason: event.reason || null,
rovers: event.rovers || [],
}),
}); });
} }
}); });
// Always end with a full rover snapshot user message. // Always end with a full rover snapshot user message.
messages.push({ messages.push({
role: 'user', role: 'user',
content: JSON.stringify({ content: formatSnapshotFinalMessage(snapshot?.current_snapshot || {}),
type: 'snapshot_final',
current_snapshot: snapshot?.current_snapshot || {},
}),
}); });
updateStatus({ updateStatus({
lastModelMessages: messages, lastModelMessages: messages,
@@ -580,7 +630,7 @@ async function runTick() {
const snapshotSummary = { const snapshotSummary = {
activeDrivers: snapshot?.run_meta?.active_driver_count || 0, activeDrivers: snapshot?.run_meta?.active_driver_count || 0,
rovers: snapshot?.current_snapshot?.rovers?.length || 0, rovers: snapshot?.current_snapshot?.rovers?.length || 0,
chatMessages: snapshot?.current_snapshot?.chat_recent?.length || 0, chatMessages: (snapshot?.event_stream || []).filter((event) => event?.type === 'chat').length,
drivingRovers: snapshot?.run_meta?.driving_rovers || [], drivingRovers: snapshot?.run_meta?.driving_rovers || [],
eventCount: snapshot?.event_stream?.length || 0, eventCount: snapshot?.event_stream?.length || 0,
}; };