Skip to content

Commit a381fe2

Browse files
chil logs update + workers
1 parent 22259f3 commit a381fe2

10 files changed

Lines changed: 62 additions & 12 deletions

File tree

apps/dashboard/routes/child-details.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ router.get("/children/:id/details", (req, res) => {
1515
const { id } = req.params;
1616

1717
// ── Core metadata ──────────────────────────────────
18-
const child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
18+
// Support lookup by id, sandbox_id, or address
19+
let child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
20+
if (!child) child = db.safeGet("SELECT * FROM children WHERE sandbox_id = ?", [id]);
21+
if (!child) child = db.safeGet("SELECT * FROM children WHERE address = ? OR address = ?", [id, `local://${id}`]);
1922
if (!child) {
2023
return res.status(404).json({ error: "Child not found", id });
2124
}

apps/dashboard/routes/child-ledger.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ const router = Router();
1313
router.get("/children/:id/ledger", (req, res) => {
1414
const { id } = req.params;
1515

16-
const child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
16+
let child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
17+
if (!child) child = db.safeGet("SELECT * FROM children WHERE sandbox_id = ?", [id]);
18+
if (!child) child = db.safeGet("SELECT * FROM children WHERE address = ? OR address = ?", [id, `local://${id}`]);
1719
if (!child) {
1820
return res.status(404).json({ error: "Child not found", id });
1921
}

apps/dashboard/routes/child-logs.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,16 @@ router.get("/children/:id/logs", (req, res) => {
138138
const maxLines = Math.min(parseInt(req.query.lines || "200", 10), 500);
139139

140140
// Get child metadata for additional search terms
141-
const child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
141+
let child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
142+
if (!child) child = db.safeGet("SELECT * FROM children WHERE sandbox_id = ?", [id]);
143+
if (!child) child = db.safeGet("SELECT * FROM children WHERE address = ? OR address = ?", [id, `local://${id}`]);
142144
const searchTerms = [id];
143145
if (child) {
146+
// sandbox_id is the unique worker identifier (e.g. local-worker-01KJEN...)
144147
if (child.sandbox_id) searchTerms.push(child.sandbox_id);
145-
if (child.name) searchTerms.push(child.name);
146-
if (child.address) searchTerms.push(child.address.slice(0, 12));
148+
// Full address for exact matching (don't slice — slicing to 12 chars
149+
// matches "local://loca" which hits ALL local workers)
150+
if (child.address) searchTerms.push(child.address);
147151
}
148152

149153
// Try journalctl first, fall back to log files

apps/dashboard/routes/child-resources.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ const router = Router();
1414
router.get("/children/:id/resources", (req, res) => {
1515
const { id } = req.params;
1616

17-
const child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
17+
let child = db.safeGet("SELECT * FROM children WHERE id = ?", [id]);
18+
if (!child) child = db.safeGet("SELECT * FROM children WHERE sandbox_id = ?", [id]);
19+
if (!child) child = db.safeGet("SELECT * FROM children WHERE address = ? OR address = ?", [id, `local://${id}`]);
1820
if (!child) {
1921
return res.status(404).json({ error: "Child not found", id });
2022
}

apps/dashboard/routes/children.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ router.get("/children", (_req, res) => {
88
});
99

1010
router.get("/children/:id", (req, res) => {
11-
const child = db.safeGet("SELECT * FROM children WHERE id = ?", [req.params.id]);
11+
let child = db.safeGet("SELECT * FROM children WHERE id = ?", [req.params.id]);
12+
if (!child) child = db.safeGet("SELECT * FROM children WHERE sandbox_id = ?", [req.params.id]);
13+
if (!child) child = db.safeGet("SELECT * FROM children WHERE address = ? OR address = ?", [req.params.id, `local://${req.params.id}`]);
1214
if (!child) {
1315
return res.status(404).json({ error: "Child not found" });
1416
}

apps/dashboard/routes/derived-health.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ router.get("/health/derived", (_req, res) => {
7272

7373
const lastCheckedMs = c.last_checked ? new Date(c.last_checked).getTime() : 0;
7474
const lastActMs = lastActivity?.last_act ? new Date(lastActivity.last_act).getTime() : 0;
75-
const lastSignal = Math.max(lastCheckedMs, lastActMs);
75+
// Also check event_stream for worker_log entries (local workers use this)
76+
const lastWorkerLog = safeGet(`SELECT MAX(created_at) as t FROM event_stream WHERE type = 'worker_log' AND agent_address = ?`, [c.address || ""]);
77+
const lastLogMs = lastWorkerLog?.t ? new Date(lastWorkerLog.t).getTime() : 0;
78+
const lastSignal = Math.max(lastCheckedMs, lastActMs, lastLogMs);
7679
const silenceMs = lastSignal > 0 ? now - lastSignal : now;
7780

7881
// Assigned tasks for this worker

apps/dashboard/routes/diagnostics-snapshot.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,12 @@ router.get("/diagnostics/snapshot", (_req, res) => {
156156
} else {
157157
lines.push(`Total: ${children.length}`);
158158
for (const c of children) {
159-
const lastCheckedAge = c.last_checked ? Math.floor((now - new Date(c.last_checked).getTime()) / 60000) : null;
159+
const lastCheckedMs = c.last_checked ? new Date(c.last_checked).getTime() : 0;
160+
// Also check event_stream for recent worker_log entries (same fix as workers.js)
161+
const lastWorkerLog = safeGet(`SELECT MAX(created_at) as t FROM event_stream WHERE type = 'worker_log' AND agent_address = ?`, [c.address || ""]);
162+
const lastLogMs = lastWorkerLog?.t ? new Date(lastWorkerLog.t).getTime() : 0;
163+
const lastSignal = Math.max(lastCheckedMs, lastLogMs);
164+
const lastCheckedAge = lastSignal > 0 ? Math.floor((now - lastSignal) / 60000) : null;
160165
const createdAge = Math.floor((now - new Date(c.created_at).getTime()) / 60000);
161166
const isLocal = c.address?.startsWith("local://");
162167
const runtime = isLocal ? "local" : "cloud";

apps/dashboard/routes/workers.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,16 @@ router.get("/workers", (_req, res) => {
3030
SELECT MAX(created_at) as t FROM child_ledger WHERE address = ?
3131
`, [c.address || ""]);
3232

33+
// Also check event_stream for worker_log entries (local workers use this)
34+
const lastWorkerLog = safeGet(`
35+
SELECT MAX(created_at) as t FROM event_stream
36+
WHERE type = 'worker_log' AND agent_address = ?
37+
`, [c.address || ""]);
38+
3339
const lastCheckedMs = c.last_checked ? new Date(c.last_checked).getTime() : 0;
3440
const lastLedgerMs = lastLedger?.t ? new Date(lastLedger.t).getTime() : 0;
35-
const lastSignal = Math.max(lastCheckedMs, lastLedgerMs);
41+
const lastLogMs = lastWorkerLog?.t ? new Date(lastWorkerLog.t).getTime() : 0;
42+
const lastSignal = Math.max(lastCheckedMs, lastLedgerMs, lastLogMs);
3643
const silenceMs = lastSignal > 0 ? now - lastSignal : -1;
3744

3845
// Spend

src/orchestration/local-worker.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ async function localReadFile(filePath: string): Promise<string> {
5151
const logger = createLogger("orchestration.local-worker");
5252

5353
const MAX_TURNS = 25;
54-
const DEFAULT_TIMEOUT_MS = 5 * 60_000;
54+
const DEFAULT_TIMEOUT_MS = 10 * 60_000;
5555
const INFERENCE_TIMEOUT_MS = 60_000; // Per-call timeout for inference API
5656
const INFERENCE_MAX_RETRIES = 1; // Retry once on inference failure
5757

@@ -221,6 +221,15 @@ export class LocalWorkerPool {
221221
logger.info(`[WORKER ${workerId}] Turn ${turn + 1}/${maxTurns} — calling inference (tier: fast)`);
222222
this.workerLog(workerId, task, `Turn ${turn + 1}/${maxTurns} — calling inference`);
223223

224+
// Heartbeat: update last_checked every 3 turns so dashboard sees worker is alive
225+
if (turn % 3 === 0) {
226+
try {
227+
this.config.db.prepare(
228+
`UPDATE children SET last_checked = ? WHERE address = ?`,
229+
).run(new Date().toISOString(), workerAddress);
230+
} catch { /* best-effort */ }
231+
}
232+
224233
let response;
225234
let lastError: string | null = null;
226235
for (let attempt = 0; attempt <= INFERENCE_MAX_RETRIES; attempt++) {

src/state/database.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,22 @@ export function createDatabase(dbPath: string): AutomatonDatabase {
387387
};
388388

389389
const getChildById = (id: string): ChildAutomaton | undefined => {
390-
const row = db
390+
// Primary lookup by ID
391+
let row = db
391392
.prepare("SELECT * FROM children WHERE id = ?")
392393
.get(id) as any | undefined;
394+
// Fallback: search by sandbox_id (local workers use this as their identifier)
395+
if (!row) {
396+
row = db
397+
.prepare("SELECT * FROM children WHERE sandbox_id = ?")
398+
.get(id) as any | undefined;
399+
}
400+
// Fallback: search by address (e.g. "local://local-worker-...")
401+
if (!row) {
402+
row = db
403+
.prepare("SELECT * FROM children WHERE address = ? OR address = ?")
404+
.get(id, `local://${id}`) as any | undefined;
405+
}
393406
return row ? deserializeChild(row) : undefined;
394407
};
395408

0 commit comments

Comments
 (0)