more better panel stuff and promp

This commit is contained in:
legop3
2026-05-04 02:50:32 -04:00
parent a66a68d7eb
commit 0ea96613b0
6 changed files with 49 additions and 13 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ Execution mode:
- Decide what to do yourself each cycle. - Decide what to do yourself each cycle.
Actions: Actions:
- Use tool calls when actions are needed. - Use tool calls when actions or memory updates are needed.
- Respect safety limits, lock policies, cooldowns, and blocked tools. - Respect safety limits, lock policies, cooldowns, and blocked tools.
- Do not invent tools. - Do not invent tools.
- Ask a question only if a required action parameter is missing. - Ask a question only if a required action parameter is missing.
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -11,7 +11,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" /> <meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
<title>Multi Roomba Rover</title> <title>Multi Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-BP-0CHxN.js"></script> <script type="module" crossorigin src="/assets/index-D8G6mAM9.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CGvUXLso.css"> <link rel="stylesheet" crossorigin href="/assets/index-CGvUXLso.css">
</head> </head>
<body> <body>
@@ -49,6 +49,7 @@ const runtime = {
generationCount: 0, generationCount: 0,
generationTotalMs: 0, generationTotalMs: 0,
runHistory: [], runHistory: [],
liveToolCalls: [],
memoryStore: loadMemory(), memoryStore: loadMemory(),
}; };
@@ -84,6 +85,7 @@ let status = {
lastChatDraft: null, lastChatDraft: null,
lastRequestedActions: null, lastRequestedActions: null,
lastActionResults: null, lastActionResults: null,
lastLiveToolCalls: null,
lastOutcome: null, lastOutcome: null,
lastReason: null, lastReason: null,
lastError: null, lastError: null,
@@ -108,6 +110,11 @@ function pushRun(run = {}) {
runtime.runHistory = [...runtime.runHistory.slice(-(MAX_RUN_HISTORY - 1)), run]; runtime.runHistory = [...runtime.runHistory.slice(-(MAX_RUN_HISTORY - 1)), run];
} }
function pushLiveToolCall(entry = {}) {
runtime.liveToolCalls = [...runtime.liveToolCalls.slice(-49), { at: Date.now(), ...entry }];
updateStatus({ lastLiveToolCalls: runtime.liveToolCalls });
}
async function readPrompt() { async function readPrompt() {
const raw = await fsp.readFile(PROMPT_PATH, 'utf8'); const raw = await fsp.readFile(PROMPT_PATH, 'utf8');
const prompt = String(raw || '').replace(/<NAME>/g, name).trim(); const prompt = String(raw || '').replace(/<NAME>/g, name).trim();
@@ -256,7 +263,9 @@ async function runDecision(triggerReason) {
if (decision === 'ACTION' || decision === 'ACTION+CHAT') { if (decision === 'ACTION' || decision === 'ACTION+CHAT') {
for (const action of requestedActions) { for (const action of requestedActions) {
pushLiveToolCall({ phase: 'start', tool: action.tool, args: action.args });
if (!toolState.availableIds.includes(action.tool)) { if (!toolState.availableIds.includes(action.tool)) {
pushLiveToolCall({ phase: 'blocked', tool: action.tool, error: 'tool unavailable or blocked' });
actionResults.push({ kind: 'tool', tool: action.tool, ok: false, error: 'tool unavailable or blocked' }); actionResults.push({ kind: 'tool', tool: action.tool, ok: false, error: 'tool unavailable or blocked' });
continue; continue;
} }
@@ -274,8 +283,10 @@ async function runDecision(triggerReason) {
if (result?.memory && typeof result.memory === 'object') { if (result?.memory && typeof result.memory === 'object') {
runtime.memoryStore = saveMemory(result.memory); runtime.memoryStore = saveMemory(result.memory);
} }
pushLiveToolCall({ phase: 'ok', tool: action.tool, result });
actionResults.push({ kind: 'tool', tool: action.tool, ok: true, result }); actionResults.push({ kind: 'tool', tool: action.tool, ok: true, result });
} catch (err) { } catch (err) {
pushLiveToolCall({ phase: 'error', tool: action.tool, error: err.message });
actionResults.push({ kind: 'tool', tool: action.tool, ok: false, error: err.message }); actionResults.push({ kind: 'tool', tool: action.tool, ok: false, error: err.message });
} }
} }
@@ -348,10 +359,11 @@ function emitStateToSocket(socket) {
function clearHistory() { function clearHistory() {
runtime.runHistory = []; runtime.runHistory = [];
runtime.liveToolCalls = [];
runtime.generationCount = 0; runtime.generationCount = 0;
runtime.generationTotalMs = 0; runtime.generationTotalMs = 0;
runtime.memoryStore = saveMemory(createDefaultMemory()); runtime.memoryStore = saveMemory(createDefaultMemory());
updateStatus({ lastReason: 'admin requested clear history', lastOutcome: 'cleared' }); updateStatus({ lastReason: 'admin requested clear history', lastOutcome: 'cleared', lastLiveToolCalls: [] });
} }
io.on('connection', (socket) => { io.on('connection', (socket) => {
@@ -41,6 +41,7 @@ function buildAdminState(status, runHistory) {
chat: status.lastChatDraft, chat: status.lastChatDraft,
actions: status.lastRequestedActions, actions: status.lastRequestedActions,
actionResults: status.lastActionResults, actionResults: status.lastActionResults,
liveToolCalls: status.lastLiveToolCalls || [],
outputAt: status.lastModelOutputAt, outputAt: status.lastModelOutputAt,
outcome: status.lastOutcome, outcome: status.lastOutcome,
reason: status.lastReason, reason: status.lastReason,
@@ -17,6 +17,17 @@ export default function OverseerControlPanel({ state, onClearHistory, clearingHi
const timings = state.timings || {}; const timings = state.timings || {};
const input = state.input || {}; const input = state.input || {};
const errors = state.errors || {}; const errors = state.errors || {};
const renderModelMessages = () => {
const messages = Array.isArray(input.modelMessages) ? input.modelMessages : [];
if (!messages.length) return '<none>';
return messages
.map((msg, idx) => {
const role = String(msg?.role || 'unknown').toUpperCase();
const content = String(msg?.content || '');
return `#${idx + 1} ${role}\n${content}`;
})
.join('\n\n----------------------------------------\n\n');
};
return ( return (
<div className="space-y-0.5"> <div className="space-y-0.5">
@@ -55,7 +66,7 @@ export default function OverseerControlPanel({ state, onClearHistory, clearingHi
<details className="surface text-xs text-slate-200" open> <details className="surface text-xs text-slate-200" open>
<summary className="cursor-pointer select-none text-slate-300">Exact Model Input (messages[])</summary> <summary className="cursor-pointer select-none text-slate-300">Exact Model Input (messages[])</summary>
<pre className="mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200"> <pre className="mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200">
{JSON.stringify(input.modelMessages || [], null, 2)} {renderModelMessages()}
</pre> </pre>
</details> </details>
@@ -87,6 +98,13 @@ export default function OverseerControlPanel({ state, onClearHistory, clearingHi
</pre> </pre>
</details> </details>
<details className="surface text-xs text-slate-200" open>
<summary className="cursor-pointer select-none text-slate-300">Live Tool Calls</summary>
<pre className="mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200">
{JSON.stringify(output.liveToolCalls || [], null, 2)}
</pre>
</details>
<div className="surface text-xs text-slate-200"> <div className="surface text-xs text-slate-200">
<div>Normalized decision: {output.normalized || '--'}</div> <div>Normalized decision: {output.normalized || '--'}</div>
<div>Model input at: {input.modelInputAt ? new Date(input.modelInputAt).toLocaleString() : 'n/a'}</div> <div>Model input at: {input.modelInputAt ? new Date(input.modelInputAt).toLocaleString() : 'n/a'}</div>