@0xmaxma/claude-gateway 2.0.4 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/agent/builtin-commands.d.ts +1 -1
- package/dist/agent/builtin-commands.d.ts.map +1 -1
- package/dist/agent/builtin-commands.js +3 -2
- package/dist/agent/builtin-commands.js.map +1 -1
- package/dist/agent/runner.d.ts +109 -9
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +148 -119
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/skill-learning/index.d.ts.map +1 -1
- package/dist/agent/skill-learning/index.js +27 -8
- package/dist/agent/skill-learning/index.js.map +1 -1
- package/dist/agent/skill-learning/reviewer.d.ts +3 -1
- package/dist/agent/skill-learning/reviewer.d.ts.map +1 -1
- package/dist/agent/skill-learning/reviewer.js +6 -2
- package/dist/agent/skill-learning/reviewer.js.map +1 -1
- package/dist/agent/turn-stream.d.ts +3 -1
- package/dist/agent/turn-stream.d.ts.map +1 -1
- package/dist/agent/turn-stream.js +8 -4
- package/dist/agent/turn-stream.js.map +1 -1
- package/dist/api/gateway-router.d.ts +2 -0
- package/dist/api/gateway-router.d.ts.map +1 -1
- package/dist/api/gateway-router.js +229 -12
- package/dist/api/gateway-router.js.map +1 -1
- package/dist/api/router.js +11 -11
- package/dist/api/router.js.map +1 -1
- package/dist/api/slack-webhook-router.js +1 -1
- package/dist/api/slack-webhook-router.js.map +1 -1
- package/dist/api/voice-router.d.ts +1 -0
- package/dist/api/voice-router.d.ts.map +1 -1
- package/dist/api/voice-router.js +129 -7
- package/dist/api/voice-router.js.map +1 -1
- package/dist/config/claude-settings.d.ts +14 -0
- package/dist/config/claude-settings.d.ts.map +1 -1
- package/dist/config/claude-settings.js +20 -0
- package/dist/config/claude-settings.js.map +1 -1
- package/dist/orchestration/agent-cli-session.d.ts +46 -0
- package/dist/orchestration/agent-cli-session.d.ts.map +1 -0
- package/dist/orchestration/agent-cli-session.js +121 -0
- package/dist/orchestration/agent-cli-session.js.map +1 -0
- package/dist/orchestration/agent-tool-schemas.d.ts +6 -0
- package/dist/orchestration/agent-tool-schemas.d.ts.map +1 -0
- package/dist/orchestration/agent-tool-schemas.js +23 -0
- package/dist/orchestration/agent-tool-schemas.js.map +1 -0
- package/dist/orchestration/bridge.d.ts +6 -3
- package/dist/orchestration/bridge.d.ts.map +1 -1
- package/dist/orchestration/bridge.js +31 -14
- package/dist/orchestration/bridge.js.map +1 -1
- package/dist/orchestration/browser-voice.d.ts +14 -0
- package/dist/orchestration/browser-voice.d.ts.map +1 -0
- package/dist/orchestration/browser-voice.js +30 -0
- package/dist/orchestration/browser-voice.js.map +1 -0
- package/dist/orchestration/context-footprint.d.ts +14 -0
- package/dist/orchestration/context-footprint.d.ts.map +1 -0
- package/dist/orchestration/context-footprint.js +57 -0
- package/dist/orchestration/context-footprint.js.map +1 -0
- package/dist/orchestration/dashboard-reader-worker.d.ts +2 -0
- package/dist/orchestration/dashboard-reader-worker.d.ts.map +1 -0
- package/dist/orchestration/dashboard-reader-worker.js +155 -0
- package/dist/orchestration/dashboard-reader-worker.js.map +1 -0
- package/dist/orchestration/dashboard-reader.d.ts +15 -0
- package/dist/orchestration/dashboard-reader.d.ts.map +1 -0
- package/dist/orchestration/dashboard-reader.js +87 -0
- package/dist/orchestration/dashboard-reader.js.map +1 -0
- package/dist/orchestration/decision-context.d.ts +15 -0
- package/dist/orchestration/decision-context.d.ts.map +1 -0
- package/dist/orchestration/decision-context.js +57 -0
- package/dist/orchestration/decision-context.js.map +1 -0
- package/dist/orchestration/display-stream.d.ts +21 -2
- package/dist/orchestration/display-stream.d.ts.map +1 -1
- package/dist/orchestration/display-stream.js +61 -8
- package/dist/orchestration/display-stream.js.map +1 -1
- package/dist/orchestration/inference-errors.d.ts.map +1 -1
- package/dist/orchestration/inference-errors.js +19 -21
- package/dist/orchestration/inference-errors.js.map +1 -1
- package/dist/orchestration/mutation-recovery.d.ts +12 -0
- package/dist/orchestration/mutation-recovery.d.ts.map +1 -0
- package/dist/orchestration/mutation-recovery.js +41 -0
- package/dist/orchestration/mutation-recovery.js.map +1 -0
- package/dist/orchestration/native-compact.d.ts +5 -0
- package/dist/orchestration/native-compact.d.ts.map +1 -0
- package/dist/orchestration/native-compact.js +29 -0
- package/dist/orchestration/native-compact.js.map +1 -0
- package/dist/orchestration/notification-mailbox.d.ts +3 -1
- package/dist/orchestration/notification-mailbox.d.ts.map +1 -1
- package/dist/orchestration/notification-mailbox.js +4 -2
- package/dist/orchestration/notification-mailbox.js.map +1 -1
- package/dist/orchestration/process-turn.d.ts +15 -2
- package/dist/orchestration/process-turn.d.ts.map +1 -1
- package/dist/orchestration/process-turn.js +78 -14
- package/dist/orchestration/process-turn.js.map +1 -1
- package/dist/orchestration/progress-review.d.ts +8 -18
- package/dist/orchestration/progress-review.d.ts.map +1 -1
- package/dist/orchestration/progress-review.js +12 -14
- package/dist/orchestration/progress-review.js.map +1 -1
- package/dist/orchestration/provider-message.d.ts +7 -0
- package/dist/orchestration/provider-message.d.ts.map +1 -0
- package/dist/orchestration/provider-message.js +63 -0
- package/dist/orchestration/provider-message.js.map +1 -0
- package/dist/orchestration/response-errors.d.ts +6 -0
- package/dist/orchestration/response-errors.d.ts.map +1 -0
- package/dist/orchestration/response-errors.js +88 -0
- package/dist/orchestration/response-errors.js.map +1 -0
- package/dist/orchestration/response-schema.d.ts +33 -0
- package/dist/orchestration/response-schema.d.ts.map +1 -0
- package/dist/orchestration/response-schema.js +61 -0
- package/dist/orchestration/response-schema.js.map +1 -0
- package/dist/orchestration/runtime.d.ts +67 -0
- package/dist/orchestration/runtime.d.ts.map +1 -1
- package/dist/orchestration/runtime.js +266 -62
- package/dist/orchestration/runtime.js.map +1 -1
- package/dist/orchestration/skills.d.ts.map +1 -1
- package/dist/orchestration/skills.js +3 -2
- package/dist/orchestration/skills.js.map +1 -1
- package/dist/orchestration/source-policy.d.ts +1 -1
- package/dist/orchestration/source-policy.d.ts.map +1 -1
- package/dist/orchestration/source-policy.js +1 -1
- package/dist/orchestration/speech.d.ts +15 -17
- package/dist/orchestration/speech.d.ts.map +1 -1
- package/dist/orchestration/speech.js +90 -30
- package/dist/orchestration/speech.js.map +1 -1
- package/dist/orchestration/store.d.ts +2 -0
- package/dist/orchestration/store.d.ts.map +1 -1
- package/dist/orchestration/store.js +16 -1
- package/dist/orchestration/store.js.map +1 -1
- package/dist/orchestration/tasks/driver.d.ts.map +1 -1
- package/dist/orchestration/tasks/driver.js +8 -3
- package/dist/orchestration/tasks/driver.js.map +1 -1
- package/dist/orchestration/tasks/pool.d.ts.map +1 -1
- package/dist/orchestration/tasks/pool.js +8 -4
- package/dist/orchestration/tasks/pool.js.map +1 -1
- package/dist/orchestration/tasks/service.d.ts +48 -1
- package/dist/orchestration/tasks/service.d.ts.map +1 -1
- package/dist/orchestration/tasks/service.js +41 -17
- package/dist/orchestration/tasks/service.js.map +1 -1
- package/dist/orchestration/token-ledger.d.ts +125 -0
- package/dist/orchestration/token-ledger.d.ts.map +1 -0
- package/dist/orchestration/token-ledger.js +232 -0
- package/dist/orchestration/token-ledger.js.map +1 -0
- package/dist/orchestration/token-usage.d.ts +46 -0
- package/dist/orchestration/token-usage.d.ts.map +1 -0
- package/dist/orchestration/token-usage.js +102 -0
- package/dist/orchestration/token-usage.js.map +1 -0
- package/dist/orchestration/tool-activity.d.ts.map +1 -1
- package/dist/orchestration/tool-activity.js +5 -3
- package/dist/orchestration/tool-activity.js.map +1 -1
- package/dist/orchestration/tool-name.d.ts +10 -0
- package/dist/orchestration/tool-name.d.ts.map +1 -0
- package/dist/orchestration/tool-name.js +14 -0
- package/dist/orchestration/tool-name.js.map +1 -0
- package/dist/orchestration/transcript-checkpoint.d.ts +14 -0
- package/dist/orchestration/transcript-checkpoint.d.ts.map +1 -0
- package/dist/orchestration/transcript-checkpoint.js +83 -0
- package/dist/orchestration/transcript-checkpoint.js.map +1 -0
- package/dist/orchestration/unanswered-inputs.d.ts +6 -0
- package/dist/orchestration/unanswered-inputs.d.ts.map +1 -0
- package/dist/orchestration/unanswered-inputs.js +18 -0
- package/dist/orchestration/unanswered-inputs.js.map +1 -0
- package/dist/session/process.d.ts +10 -0
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +91 -9
- package/dist/session/process.js.map +1 -1
- package/dist/session/request-tool-capture.d.ts +31 -0
- package/dist/session/request-tool-capture.d.ts.map +1 -0
- package/dist/session/request-tool-capture.js +194 -0
- package/dist/session/request-tool-capture.js.map +1 -0
- package/dist/session/runtime-profile.d.ts +7 -3
- package/dist/session/runtime-profile.d.ts.map +1 -1
- package/dist/session/runtime-profile.js +3 -1
- package/dist/session/runtime-profile.js.map +1 -1
- package/dist/session/store.d.ts +7 -0
- package/dist/session/store.d.ts.map +1 -1
- package/dist/session/store.js +27 -0
- package/dist/session/store.js.map +1 -1
- package/dist/shell/tailer.d.ts +7 -5
- package/dist/shell/tailer.d.ts.map +1 -1
- package/dist/shell/tailer.js +6 -17
- package/dist/shell/tailer.js.map +1 -1
- package/dist/ui/cli-viewer-ui.js +1 -1
- package/dist/ui/dashboard-client.d.ts +3 -0
- package/dist/ui/dashboard-client.d.ts.map +1 -0
- package/dist/ui/dashboard-client.js +188 -0
- package/dist/ui/dashboard-client.js.map +1 -0
- package/dist/ui/dashboard-presentation.d.ts +9 -0
- package/dist/ui/dashboard-presentation.d.ts.map +1 -0
- package/dist/ui/dashboard-presentation.js +56 -0
- package/dist/ui/dashboard-presentation.js.map +1 -0
- package/dist/ui/dashboard-range.d.ts +5 -0
- package/dist/ui/dashboard-range.d.ts.map +1 -0
- package/dist/ui/dashboard-range.js +20 -0
- package/dist/ui/dashboard-range.js.map +1 -0
- package/dist/ui/dashboard-theme.d.ts +4 -0
- package/dist/ui/dashboard-theme.d.ts.map +1 -0
- package/dist/ui/dashboard-theme.js +485 -0
- package/dist/ui/dashboard-theme.js.map +1 -0
- package/dist/ui/token-report-client.d.ts +3 -0
- package/dist/ui/token-report-client.d.ts.map +1 -0
- package/dist/ui/token-report-client.js +34 -0
- package/dist/ui/token-report-client.js.map +1 -0
- package/dist/ui/token-report.d.ts +89 -0
- package/dist/ui/token-report.d.ts.map +1 -0
- package/dist/ui/token-report.js +200 -0
- package/dist/ui/token-report.js.map +1 -0
- package/dist/ui/web-ui.d.ts.map +1 -1
- package/dist/ui/web-ui.js +124 -181
- package/dist/ui/web-ui.js.map +1 -1
- package/dist/voice/replay.d.ts +8 -0
- package/dist/voice/replay.d.ts.map +1 -0
- package/dist/voice/replay.js +48 -0
- package/dist/voice/replay.js.map +1 -0
- package/dist/voice/session.d.ts +9 -0
- package/dist/voice/session.d.ts.map +1 -1
- package/dist/voice/session.js +72 -14
- package/dist/voice/session.js.map +1 -1
- package/mcp/lazy-connector.test.ts +58 -0
- package/mcp/lazy-connector.ts +67 -0
- package/mcp/lazy-tools.test.ts +152 -0
- package/mcp/lazy-tools.ts +41 -0
- package/mcp/server.ts +53 -34
- package/mcp/tools/discord/commands.ts +2 -0
- package/mcp/tools/tasks/module.ts +1 -12
- package/mcp/tools/telegram/receiver-server.ts +14 -14
- package/package.json +2 -1
- package/resource/dashboard/OFL.txt +93 -0
- package/resource/dashboard/poppins-300.woff2 +0 -0
- package/resource/dashboard/poppins-400.woff2 +0 -0
- package/resource/dashboard/poppins-500.woff2 +0 -0
- package/resource/dashboard/poppins-600.woff2 +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const context_footprint_1 = require("./context-footprint");
|
|
4
|
+
const worker_threads_1 = require("worker_threads");
|
|
5
|
+
const node_sqlite_1 = require("node:sqlite");
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const token_ledger_1 = require("./token-ledger");
|
|
8
|
+
const task_directive_1 = require("./tasks/task-directive");
|
|
9
|
+
/**
|
|
10
|
+
* Conversation activity status — the single source shared by the dashboard
|
|
11
|
+
* Conversations "Status" column and the Session token report header, so the two
|
|
12
|
+
* views can never disagree (thinking → working → waiting_input → queued → idle).
|
|
13
|
+
* `thinking` is returned alongside so callers keep the existing isRunning signal
|
|
14
|
+
* without re-querying. Display-only; does not touch token accounting.
|
|
15
|
+
*/
|
|
16
|
+
function conversationActivityStatus(get, all, conversationId) {
|
|
17
|
+
const thinking = Boolean(get("SELECT id FROM conversation_decisions WHERE conversation_id=? AND state IN ('running','interrupting') LIMIT 1", conversationId));
|
|
18
|
+
const states = all("SELECT DISTINCT state FROM tasks WHERE conversation_id=? AND state NOT IN ('completed','failed','cancelled')", conversationId).map(t => t.state);
|
|
19
|
+
const lastTurn = get('SELECT MAX(ended_at) ended_at FROM conversation_decisions WHERE conversation_id=?', conversationId)?.ended_at;
|
|
20
|
+
const resting = lastTurn != null && Date.now() - Number(lastTurn) <= 3600000 ? 'idle' : 'stopped';
|
|
21
|
+
const status = thinking ? 'thinking' : states.includes('needs_reconciliation') ? 'needs_reconciliation' : states.some(s => ['starting', 'running', 'interrupting', 'cancel_requested', 'recovering'].includes(s)) ? 'working' : states.includes('waiting_input') ? 'waiting_input' : states.includes('queued') ? 'queued' : resting;
|
|
22
|
+
return { status, thinking };
|
|
23
|
+
}
|
|
24
|
+
const connections = new Map();
|
|
25
|
+
function database(filename) {
|
|
26
|
+
if (!(0, fs_1.existsSync)(filename))
|
|
27
|
+
return undefined;
|
|
28
|
+
let db = connections.get(filename);
|
|
29
|
+
if (!db) {
|
|
30
|
+
if (connections.size >= 32) {
|
|
31
|
+
const key = connections.keys().next().value;
|
|
32
|
+
connections.get(key).close();
|
|
33
|
+
connections.delete(key);
|
|
34
|
+
}
|
|
35
|
+
db = new node_sqlite_1.DatabaseSync(filename, { readOnly: true });
|
|
36
|
+
db.exec('PRAGMA query_only=ON; PRAGMA busy_timeout=1000');
|
|
37
|
+
connections.set(filename, db);
|
|
38
|
+
}
|
|
39
|
+
connections.delete(filename);
|
|
40
|
+
connections.set(filename, db);
|
|
41
|
+
return db;
|
|
42
|
+
}
|
|
43
|
+
function read(filename, operation, options) {
|
|
44
|
+
const db = database(filename);
|
|
45
|
+
if (!db)
|
|
46
|
+
return undefined;
|
|
47
|
+
const all = (sql, ...params) => db.prepare(sql).all(...params);
|
|
48
|
+
const get = (sql, ...params) => db.prepare(sql).get(...params);
|
|
49
|
+
const exists = (table) => Boolean(get("SELECT name FROM sqlite_master WHERE type='table' AND name=?", table));
|
|
50
|
+
if (!exists('conversations'))
|
|
51
|
+
return undefined;
|
|
52
|
+
const since = Math.max(0, Number(options.since) || 0);
|
|
53
|
+
// A read transaction makes the session/task/attempt relationships consistent.
|
|
54
|
+
db.exec('BEGIN');
|
|
55
|
+
try {
|
|
56
|
+
const adapter = { all, get, attempt: (id) => { const row = get('SELECT payload_json FROM task_attempts WHERE id=?', id); return row ? JSON.parse(row.payload_json) : undefined; } };
|
|
57
|
+
if (operation === 'report' || operation === 'session') {
|
|
58
|
+
if (!get('SELECT id FROM conversations WHERE agent_session_id=?', options.sessionId))
|
|
59
|
+
return undefined;
|
|
60
|
+
// Before the ledger table exists (an agent whose very first turn has not recorded
|
|
61
|
+
// usage yet) a queued input still has to be visible, so derive the pending rows
|
|
62
|
+
// without the token_turns lookup instead of returning an empty list.
|
|
63
|
+
const report = exists('token_turns') ? (0, token_ledger_1.readTokenReport)(adapter, options.sessionId, true, { offset: Math.max(0, Number(options.offset) || 0), limit: operation === 'report' ? 25 : 50, since, newestFirst: true }) : { sessionId: options.sessionId, turns: (0, token_ledger_1.pendingInputTurns)(adapter, options.sessionId, since, false), totals: { agentTokens: null, workerTokens: null, totalTokens: null }, coverage: 'recorded-turns-only' };
|
|
64
|
+
if (operation === 'session') {
|
|
65
|
+
const session = get('SELECT * FROM conversations WHERE agent_session_id=?', options.sessionId);
|
|
66
|
+
const offset = Math.max(0, Number(options.offset) || 0);
|
|
67
|
+
const tasks = all('SELECT id,state,snapshot_json,updated_at FROM tasks WHERE conversation_id=? AND updated_at>=? ORDER BY updated_at DESC,id LIMIT 50 OFFSET ?', session.id, since, offset).map(t => ({ taskId: t.id, state: t.state, title: JSON.parse(t.snapshot_json).title, updatedAt: t.updated_at }));
|
|
68
|
+
// Same activity status the Conversations column shows, so the session drawer's
|
|
69
|
+
// Context window box can use the same idle-vs-stopped disambiguation as the report page.
|
|
70
|
+
const activityStatus = conversationActivityStatus(get, all, session.id).status;
|
|
71
|
+
return { ...report, session: { sessionId: session.agent_session_id, source: session.source, chatId: session.chat_id, createdAt: session.created_at, updatedAt: session.updated_at }, tasks, totalTasks: Number(get('SELECT COUNT(*) n FROM tasks WHERE conversation_id=? AND updated_at>=?', session.id, since).n), offset, activityStatus };
|
|
72
|
+
}
|
|
73
|
+
const session = get('SELECT id,source,chat_id FROM conversations WHERE agent_session_id=?', options.sessionId);
|
|
74
|
+
// Same activity status the Conversations column shows, so the report header mirrors it.
|
|
75
|
+
const activityStatus = conversationActivityStatus(get, all, session.id).status;
|
|
76
|
+
return { ...report, source: session.source, chatId: session.chat_id, activityStatus, since, contextFootprint: (0, context_footprint_1.contextFootprint)(options.workspace) };
|
|
77
|
+
}
|
|
78
|
+
if (operation === 'task') {
|
|
79
|
+
const row = get('SELECT t.*,c.agent_session_id FROM tasks t JOIN conversations c ON c.id=t.conversation_id WHERE t.id=? AND c.agent_session_id=?', options.taskId, options.sessionId);
|
|
80
|
+
if (!row)
|
|
81
|
+
return undefined;
|
|
82
|
+
const snapshot = JSON.parse(row.snapshot_json);
|
|
83
|
+
// The assignment text is never stored on the task snapshot — it lives in task_revisions.
|
|
84
|
+
// Read the revisions the worker actually received (appliedRevision, or the newest authored
|
|
85
|
+
// one before the first claim) and normalize them exactly like TaskService.revision() does,
|
|
86
|
+
// so a revision > 1 shows the effective brief instead of append-only answer text.
|
|
87
|
+
const effectiveRevision = Number(snapshot.appliedRevision) || Number(snapshot.revision) || Number.MAX_SAFE_INTEGER;
|
|
88
|
+
const revisions = all('SELECT payload_json FROM task_revisions WHERE task_id=? AND revision<=? ORDER BY revision', options.taskId, effectiveRevision)
|
|
89
|
+
.map(r => JSON.parse(String(r.payload_json)));
|
|
90
|
+
const instructions = revisions.length ? (0, task_directive_1.normalizeTaskRevisions)(revisions).instructions : undefined;
|
|
91
|
+
const offset = Math.max(0, Number(options.offset) || 0);
|
|
92
|
+
const attempts = all(`SELECT payload_json FROM task_attempts WHERE task_id=? AND COALESCE(json_extract(payload_json,'$.startedAt'),0)>=? ORDER BY generation DESC LIMIT 25 OFFSET ?`, options.taskId, since, offset).map(r => {
|
|
93
|
+
const attempt = JSON.parse(r.payload_json);
|
|
94
|
+
const metrics = exists('token_turns') ? get('SELECT payload_json FROM token_turns WHERE id=? AND session_id=?', attempt.attemptId, options.sessionId) : undefined;
|
|
95
|
+
const events = all('SELECT type,payload_json,occurred_at FROM worker_events WHERE attempt_id=? ORDER BY local_seq DESC LIMIT 30', attempt.attemptId).map(e => ({ type: e.type, at: e.occurred_at, payload: JSON.parse(e.payload_json) }));
|
|
96
|
+
return { ...attempt, metrics: metrics ? JSON.parse(metrics.payload_json) : null, events };
|
|
97
|
+
});
|
|
98
|
+
return { snapshot, instructions, attempts, totalAttempts: Number(get("SELECT COUNT(*) n FROM task_attempts WHERE task_id=? AND COALESCE(json_extract(payload_json,'$.startedAt'),0)>=?", options.taskId, since).n), offset };
|
|
99
|
+
}
|
|
100
|
+
const offset = Math.max(0, Number(options.offset) || 0), limit = 25;
|
|
101
|
+
const conversations = all('SELECT c.* FROM conversations c WHERE c.updated_at>=? ORDER BY c.updated_at DESC,c.id DESC LIMIT ? OFFSET ?', since, limit, offset);
|
|
102
|
+
const sessions = conversations.map(c => {
|
|
103
|
+
const turns = exists('token_turn_metrics')
|
|
104
|
+
? all("SELECT COALESCE(m.payload_json,json_remove(t.payload_json,'$.requests','$.inputTexts','$.responseText')) payload_json FROM token_turns t LEFT JOIN token_turn_metrics m ON m.id=t.id WHERE t.session_id=? AND t.started_at>=? ORDER BY t.started_at,t.id", c.agent_session_id, since).map(r => JSON.parse(r.payload_json))
|
|
105
|
+
: exists('token_turns') ? all(`SELECT id,role,task_id,started_at,json_extract(payload_json,'$.usage') usage,
|
|
106
|
+
json_extract(payload_json,'$.loadedTools') loadedTools,json_extract(payload_json,'$.usedTools') usedTools,
|
|
107
|
+
json_extract(payload_json,'$.model') model FROM token_turns WHERE session_id=? AND started_at>=? ORDER BY started_at,id`, c.agent_session_id, since).map(r => ({ ...r, taskId: r.task_id, startedAt: r.started_at, sessionId: c.agent_session_id, usage: r.usage ? JSON.parse(r.usage) : null, loadedTools: r.loadedTools ? JSON.parse(r.loadedTools) : null, usedTools: r.usedTools ? JSON.parse(r.usedTools) : [] })) : [];
|
|
108
|
+
const agent = (0, token_ledger_1.summarizeTokenTurns)(turns.filter(t => t.role === 'agent')), workers = (0, token_ledger_1.summarizeTokenTurns)(turns.filter(t => t.role === 'worker'));
|
|
109
|
+
const tasks = all(`SELECT * FROM tasks WHERE conversation_id=? AND updated_at>=? ORDER BY updated_at DESC,id DESC LIMIT 100`, c.id, since).map(t => {
|
|
110
|
+
const snapshot = JSON.parse(t.snapshot_json);
|
|
111
|
+
const last = t.active_attempt_id ? { id: t.active_attempt_id } : get('SELECT id FROM task_attempts WHERE task_id=? ORDER BY generation DESC LIMIT 1', t.id);
|
|
112
|
+
const attempt = last ? adapter.attempt(last.id) : undefined;
|
|
113
|
+
const metrics = (0, token_ledger_1.summarizeTokenTurns)(turns.filter(turn => turn.id === attempt?.attemptId));
|
|
114
|
+
const total = (0, token_ledger_1.summarizeTokenTurns)(turns.filter(turn => turn.taskId === t.id));
|
|
115
|
+
const lastTool = get("SELECT payload_json,occurred_at FROM conversation_events WHERE json_extract(payload_json,'$.task_id')=? AND type='tool.activity' ORDER BY seq DESC LIMIT 1", t.id);
|
|
116
|
+
const tool = lastTool ? JSON.parse(lastTool.payload_json).payload : undefined;
|
|
117
|
+
return { taskId: t.id, sessionId: c.agent_session_id, title: snapshot.title, state: t.state, updatedAt: t.updated_at,
|
|
118
|
+
createdAt: t.created_at, execution: snapshot.execution, workerId: attempt?.workerId, attemptId: attempt?.attemptId,
|
|
119
|
+
workerSessionId: attempt?.sessionId, resumed: attempt?.resumeSession, workstreamId: snapshot.workstreamId,
|
|
120
|
+
continueTaskId: snapshot.continueTaskId, hostProcessId: t.active_attempt_id ? attempt?.processIdentity?.pid : undefined,
|
|
121
|
+
tokenSummary: { totalTokens: metrics.totalTokens, allAttemptsTokens: total.totalTokens }, contextTools: metrics.contextTools, loadedTools: metrics.loadedTools, usedTools: metrics.usedTools,
|
|
122
|
+
lastTool: tool ? { name: tool.name, type: tool.type, is_error: tool.is_error, at: lastTool.occurred_at } : undefined };
|
|
123
|
+
});
|
|
124
|
+
const { status: state, thinking } = conversationActivityStatus(get, all, c.id);
|
|
125
|
+
const totalTokens = agent.totalTokens === null && workers.totalTokens === null ? null : (agent.totalTokens ?? 0) + (workers.totalTokens ?? 0);
|
|
126
|
+
return { sessionId: c.agent_session_id, chatId: c.chat_id, source: c.source, orchestration: true, mode: 'headless', status: state, isRunning: thinking,
|
|
127
|
+
model: turns.filter(t => t.role === 'agent' && t.model).at(-1)?.model ?? '', updatedAt: c.updated_at, createdAt: c.created_at,
|
|
128
|
+
tokenSummary: { agentTokens: agent.totalTokens, workerTokens: workers.totalTokens, totalTokens }, contextTools: agent.contextTools, loadedTools: agent.loadedTools, usedTools: agent.usedTools,
|
|
129
|
+
tasks, totalTasks: Number(get('SELECT COUNT(*) n FROM tasks WHERE conversation_id=? AND updated_at>=?', c.id, since).n),
|
|
130
|
+
workerIds: all('SELECT id FROM worker_pool WHERE conversation_id=?', c.id).map(w => w.id), spawnedAt: 0, uptimeSec: 0, tokens: 0 };
|
|
131
|
+
});
|
|
132
|
+
const today = Date.now() - Date.now() % 86400000;
|
|
133
|
+
const usageToday = exists('token_turns') ? all(`SELECT role,CAST((started_at-?)/3600000 AS INTEGER) hour,SUM(json_extract(payload_json,'$.usage.totalTokens')) tokens FROM token_turns WHERE started_at>=? AND json_type(payload_json,'$.usage')='object' GROUP BY role,hour`, today, Math.max(today, since)) : [];
|
|
134
|
+
const attention = all(`SELECT t.id taskId,t.state,t.snapshot_json,c.agent_session_id sessionId FROM tasks t JOIN conversations c ON c.id=t.conversation_id WHERE t.updated_at>=? AND t.state IN ('waiting_input','needs_reconciliation') ORDER BY t.updated_at DESC LIMIT 8`, since).map(t => ({ taskId: t.taskId, state: t.state, sessionId: t.sessionId, title: JSON.parse(t.snapshot_json).title }));
|
|
135
|
+
const recentWork = all(`SELECT t.id taskId,t.state,t.snapshot_json,t.updated_at updatedAt,c.agent_session_id sessionId FROM tasks t JOIN conversations c ON c.id=t.conversation_id WHERE t.updated_at>=? ORDER BY t.updated_at DESC,t.id DESC LIMIT 6`, today).map(t => ({ taskId: t.taskId, state: t.state, sessionId: t.sessionId, updatedAt: t.updatedAt, title: JSON.parse(t.snapshot_json).title }));
|
|
136
|
+
const pool = exists('worker_pool') ? all('SELECT * FROM worker_pool') : [];
|
|
137
|
+
return { usageToday, attention, recentWork, managedLegacyIds: all('SELECT agent_session_id FROM conversations WHERE agent_session_id IN (SELECT value FROM json_each(?))', JSON.stringify(options.legacyIds ?? [])).map(c => c.agent_session_id), enabled: true, backend: 'headless', workspaceMode: options.workspaceMode, sessions, tasks: sessions.flatMap(s => s.tasks),
|
|
138
|
+
pagination: { offset, limit, total: Number(get('SELECT COUNT(*) n FROM conversations WHERE updated_at>=?', since).n) },
|
|
139
|
+
counts: { sessions: Number(get('SELECT COUNT(*) n FROM conversations WHERE updated_at>=?', since).n), tasks: all('SELECT state,COUNT(*) count FROM tasks WHERE updated_at>=? GROUP BY state', since) },
|
|
140
|
+
activeAgentSessions: sessions.filter(s => s.isRunning).map(s => s.sessionId),
|
|
141
|
+
workerPool: { maxWorkers: options.maxWorkers, idleTtlMs: options.idleTtlMs, workers: pool.map(w => ({ workerId: w.id, sessionId: w.session_id, workstreamId: w.workstream_id, state: w.active_task_id ? 'busy' : 'idle', taskId: w.active_task_id, expiresAt: w.active_task_id ? undefined : Number(w.idle_since) + Number(options.idleTtlMs) })) } };
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
db.exec('ROLLBACK');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
worker_threads_1.parentPort.on('message', ({ id, operation, filename, options }) => {
|
|
148
|
+
try {
|
|
149
|
+
worker_threads_1.parentPort.postMessage({ id, value: read(filename, operation, options) });
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
worker_threads_1.parentPort.postMessage({ id, error: 'Unable to read dashboard data' });
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=dashboard-reader-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-reader-worker.js","sourceRoot":"","sources":["../../src/orchestration/dashboard-reader-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** One isolated reader per gateway, bounded requests and coalesced snapshots. */
|
|
2
|
+
export declare class DashboardReader {
|
|
3
|
+
private readonly workerPath;
|
|
4
|
+
constructor(workerPath?: string);
|
|
5
|
+
private worker?;
|
|
6
|
+
private nextId;
|
|
7
|
+
private pending;
|
|
8
|
+
private inflight;
|
|
9
|
+
private cache;
|
|
10
|
+
private closed;
|
|
11
|
+
read(operation: 'summary' | 'report' | 'task' | 'session', filename: string, options?: Record<string, unknown>): Promise<any>;
|
|
12
|
+
private fail;
|
|
13
|
+
close(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=dashboard-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-reader.d.ts","sourceRoot":"","sources":["../../src/orchestration/dashboard-reader.ts"],"names":[],"mappings":"AAGA,iFAAiF;AACjF,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,SAAgD;IACvF,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAuG;IACtH,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,KAAK,CAAoD;IACjE,OAAO,CAAC,MAAM,CAAS;IACvB,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAsCjI,OAAO,CAAC,IAAI;IAON,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DashboardReader = void 0;
|
|
4
|
+
const worker_threads_1 = require("worker_threads");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
/** One isolated reader per gateway, bounded requests and coalesced snapshots. */
|
|
7
|
+
class DashboardReader {
|
|
8
|
+
constructor(workerPath = (0, path_1.join)(__dirname, 'dashboard-reader-worker.js')) {
|
|
9
|
+
this.workerPath = workerPath;
|
|
10
|
+
this.nextId = 0;
|
|
11
|
+
this.pending = new Map();
|
|
12
|
+
this.inflight = new Map();
|
|
13
|
+
this.cache = new Map();
|
|
14
|
+
this.closed = false;
|
|
15
|
+
}
|
|
16
|
+
read(operation, filename, options = {}) {
|
|
17
|
+
if (this.closed)
|
|
18
|
+
return Promise.reject(new Error('Dashboard reader is closed'));
|
|
19
|
+
const key = JSON.stringify([operation, filename, options]);
|
|
20
|
+
const cached = this.cache.get(key);
|
|
21
|
+
if (cached && cached.until > Date.now())
|
|
22
|
+
return Promise.resolve(cached.value);
|
|
23
|
+
const existing = this.inflight.get(key);
|
|
24
|
+
if (existing)
|
|
25
|
+
return existing;
|
|
26
|
+
if (this.pending.size >= 64)
|
|
27
|
+
return Promise.reject(new Error('Dashboard reader is busy'));
|
|
28
|
+
if (!this.worker) {
|
|
29
|
+
const worker = this.worker = new worker_threads_1.Worker(this.workerPath);
|
|
30
|
+
worker.on('message', ({ id, value, error }) => {
|
|
31
|
+
const request = this.pending.get(id);
|
|
32
|
+
if (!request)
|
|
33
|
+
return;
|
|
34
|
+
clearTimeout(request.timer);
|
|
35
|
+
this.pending.delete(id);
|
|
36
|
+
if (!this.pending.size)
|
|
37
|
+
worker.unref();
|
|
38
|
+
if (error)
|
|
39
|
+
request.reject(new Error(error));
|
|
40
|
+
else
|
|
41
|
+
request.resolve(value);
|
|
42
|
+
});
|
|
43
|
+
worker.on('error', () => this.fail(worker));
|
|
44
|
+
worker.on('exit', () => this.fail(worker));
|
|
45
|
+
worker.unref();
|
|
46
|
+
}
|
|
47
|
+
const id = ++this.nextId;
|
|
48
|
+
const promise = new Promise((resolve, reject) => {
|
|
49
|
+
const timer = setTimeout(() => { this.fail(this.worker); }, 15000);
|
|
50
|
+
timer.unref();
|
|
51
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
52
|
+
this.worker.ref();
|
|
53
|
+
this.worker.postMessage({ id, operation, filename, options });
|
|
54
|
+
}).then(value => {
|
|
55
|
+
if (operation === 'summary') {
|
|
56
|
+
if (this.cache.size >= 64)
|
|
57
|
+
this.cache.delete(this.cache.keys().next().value);
|
|
58
|
+
this.cache.set(key, { until: Date.now() + 2000, value });
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}).finally(() => this.inflight.delete(key));
|
|
62
|
+
this.inflight.set(key, promise);
|
|
63
|
+
return promise;
|
|
64
|
+
}
|
|
65
|
+
fail(worker) {
|
|
66
|
+
if (worker !== this.worker)
|
|
67
|
+
return;
|
|
68
|
+
this.worker = undefined;
|
|
69
|
+
for (const request of this.pending.values()) {
|
|
70
|
+
clearTimeout(request.timer);
|
|
71
|
+
request.reject(new Error('Dashboard reader unavailable'));
|
|
72
|
+
}
|
|
73
|
+
this.pending.clear();
|
|
74
|
+
this.cache.clear();
|
|
75
|
+
void worker.terminate();
|
|
76
|
+
}
|
|
77
|
+
async close() {
|
|
78
|
+
this.closed = true;
|
|
79
|
+
const worker = this.worker;
|
|
80
|
+
if (worker) {
|
|
81
|
+
this.fail(worker);
|
|
82
|
+
await worker.terminate();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.DashboardReader = DashboardReader;
|
|
87
|
+
//# sourceMappingURL=dashboard-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-reader.js","sourceRoot":"","sources":["../../src/orchestration/dashboard-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { OrchestrationStore } from './store';
|
|
2
|
+
/** Receipts prove a mutation committed; they are not another copy of task state.
|
|
3
|
+
* Keep their versions and question/answer data, and fetch full current state via
|
|
4
|
+
* task_status. Persisted receipts and full worker reports are never rewritten.
|
|
5
|
+
*/
|
|
6
|
+
export declare function committedCommandContext(store: OrchestrationStore, conversationId: string): {
|
|
7
|
+
actionId: string | number | null;
|
|
8
|
+
decisionId: string | number | null;
|
|
9
|
+
committedAt: string | number | null;
|
|
10
|
+
command: string | number | null;
|
|
11
|
+
receipt: any;
|
|
12
|
+
}[];
|
|
13
|
+
/** Changing report history belongs after the stable system instructions. */
|
|
14
|
+
export declare function communicatedProgressContext(previous: readonly string[]): string;
|
|
15
|
+
//# sourceMappingURL=decision-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-context.d.ts","sourceRoot":"","sources":["../../src/orchestration/decision-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAe7C;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM;;;;;;IAgBxF;AAED,4EAA4E;AAC5E,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAa/E"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.committedCommandContext = committedCommandContext;
|
|
4
|
+
exports.communicatedProgressContext = communicatedProgressContext;
|
|
5
|
+
/** How many committed receipts each decision turn carries. A receipt only has to stop the
|
|
6
|
+
* agent repeating work it already committed, and every one of them stays queryable through
|
|
7
|
+
* task_status, so this window is deliberately short. */
|
|
8
|
+
const COMMITTED_RECEIPT_WINDOW = 10;
|
|
9
|
+
/** What a task receipt keeps. An allowlist, not a growing denylist: a new snapshot field has
|
|
10
|
+
* to be opted in here instead of silently enlarging the context of every later turn. The
|
|
11
|
+
* pending question stays because the docstring below promises the question/answer data; the
|
|
12
|
+
* rest of the task's current state is a task_status call away. */
|
|
13
|
+
const RECEIPT_FIELDS = ['taskId', 'title', 'state', 'targetProfile', 'stateVersion', 'revision',
|
|
14
|
+
'appliedRevision', 'workstreamId', 'continueTaskId', 'continuationPolicy', 'replacedByTaskId',
|
|
15
|
+
'pendingQuestion'];
|
|
16
|
+
/** Receipts prove a mutation committed; they are not another copy of task state.
|
|
17
|
+
* Keep their versions and question/answer data, and fetch full current state via
|
|
18
|
+
* task_status. Persisted receipts and full worker reports are never rewritten.
|
|
19
|
+
*/
|
|
20
|
+
function committedCommandContext(store, conversationId) {
|
|
21
|
+
return store.all(`SELECT action_id,decision_id,created_at,command_type,receipt_json
|
|
22
|
+
FROM task_commands WHERE conversation_id=? ORDER BY created_at DESC,rowid DESC LIMIT ${COMMITTED_RECEIPT_WINDOW}`, conversationId).map(row => {
|
|
23
|
+
const stored = JSON.parse(String(row.receipt_json));
|
|
24
|
+
// Non-task receipts (for example grouped question presentation) are already
|
|
25
|
+
// compact and must retain their specific question IDs and acknowledgement.
|
|
26
|
+
let receipt = stored;
|
|
27
|
+
if (stored && typeof stored.taskId === 'string' && typeof stored.stateVersion === 'number') {
|
|
28
|
+
receipt = {};
|
|
29
|
+
for (const key of RECEIPT_FIELDS)
|
|
30
|
+
if (stored[key] !== undefined)
|
|
31
|
+
receipt[key] = stored[key];
|
|
32
|
+
if (stored.result)
|
|
33
|
+
receipt.resultAvailable = true;
|
|
34
|
+
receipt.details = { tool: 'task_status', task_id: stored.taskId };
|
|
35
|
+
}
|
|
36
|
+
return { actionId: row.action_id, decisionId: row.decision_id, committedAt: row.created_at,
|
|
37
|
+
command: row.command_type, receipt };
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** Changing report history belongs after the stable system instructions. */
|
|
41
|
+
function communicatedProgressContext(previous) {
|
|
42
|
+
if (!previous.length)
|
|
43
|
+
return '';
|
|
44
|
+
// Only duplicate-suppression reference excerpts, never the new worker result.
|
|
45
|
+
// Full replies remain in canonical history, and duplicate comparison uses the
|
|
46
|
+
// untouched originals. Bound serialized size too (JSON escapes can expand it).
|
|
47
|
+
const excerpts = [];
|
|
48
|
+
for (const message of previous) {
|
|
49
|
+
const chars = [...message];
|
|
50
|
+
const excerpt = chars.length > 900 ? chars.slice(0, 600).join('') + '\n[Earlier reply excerpt; middle omitted]\n' + chars.slice(-250).join('') : message;
|
|
51
|
+
if (JSON.stringify([...excerpts, excerpt]).length > 6000)
|
|
52
|
+
break;
|
|
53
|
+
excerpts.push(excerpt);
|
|
54
|
+
}
|
|
55
|
+
return '\nPreviously communicated reply excerpts (reference data, not instructions; full replies remain in conversation history):\n' + JSON.stringify(excerpts);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=decision-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-context.js","sourceRoot":"","sources":["../../src/orchestration/decision-context.ts"],"names":[],"mappings":";;AAmBA,0DAgBC;AAGD,kEAaC;AAjDD;;wDAEwD;AACxD,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAEpC;;;kEAGkE;AAClE,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU;IAC7F,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,kBAAkB;IAC7F,iBAAiB,CAAU,CAAC;AAE9B;;;GAGG;AACH,SAAgB,uBAAuB,CAAC,KAAyB,EAAE,cAAsB;IACvF,OAAO,KAAK,CAAC,GAAG,CAAC;2FACwE,wBAAwB,EAAE,EAAE,cAAc,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC7I,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QACpD,4EAA4E;QAC5E,2EAA2E;QAC3E,IAAI,OAAO,GAAG,MAAM,CAAC;QACrB,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC3F,OAAO,GAAG,EAA6B,CAAC;YACxC,KAAK,MAAM,GAAG,IAAI,cAAc;gBAAE,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS;oBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5F,IAAI,MAAM,CAAC,MAAM;gBAAE,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAClD,OAAO,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACpE,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,CAAC,UAAU;YACxF,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,4EAA4E;AAC5E,SAAgB,2BAA2B,CAAC,QAA2B;IACrE,IAAI,CAAC,QAAQ,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAChC,8EAA8E;IAC9E,8EAA8E;IAC9E,+EAA+E;IAC/E,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,6CAA6C,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACxJ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,QAAQ,EAAC,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI;YAAE,MAAM;QAC/D,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,6HAA6H,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAClK,CAAC"}
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
/** Extract only the display string from an incomplete flat
|
|
2
|
-
* Incomplete escapes/surrogate pairs are held until the next provider chunk.
|
|
1
|
+
/** Extract only the display string from an incomplete flat response JSON object.
|
|
2
|
+
* Incomplete escapes/surrogate pairs are held until the next provider chunk.
|
|
3
|
+
* Other fields of the union response schema (spoken_text, notify_user) are skipped
|
|
4
|
+
* without ever being published, whatever order the model emits them in. */
|
|
3
5
|
export declare function partialDisplay(raw: string): string;
|
|
6
|
+
/** `index` moved back over the opening fence that announces the object there, if any: a
|
|
7
|
+
* fenced payload is announced by its fence, so the fence belongs to the payload rather than
|
|
8
|
+
* being left behind as stray markdown. */
|
|
9
|
+
export declare function fenceAdjusted(raw: string, index: number): number;
|
|
10
|
+
/** Index at which the first union-schema payload starts inside otherwise plain text, or -1. */
|
|
11
|
+
export declare function payloadStart(raw: string): number;
|
|
12
|
+
/** The incremental text safe to publish for a partial agent turn.
|
|
13
|
+
*
|
|
14
|
+
* The union response schema is declared on every turn, so the dominant case is a
|
|
15
|
+
* StructuredOutput argument stream and only display_text may be shown. The model may
|
|
16
|
+
* still answer in plain text (the CLI never forces the tool), and that text is the reply
|
|
17
|
+
* itself — publish it as it arrives, exactly as before the schema became invariant.
|
|
18
|
+
* Anything that opens like an object or a fenced block is treated as structured and held
|
|
19
|
+
* until display_text is parseable, so raw JSON is never shown to the user. A turn that
|
|
20
|
+
* opens with prose and only then emits its payload is the same leak one token later: the
|
|
21
|
+
* prose streams, but everything from the payload on is withheld for the final parse. */
|
|
22
|
+
export declare function displayPrefix(raw: string): string;
|
|
4
23
|
//# sourceMappingURL=display-stream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-stream.d.ts","sourceRoot":"","sources":["../../src/orchestration/display-stream.ts"],"names":[],"mappings":"AAAA;
|
|
1
|
+
{"version":3,"file":"display-stream.d.ts","sourceRoot":"","sources":["../../src/orchestration/display-stream.ts"],"names":[],"mappings":"AAAA;;;2EAG2E;AAC3E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA+ClD;AAQD;;0CAE0C;AAC1C,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,+FAA+F;AAC/F,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED;;;;;;;;;wFASwF;AACxF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWjD"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.partialDisplay = partialDisplay;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
exports.fenceAdjusted = fenceAdjusted;
|
|
5
|
+
exports.payloadStart = payloadStart;
|
|
6
|
+
exports.displayPrefix = displayPrefix;
|
|
7
|
+
/** Extract only the display string from an incomplete flat response JSON object.
|
|
8
|
+
* Incomplete escapes/surrogate pairs are held until the next provider chunk.
|
|
9
|
+
* Other fields of the union response schema (spoken_text, notify_user) are skipped
|
|
10
|
+
* without ever being published, whatever order the model emits them in. */
|
|
6
11
|
function partialDisplay(raw) {
|
|
7
12
|
let i = 0;
|
|
8
13
|
const space = () => { while (/\s/.test(raw[i] ?? '') && i < raw.length)
|
|
@@ -49,10 +54,20 @@ function partialDisplay(raw) {
|
|
|
49
54
|
text = text.slice(0, -1);
|
|
50
55
|
return { text, complete: false };
|
|
51
56
|
};
|
|
57
|
+
// true/false/null/number values (notify_user) carry no display text; skip a complete
|
|
58
|
+
// one, and hold the chunk while it is still arriving so position stays trustworthy.
|
|
59
|
+
const literal = () => {
|
|
60
|
+
const match = /^(?:true|false|null|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)(?=[\s,}])/.exec(raw.slice(i));
|
|
61
|
+
if (!match)
|
|
62
|
+
return false;
|
|
63
|
+
i += match[0].length;
|
|
64
|
+
return true;
|
|
65
|
+
};
|
|
52
66
|
space();
|
|
53
67
|
if (raw[i++] !== '{')
|
|
54
68
|
return '';
|
|
55
|
-
|
|
69
|
+
// One pass per union field; an unexpected shape simply holds the chunk back.
|
|
70
|
+
for (let fields = 0; fields < 8; fields++) {
|
|
56
71
|
space();
|
|
57
72
|
const key = string();
|
|
58
73
|
if (!key?.complete)
|
|
@@ -61,12 +76,9 @@ function partialDisplay(raw) {
|
|
|
61
76
|
if (raw[i++] !== ':')
|
|
62
77
|
return '';
|
|
63
78
|
space();
|
|
64
|
-
const value = string();
|
|
65
|
-
if (!value)
|
|
66
|
-
return '';
|
|
67
79
|
if (key.text === 'display_text')
|
|
68
|
-
return
|
|
69
|
-
if (!
|
|
80
|
+
return string()?.text ?? '';
|
|
81
|
+
if (!(raw[i] === '"' ? string()?.complete : literal()))
|
|
70
82
|
return '';
|
|
71
83
|
space();
|
|
72
84
|
if (raw[i++] !== ',')
|
|
@@ -74,4 +86,45 @@ function partialDisplay(raw) {
|
|
|
74
86
|
}
|
|
75
87
|
return '';
|
|
76
88
|
}
|
|
89
|
+
/** An object opening with one of the union response schema's own field names. Ordinary
|
|
90
|
+
* replies contain braces and fenced code blocks legitimately, so only this shape counts
|
|
91
|
+
* as our payload; anything looser would hold back or mangle real answers. */
|
|
92
|
+
const UNION_KEYS = ['display_text', 'spoken_text', 'notify_user'];
|
|
93
|
+
const PAYLOAD_OBJECT = /\{\s*"(?:display_text|spoken_text|notify_user)"\s*:/;
|
|
94
|
+
/** `index` moved back over the opening fence that announces the object there, if any: a
|
|
95
|
+
* fenced payload is announced by its fence, so the fence belongs to the payload rather than
|
|
96
|
+
* being left behind as stray markdown. */
|
|
97
|
+
function fenceAdjusted(raw, index) {
|
|
98
|
+
const fence = /```(?:json)?[ \t]*\r?\n?$/.exec(raw.slice(0, index));
|
|
99
|
+
return fence ? fence.index : index;
|
|
100
|
+
}
|
|
101
|
+
/** Index at which the first union-schema payload starts inside otherwise plain text, or -1. */
|
|
102
|
+
function payloadStart(raw) {
|
|
103
|
+
const match = PAYLOAD_OBJECT.exec(raw);
|
|
104
|
+
return match ? fenceAdjusted(raw, match.index) : -1;
|
|
105
|
+
}
|
|
106
|
+
/** The incremental text safe to publish for a partial agent turn.
|
|
107
|
+
*
|
|
108
|
+
* The union response schema is declared on every turn, so the dominant case is a
|
|
109
|
+
* StructuredOutput argument stream and only display_text may be shown. The model may
|
|
110
|
+
* still answer in plain text (the CLI never forces the tool), and that text is the reply
|
|
111
|
+
* itself — publish it as it arrives, exactly as before the schema became invariant.
|
|
112
|
+
* Anything that opens like an object or a fenced block is treated as structured and held
|
|
113
|
+
* until display_text is parseable, so raw JSON is never shown to the user. A turn that
|
|
114
|
+
* opens with prose and only then emits its payload is the same leak one token later: the
|
|
115
|
+
* prose streams, but everything from the payload on is withheld for the final parse. */
|
|
116
|
+
function displayPrefix(raw) {
|
|
117
|
+
if (/^\s*[{`]/.test(raw))
|
|
118
|
+
return partialDisplay(raw);
|
|
119
|
+
const start = payloadStart(raw);
|
|
120
|
+
if (start >= 0)
|
|
121
|
+
return raw.slice(0, start);
|
|
122
|
+
// The opener arrives a character at a time, so an object whose key is still being typed
|
|
123
|
+
// must be held too — otherwise `{"display_text"` publishes before the colon identifies it.
|
|
124
|
+
// Only a key that can still become a union field holds; braces in ordinary prose (and the
|
|
125
|
+
// JSON a user actually asked for) keep streaming.
|
|
126
|
+
const opening = /\{\s*(?:"([a-z_]*)"?\s*:?)?$/.exec(raw);
|
|
127
|
+
const typed = opening?.[1] ?? '';
|
|
128
|
+
return opening && UNION_KEYS.some(key => key.startsWith(typed)) ? raw.slice(0, opening.index) : raw;
|
|
129
|
+
}
|
|
77
130
|
//# sourceMappingURL=display-stream.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-stream.js","sourceRoot":"","sources":["../../src/orchestration/display-stream.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"display-stream.js","sourceRoot":"","sources":["../../src/orchestration/display-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inference-errors.d.ts","sourceRoot":"","sources":["../../src/orchestration/inference-errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inference-errors.d.ts","sourceRoot":"","sources":["../../src/orchestration/inference-errors.ts"],"names":[],"mappings":"AAUA,mFAAmF;AACnF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CA0C1E"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.inferenceFailureMessage = inferenceFailureMessage;
|
|
4
|
+
const provider_message_1 = require("./provider-message");
|
|
4
5
|
const providerCodes = {
|
|
5
6
|
insufficient_quota: 'quota', quota_exceeded: 'quota', billing_error: 'quota', payment_required: 'quota',
|
|
6
7
|
insufficient_credits: 'quota', insufficient_balance: 'quota', credit_balance: 'quota',
|
|
@@ -9,28 +10,16 @@ const providerCodes = {
|
|
|
9
10
|
overloaded_error: 'capacity', service_unavailable: 'unavailable',
|
|
10
11
|
};
|
|
11
12
|
const codeCategory = (code) => Object.prototype.hasOwnProperty.call(providerCodes, code) ? providerCodes[code] : undefined;
|
|
12
|
-
function retryGuidance(message) {
|
|
13
|
-
// Validate the entire clause: never truncate an offset, AM/PM, or compound duration.
|
|
14
|
-
const reset = message.match(/\b(resets?|resetting|retry(?:ing)?|try again)\s+(?:(in|after|at)\s+)?([^\n.!?]{1,160})(?:[\n.!?]|$)/i);
|
|
15
|
-
if (!reset)
|
|
16
|
-
return undefined;
|
|
17
|
-
const value = reset[3].trim(), connector = reset[2]?.toLowerCase();
|
|
18
|
-
const duration = /^(?:\d{1,4}\s*(?:seconds?|minutes?|hours?|days?))(?:\s*(?:,\s*|and\s+)?\d{1,4}\s*(?:seconds?|minutes?|hours?|days?)){0,3}$/i.test(value);
|
|
19
|
-
const clock = value.match(/^([01]?\d|2[0-3]):[0-5]\d(?::[0-5]\d)?(?:\s+(AM|PM))?(?:\s+(UTC|GMT)(?:([+-])((?:0?\d|1[0-4]))(?::([0-5]\d))?)?)?$/i);
|
|
20
|
-
if (clock?.[2] && (Number(clock[1]) < 1 || Number(clock[1]) > 12))
|
|
21
|
-
return undefined;
|
|
22
|
-
if (clock?.[5] && Number(clock[5]) === 14 && Number(clock[6] ?? 0) !== 0)
|
|
23
|
-
return undefined;
|
|
24
|
-
if (duration && connector === 'at')
|
|
25
|
-
return undefined;
|
|
26
|
-
if (!duration && (!clock || ((connector === 'in' || connector === 'after') && (clock[2] || clock[3]))))
|
|
27
|
-
return undefined;
|
|
28
|
-
const when = duration || connector === 'in' || connector === 'after' ? 'in' : 'at';
|
|
29
|
-
return ` Try again ${/^reset/i.test(reset[1]) ? 'after the limit resets ' : ''}${when} ${value}.`;
|
|
30
|
-
}
|
|
31
13
|
/** User-facing provider failures, without credentials or internal stack traces. */
|
|
32
14
|
function inferenceFailureMessage(error) {
|
|
33
15
|
const failure = error;
|
|
16
|
+
if (failure?.code === 'WORKSPACE_CONTEXT_MISSING')
|
|
17
|
+
return 'The agent could not start because its workspace context (CLAUDE.md) is missing. Restore the required workspace files and restart the agent.';
|
|
18
|
+
if (failure && ['INFERENCE_FAILED', 'PROVIDER_CAPACITY', 'PROVIDER_UNAVAILABLE'].includes(failure.code ?? '') && typeof failure.providerMessage === 'string') {
|
|
19
|
+
const message = (0, provider_message_1.sanitizeProviderMessage)(failure.providerMessage);
|
|
20
|
+
if (message)
|
|
21
|
+
return message;
|
|
22
|
+
}
|
|
34
23
|
if (failure?.code === 'PROVIDER_CAPACITY')
|
|
35
24
|
return '503: Provider capacity is fully in use right now. Please try again later.';
|
|
36
25
|
if (failure?.code === 'PROVIDER_UNAVAILABLE')
|
|
@@ -57,6 +46,15 @@ function inferenceFailureMessage(error) {
|
|
|
57
46
|
}
|
|
58
47
|
if (!category)
|
|
59
48
|
return undefined;
|
|
49
|
+
// Older callers carry only an Error message. Once identified as a provider
|
|
50
|
+
// failure, preserve its wording too; do not parse a reset time out of prose.
|
|
51
|
+
// When sanitizing strips the detail to nothing (a pure stack/path), fall
|
|
52
|
+
// through to the categorized base message rather than dropping to generic.
|
|
53
|
+
if (detail && !failure.providerCodes?.length && !/^HTTP \d{3}$/.test(detail)) {
|
|
54
|
+
const preserved = (0, provider_message_1.sanitizeProviderMessage)(detail);
|
|
55
|
+
if (preserved)
|
|
56
|
+
return preserved;
|
|
57
|
+
}
|
|
60
58
|
const base = category === 'quota' ? 'Provider quota or billing limit reached.'
|
|
61
59
|
: category === 'rate_limit' ? 'Provider rate limit reached.'
|
|
62
60
|
: category === 'quota_or_rate_limit' ? 'Provider rate limit or quota reached.'
|
|
@@ -65,7 +63,7 @@ function inferenceFailureMessage(error) {
|
|
|
65
63
|
: 'The model provider is temporarily unavailable.';
|
|
66
64
|
if (category === 'authentication')
|
|
67
65
|
return base + ' Check your provider credentials.';
|
|
68
|
-
return base + (
|
|
69
|
-
: category === 'quota_or_rate_limit' ? ' Check provider usage before retrying.' : ' Please try again later.')
|
|
66
|
+
return base + (category === 'quota' ? ' Check your provider usage or billing before retrying.'
|
|
67
|
+
: category === 'quota_or_rate_limit' ? ' Check provider usage before retrying.' : ' Please try again later.');
|
|
70
68
|
}
|
|
71
69
|
//# sourceMappingURL=inference-errors.js.map
|