This commit is contained in:
legop3
2026-02-26 03:32:31 -05:00
parent 5a575aeab4
commit d34c107b1a
2 changed files with 88 additions and 9 deletions
+63 -1
View File
@@ -105,12 +105,68 @@ function buildMessage(socket, text, meta = {}) {
discordUserId: meta.discordUserId || null,
discordUserName: meta.discordUserName || null,
discordUserAvatarUrl: meta.discordUserAvatarUrl || null,
roverCtx: meta.roverCtx || null,
text,
tts: meta.tts || null,
system: Boolean(meta.system),
};
}
function isChargingFromSensors(sensors = {}) {
const label = String(sensors?.chargingState?.label || '').toLowerCase();
if (label === 'waiting' || label === 'full charging' || label === 'trickle charging') {
return true;
}
const code = sensors?.chargingState?.code;
return code === 2 || code === 3 || code === 4;
}
function buildRoverCtxSnapshot(roverId) {
if (!roverId) return null;
const key = String(roverId);
const record = roverManager.rovers.get(key);
if (!record) return null;
const sensors = record?.lastSensor?.decoded || {};
const batteryState = record?.batteryState || null;
const { getActiveDrivers } = require('./turnService');
const activeDrivers = getActiveDrivers();
const driverSocketId = activeDrivers[key] || record?.drivers?.values?.().next?.().value || null;
const charging = isChargingFromSensors(sensors);
const docked = Boolean(sensors?.chargingSources?.homeBase);
const wheelsOffGround = Boolean(
sensors?.bumpsAndWheelDrops?.wheelDropLeft && sensors?.bumpsAndWheelDrops?.wheelDropRight,
);
const latestDistanceM = Math.round((Math.abs(Number(sensors?.distanceMm) || 0) / 1000) * 10) / 10;
const latestTurnDeg = Math.round(Math.abs(Number(sensors?.angleDeg) || 0));
const latestBumps =
(sensors?.bumpsAndWheelDrops?.bumpLeft ? 0.5 : 0) +
(sensors?.bumpsAndWheelDrops?.bumpRight ? 0.5 : 0);
const moving = latestDistanceM > 0.05 || latestTurnDeg > 10;
let statusTag = 'idle';
if (charging) {
statusTag = 'charging';
} else if (docked) {
statusTag = 'docked';
} else if (driverSocketId && moving) {
statusTag = 'driving';
} else if (driverSocketId) {
statusTag = 'active-idle';
}
return {
id: key,
status_tag: statusTag,
battery_low: Boolean(batteryState?.warnActive || batteryState?.urgentActive),
docked,
charging,
wheels_off_ground: wheelsOffGround,
activity_30s: {
distance_m: latestDistanceM,
turn_deg: latestTurnDeg,
bumps: latestBumps,
},
};
}
function buildTypingPayload(socket, meta = {}) {
const roverId = meta.roverId || resolveRoverId(socket?.id);
const socketId = socket?.id || null;
@@ -282,7 +338,12 @@ function handleIncoming({ text, tts } = {}, socket, cb = () => {}) {
// }
const roverId = resolveRoverId(socket?.id);
const ttsOptions = normalizeTtsOptions(tts);
const message = buildMessage(socket, clean, { fromDiscord: false, roverId, tts: ttsOptions });
const message = buildMessage(socket, clean, {
fromDiscord: false,
roverId,
roverCtx: buildRoverCtxSnapshot(roverId),
tts: ttsOptions,
});
logger.info('Chat message', { socket: socket.id, roverId: message.roverId });
playTypingNote(roverId, TYPING_SEND_NOTE, socket?.id);
broadcastMessage(message);
@@ -349,6 +410,7 @@ function sendExternalMessage({
nickname,
role,
roverId,
roverCtx: buildRoverCtxSnapshot(roverId),
fromDiscord: true,
discordGuildId,
discordGuildName,
+25 -8
View File
@@ -477,12 +477,8 @@ function compactRoverForContext(rover) {
};
}
function buildSnapshot() {
const now = new Date();
const nowMs = now.getTime();
function buildRoversNow(nowMs = Date.now()) {
const activeDrivers = getActiveDrivers();
const driverEntries = collectActiveDriverEntries();
const roster = roverManager.getRoster().slice(0, MAX_ROVERS);
const nextRoverStateById = new Map();
const rovers = roster.map((entry) => {
@@ -537,6 +533,14 @@ function buildSnapshot() {
nextRoverStateById.forEach((value, roverId) => {
lastRoverStateById.set(roverId, value);
});
return { rovers, activeDrivers, roster };
}
function buildSnapshot() {
const now = new Date();
const nowMs = now.getTime();
const driverEntries = collectActiveDriverEntries();
const { rovers } = buildRoversNow(nowMs);
const roverById = new Map(rovers.map((rover) => [String(rover.id), rover]));
const allRecentMessages = getRecentMessages(300, { includeSystem: true })
.filter((entry) => Number(entry?.ts) >= contextResetAt);
@@ -571,7 +575,7 @@ function buildSnapshot() {
nickname: entry.nickname || entry.socketId?.slice(0, 6) || 'unknown',
text: entry.text || '',
rover_id: roverId,
rover_ctx: compactRoverForContext(rover),
rover_ctx: entry?.roverCtx || entry?.rover_ctx || compactRoverForContext(rover),
};
});
const hasRecentChat = eventStream.some((event) => event.type === 'chat');
@@ -604,6 +608,17 @@ function buildSnapshot() {
};
}
function refreshFinalSnapshotForSend(snapshot) {
const { rovers } = buildRoversNow(Date.now());
return {
...(snapshot || {}),
current_snapshot: {
...(snapshot?.current_snapshot || {}),
rovers,
},
};
}
function normalizeCommentary(rawText) {
if (typeof rawText !== 'string') return null;
const trimmed = rawText.trim();
@@ -832,14 +847,15 @@ async function runTick() {
lastInfoSnapshot: snapshot,
});
const systemPrompt = await readSystemPrompt();
const modelMessages = buildModelMessages(systemPrompt, snapshot);
const snapshotForSend = refreshFinalSnapshotForSend(snapshot);
const modelMessages = buildModelMessages(systemPrompt, snapshotForSend);
const modelInputAt = Date.now();
patchCurrentRun({
phase: 'input_ready',
input: {
...(currentRun?.input || {}),
systemPrompt,
infoSnapshot: snapshot,
infoSnapshot: snapshotForSend,
modelMessages,
modelInputAt,
},
@@ -848,6 +864,7 @@ async function runTick() {
lastModelMessages: modelMessages,
lastModelInputAt: modelInputAt,
lastModelInputTickId: tickId,
lastInfoSnapshot: snapshotForSend,
lastModelRawOutput: null,
lastModelOutputAt: null,
lastModelOutputTickId: null,