hoomanjs 1.59.0 → 1.60.0
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 +2 -1
- package/dist/chat/components/StatusBar.js +1 -25
- package/dist/chat/components/StatusBar.js.map +1 -1
- package/dist/cli.js +68 -3
- package/dist/cli.js.map +1 -1
- package/dist/core/skills/built-in/hooman-channels/SKILL.md +6 -6
- package/dist/core/utils/usage-format.d.ts +4 -0
- package/dist/core/utils/usage-format.js +27 -0
- package/dist/core/utils/usage-format.js.map +1 -0
- package/dist/daemon/acp-client.d.ts +4 -0
- package/dist/daemon/acp-client.js +2 -0
- package/dist/daemon/acp-client.js.map +1 -1
- package/dist/daemon/dashboard/store.d.ts +36 -0
- package/dist/daemon/dashboard/store.js +290 -0
- package/dist/daemon/dashboard/store.js.map +1 -0
- package/dist/daemon/dashboard/types.d.ts +60 -0
- package/dist/daemon/dashboard/types.js +2 -0
- package/dist/daemon/dashboard/types.js.map +1 -0
- package/dist/daemon/index.d.ts +3 -0
- package/dist/daemon/index.js +23 -7
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/queue.js +9 -0
- package/dist/daemon/queue.js.map +1 -1
- package/dist/daemon/session-registry.d.ts +47 -1
- package/dist/daemon/session-registry.js +87 -13
- package/dist/daemon/session-registry.js.map +1 -1
- package/dist/daemon/ui/Card.d.ts +8 -0
- package/dist/daemon/ui/Card.js +52 -0
- package/dist/daemon/ui/Card.js.map +1 -0
- package/dist/daemon/ui/DaemonDashboardApp.d.ts +6 -0
- package/dist/daemon/ui/DaemonDashboardApp.js +75 -0
- package/dist/daemon/ui/DaemonDashboardApp.js.map +1 -0
- package/dist/daemon/ui/Footer.d.ts +3 -0
- package/dist/daemon/ui/Footer.js +7 -0
- package/dist/daemon/ui/Footer.js.map +1 -0
- package/dist/daemon/ui/Header.d.ts +4 -0
- package/dist/daemon/ui/Header.js +22 -0
- package/dist/daemon/ui/Header.js.map +1 -0
- package/dist/daemon/ui/Lane.d.ts +11 -0
- package/dist/daemon/ui/Lane.js +10 -0
- package/dist/daemon/ui/Lane.js.map +1 -0
- package/dist/daemon/ui/format.d.ts +7 -0
- package/dist/daemon/ui/format.js +67 -0
- package/dist/daemon/ui/format.js.map +1 -0
- package/dist/daemon/ui/index.d.ts +11 -0
- package/dist/daemon/ui/index.js +14 -0
- package/dist/daemon/ui/index.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
const MAX_DISPOSED = 10;
|
|
2
|
+
const MAX_DIAGNOSTICS = 300;
|
|
3
|
+
const MAX_PREVIEW_LINES = 2;
|
|
4
|
+
const MAX_PREVIEW_CHARS = 220;
|
|
5
|
+
const NOTIFY_THROTTLE_MS = 90;
|
|
6
|
+
function truncatePreview(text) {
|
|
7
|
+
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
8
|
+
if (collapsed.length <= MAX_PREVIEW_CHARS) {
|
|
9
|
+
return collapsed;
|
|
10
|
+
}
|
|
11
|
+
return `${collapsed.slice(0, MAX_PREVIEW_CHARS - 1)}\u2026`;
|
|
12
|
+
}
|
|
13
|
+
/** Keeps only the last `MAX_PREVIEW_LINES` worth of a growing stream preview. */
|
|
14
|
+
function appendStreamText(previous, delta) {
|
|
15
|
+
const combined = `${previous ?? ""}${delta}`;
|
|
16
|
+
const lines = combined.split("\n");
|
|
17
|
+
const tail = lines.slice(-MAX_PREVIEW_LINES).join("\n");
|
|
18
|
+
return truncatePreview(tail);
|
|
19
|
+
}
|
|
20
|
+
function textFromContent(content) {
|
|
21
|
+
return content.type === "text" ? content.text : null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Owns every card the daemon dashboard renders. Fed exclusively through
|
|
25
|
+
* explicit `on*` calls from daemon orchestration, the session registry, the
|
|
26
|
+
* ACP child, and parsed `session/update` notifications — it has no direct
|
|
27
|
+
* dependency on Ink so it can be tested or reused headlessly.
|
|
28
|
+
*/
|
|
29
|
+
export class DaemonDashboardStore {
|
|
30
|
+
#startedAt = Date.now();
|
|
31
|
+
#channels = [];
|
|
32
|
+
#mcpServerCount = 0;
|
|
33
|
+
#acpChildState = "starting";
|
|
34
|
+
#poolMax = 1;
|
|
35
|
+
#draining = false;
|
|
36
|
+
#cards = new Map();
|
|
37
|
+
#disposed = [];
|
|
38
|
+
#diagnostics = [];
|
|
39
|
+
#poolStats = { active: 0, max: 1, waiting: 0 };
|
|
40
|
+
#listeners = new Set();
|
|
41
|
+
#notifyTimer = null;
|
|
42
|
+
subscribe(listener) {
|
|
43
|
+
this.#listeners.add(listener);
|
|
44
|
+
return () => this.#listeners.delete(listener);
|
|
45
|
+
}
|
|
46
|
+
#notify() {
|
|
47
|
+
if (this.#notifyTimer) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.#notifyTimer = setTimeout(() => {
|
|
51
|
+
this.#notifyTimer = null;
|
|
52
|
+
for (const listener of this.#listeners) {
|
|
53
|
+
listener();
|
|
54
|
+
}
|
|
55
|
+
}, NOTIFY_THROTTLE_MS);
|
|
56
|
+
this.#notifyTimer.unref?.();
|
|
57
|
+
}
|
|
58
|
+
#card(externalKey) {
|
|
59
|
+
const existing = this.#cards.get(externalKey);
|
|
60
|
+
if (existing) {
|
|
61
|
+
return existing;
|
|
62
|
+
}
|
|
63
|
+
const now = Date.now();
|
|
64
|
+
const created = {
|
|
65
|
+
externalKey,
|
|
66
|
+
origin: null,
|
|
67
|
+
status: "in_progress",
|
|
68
|
+
phase: "queued",
|
|
69
|
+
queueDepth: 1,
|
|
70
|
+
createdAt: now,
|
|
71
|
+
lastActiveAt: now,
|
|
72
|
+
usage: { inputTokens: 0, outputTokens: 0 },
|
|
73
|
+
};
|
|
74
|
+
this.#cards.set(externalKey, created);
|
|
75
|
+
return created;
|
|
76
|
+
}
|
|
77
|
+
setChannels(channels) {
|
|
78
|
+
this.#channels = channels;
|
|
79
|
+
this.#notify();
|
|
80
|
+
}
|
|
81
|
+
setMcpServerCount(count) {
|
|
82
|
+
this.#mcpServerCount = count;
|
|
83
|
+
this.#notify();
|
|
84
|
+
}
|
|
85
|
+
setPoolMax(max) {
|
|
86
|
+
this.#poolMax = max;
|
|
87
|
+
this.#poolStats.max = max;
|
|
88
|
+
this.#notify();
|
|
89
|
+
}
|
|
90
|
+
setAcpChildState(state) {
|
|
91
|
+
this.#acpChildState = state;
|
|
92
|
+
this.#notify();
|
|
93
|
+
}
|
|
94
|
+
setPoolStats(stats) {
|
|
95
|
+
this.#poolStats = stats;
|
|
96
|
+
this.#notify();
|
|
97
|
+
}
|
|
98
|
+
setDraining(draining) {
|
|
99
|
+
this.#draining = draining;
|
|
100
|
+
this.#notify();
|
|
101
|
+
}
|
|
102
|
+
addDiagnostic(line) {
|
|
103
|
+
this.#diagnostics.push(`[${new Date().toLocaleTimeString()}] ${line}`);
|
|
104
|
+
if (this.#diagnostics.length > MAX_DIAGNOSTICS) {
|
|
105
|
+
this.#diagnostics.splice(0, this.#diagnostics.length - MAX_DIAGNOSTICS);
|
|
106
|
+
}
|
|
107
|
+
this.#notify();
|
|
108
|
+
}
|
|
109
|
+
onEnqueued(externalKey, queueDepth) {
|
|
110
|
+
const card = this.#card(externalKey);
|
|
111
|
+
card.status = "in_progress";
|
|
112
|
+
card.phase = queueDepth > 1 ? "queued" : (card.phase ?? "queued");
|
|
113
|
+
card.queueDepth = queueDepth;
|
|
114
|
+
this.#notify();
|
|
115
|
+
}
|
|
116
|
+
onWaitingSlot(externalKey) {
|
|
117
|
+
const card = this.#card(externalKey);
|
|
118
|
+
card.status = "in_progress";
|
|
119
|
+
card.phase = "waiting_slot";
|
|
120
|
+
this.#notify();
|
|
121
|
+
}
|
|
122
|
+
onDequeued(externalKey, userId, origin, prompt, queueDepth) {
|
|
123
|
+
const card = this.#card(externalKey);
|
|
124
|
+
card.status = "in_progress";
|
|
125
|
+
card.phase = "setting_up";
|
|
126
|
+
card.userId = userId;
|
|
127
|
+
card.origin = origin;
|
|
128
|
+
card.promptPreview = truncatePreview(prompt);
|
|
129
|
+
card.streamPreview = undefined;
|
|
130
|
+
card.toolLabel = undefined;
|
|
131
|
+
card.errorMessage = undefined;
|
|
132
|
+
card.queueDepth = queueDepth;
|
|
133
|
+
card.lastActiveAt = Date.now();
|
|
134
|
+
this.#notify();
|
|
135
|
+
}
|
|
136
|
+
onSessionReady(externalKey, acpSessionId) {
|
|
137
|
+
const card = this.#card(externalKey);
|
|
138
|
+
card.acpSessionId = acpSessionId;
|
|
139
|
+
card.phase = "generating";
|
|
140
|
+
this.#notify();
|
|
141
|
+
}
|
|
142
|
+
onSessionSetupFailed(externalKey, message) {
|
|
143
|
+
const card = this.#card(externalKey);
|
|
144
|
+
card.status = "idle";
|
|
145
|
+
card.phase = undefined;
|
|
146
|
+
card.errorMessage = message;
|
|
147
|
+
card.lastActiveAt = Date.now();
|
|
148
|
+
this.#notify();
|
|
149
|
+
}
|
|
150
|
+
onPromptFailed(externalKey, message) {
|
|
151
|
+
const card = this.#cards.get(externalKey);
|
|
152
|
+
if (card) {
|
|
153
|
+
card.errorMessage = message;
|
|
154
|
+
}
|
|
155
|
+
this.#notify();
|
|
156
|
+
}
|
|
157
|
+
onIdle(externalKey) {
|
|
158
|
+
const card = this.#cards.get(externalKey);
|
|
159
|
+
if (!card) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
card.status = "idle";
|
|
163
|
+
card.phase = undefined;
|
|
164
|
+
card.toolLabel = undefined;
|
|
165
|
+
card.queueDepth = 0;
|
|
166
|
+
card.lastActiveAt = Date.now();
|
|
167
|
+
this.#notify();
|
|
168
|
+
}
|
|
169
|
+
onDisposed(externalKey, reason) {
|
|
170
|
+
const card = this.#cards.get(externalKey);
|
|
171
|
+
if (!card) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
this.#cards.delete(externalKey);
|
|
175
|
+
card.status = "disposed";
|
|
176
|
+
card.disposeReason = reason;
|
|
177
|
+
card.disposedAt = Date.now();
|
|
178
|
+
this.#disposed.unshift(card);
|
|
179
|
+
if (this.#disposed.length > MAX_DISPOSED) {
|
|
180
|
+
this.#disposed.length = MAX_DISPOSED;
|
|
181
|
+
}
|
|
182
|
+
this.#notify();
|
|
183
|
+
}
|
|
184
|
+
/** Parses a raw ACP `session/update` payload into card state, keyed by external key. */
|
|
185
|
+
onAcpUpdate(externalKey, notification) {
|
|
186
|
+
const card = this.#cards.get(externalKey);
|
|
187
|
+
if (!card) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const update = notification.update;
|
|
191
|
+
card.lastActiveAt = Date.now();
|
|
192
|
+
switch (update.sessionUpdate) {
|
|
193
|
+
case "agent_message_chunk": {
|
|
194
|
+
const text = textFromContent(update.content);
|
|
195
|
+
if (text) {
|
|
196
|
+
card.phase = "generating";
|
|
197
|
+
card.toolLabel = undefined;
|
|
198
|
+
card.streamPreview = appendStreamText(card.streamPreview, text);
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case "agent_thought_chunk": {
|
|
203
|
+
card.phase = "generating";
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case "tool_call": {
|
|
207
|
+
card.phase = "tool";
|
|
208
|
+
card.toolLabel = `${update.title} \u00b7 running`;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case "tool_call_update": {
|
|
212
|
+
card.phase = "tool";
|
|
213
|
+
const status = update.status ?? "in_progress";
|
|
214
|
+
card.toolLabel = `${card.toolLabel?.split(" \u00b7 ")[0] ?? "tool"} \u00b7 ${status}`;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
case "session_info_update": {
|
|
218
|
+
if (update.title) {
|
|
219
|
+
card.title = update.title;
|
|
220
|
+
}
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
case "usage_update": {
|
|
224
|
+
const meta = notification._meta?.["hoomanjs/tokens"];
|
|
225
|
+
card.usage = {
|
|
226
|
+
inputTokens: meta?.input ?? card.usage.inputTokens,
|
|
227
|
+
outputTokens: meta?.output ?? card.usage.outputTokens,
|
|
228
|
+
cacheReadInputTokens: meta?.cacheRead,
|
|
229
|
+
cacheWriteInputTokens: meta?.cacheWrite,
|
|
230
|
+
tokensPerSecond: meta?.tokensPerSecond,
|
|
231
|
+
contextUsed: update.used,
|
|
232
|
+
contextSize: update.size > 0 ? update.size : undefined,
|
|
233
|
+
costUsd: update.cost?.amount,
|
|
234
|
+
};
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
default:
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
this.#notify();
|
|
241
|
+
}
|
|
242
|
+
onApprovalWait(externalKey) {
|
|
243
|
+
const card = this.#cards.get(externalKey);
|
|
244
|
+
if (card) {
|
|
245
|
+
card.phase = "approval";
|
|
246
|
+
this.#notify();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
#laneOf(status) {
|
|
250
|
+
return [...this.#cards.values()].filter((card) => card.status === status);
|
|
251
|
+
}
|
|
252
|
+
snapshot() {
|
|
253
|
+
const idle = this.#laneOf("idle").sort((a, b) => b.lastActiveAt - a.lastActiveAt);
|
|
254
|
+
const inProgress = this.#laneOf("in_progress").sort((a, b) => a.createdAt - b.createdAt);
|
|
255
|
+
const disposed = [...this.#disposed];
|
|
256
|
+
const allLiveUsage = [...idle, ...inProgress];
|
|
257
|
+
let inputTokens = 0;
|
|
258
|
+
let outputTokens = 0;
|
|
259
|
+
let costUsd = 0;
|
|
260
|
+
let costComplete = allLiveUsage.length > 0;
|
|
261
|
+
for (const card of allLiveUsage) {
|
|
262
|
+
inputTokens += card.usage.inputTokens;
|
|
263
|
+
outputTokens += card.usage.outputTokens;
|
|
264
|
+
if (card.usage.costUsd !== undefined) {
|
|
265
|
+
costUsd += card.usage.costUsd;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
costComplete = false;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
startedAt: this.#startedAt,
|
|
273
|
+
now: Date.now(),
|
|
274
|
+
channels: this.#channels,
|
|
275
|
+
mcpServerCount: this.#mcpServerCount,
|
|
276
|
+
acpChildState: this.#acpChildState,
|
|
277
|
+
poolActive: this.#poolStats.active,
|
|
278
|
+
poolMax: this.#poolStats.max || this.#poolMax,
|
|
279
|
+
poolWaiting: this.#poolStats.waiting,
|
|
280
|
+
totalQueued: inProgress.reduce((sum, card) => sum + Math.max(0, card.queueDepth - 1), 0),
|
|
281
|
+
aggregateUsage: { inputTokens, outputTokens, costUsd, costComplete },
|
|
282
|
+
draining: this.#draining,
|
|
283
|
+
idle,
|
|
284
|
+
inProgress,
|
|
285
|
+
disposed,
|
|
286
|
+
diagnostics: this.#diagnostics.slice(-40),
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/daemon/dashboard/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ChannelOrigin } from "../../core/approvals/channel-ask.js";
|
|
2
|
+
import type { DaemonDisposeReason } from "../session-registry.js";
|
|
3
|
+
export type { DaemonDisposeReason };
|
|
4
|
+
/** Which lane a card currently belongs to. */
|
|
5
|
+
export type DaemonLaneStatus = "idle" | "in_progress" | "disposed";
|
|
6
|
+
/** Fine-grained activity while a card is in the "in_progress" lane. */
|
|
7
|
+
export type DaemonTurnPhase = "queued" | "waiting_slot" | "setting_up" | "generating" | "tool" | "approval" | "draining";
|
|
8
|
+
export type DaemonCardUsage = {
|
|
9
|
+
inputTokens: number;
|
|
10
|
+
outputTokens: number;
|
|
11
|
+
cacheReadInputTokens?: number;
|
|
12
|
+
cacheWriteInputTokens?: number;
|
|
13
|
+
tokensPerSecond?: number;
|
|
14
|
+
contextUsed?: number;
|
|
15
|
+
contextSize?: number;
|
|
16
|
+
costUsd?: number;
|
|
17
|
+
};
|
|
18
|
+
export type DaemonSessionCard = {
|
|
19
|
+
externalKey: string;
|
|
20
|
+
acpSessionId?: string;
|
|
21
|
+
title?: string;
|
|
22
|
+
userId?: string;
|
|
23
|
+
origin: ChannelOrigin | null;
|
|
24
|
+
status: DaemonLaneStatus;
|
|
25
|
+
phase?: DaemonTurnPhase;
|
|
26
|
+
toolLabel?: string;
|
|
27
|
+
queueDepth: number;
|
|
28
|
+
promptPreview?: string;
|
|
29
|
+
streamPreview?: string;
|
|
30
|
+
errorMessage?: string;
|
|
31
|
+
disposeReason?: DaemonDisposeReason;
|
|
32
|
+
createdAt: number;
|
|
33
|
+
lastActiveAt: number;
|
|
34
|
+
disposedAt?: number;
|
|
35
|
+
usage: DaemonCardUsage;
|
|
36
|
+
};
|
|
37
|
+
export type DaemonAcpChildState = "starting" | "connected" | "reconnecting" | "stopped";
|
|
38
|
+
export type DaemonDashboardSnapshot = {
|
|
39
|
+
startedAt: number;
|
|
40
|
+
now: number;
|
|
41
|
+
channels: string[];
|
|
42
|
+
mcpServerCount: number;
|
|
43
|
+
acpChildState: DaemonAcpChildState;
|
|
44
|
+
poolActive: number;
|
|
45
|
+
poolMax: number;
|
|
46
|
+
poolWaiting: number;
|
|
47
|
+
totalQueued: number;
|
|
48
|
+
aggregateUsage: {
|
|
49
|
+
inputTokens: number;
|
|
50
|
+
outputTokens: number;
|
|
51
|
+
costUsd: number;
|
|
52
|
+
/** Whether cost is fully priced across every card contributing to it. */
|
|
53
|
+
costComplete: boolean;
|
|
54
|
+
};
|
|
55
|
+
draining: boolean;
|
|
56
|
+
idle: DaemonSessionCard[];
|
|
57
|
+
inProgress: DaemonSessionCard[];
|
|
58
|
+
disposed: DaemonSessionCard[];
|
|
59
|
+
diagnostics: string[];
|
|
60
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/daemon/dashboard/types.ts"],"names":[],"mappings":""}
|
package/dist/daemon/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Manager as McpManager } from "../core/mcp/index.js";
|
|
2
2
|
import type { AcpDaemonClient } from "./acp-client.js";
|
|
3
|
+
import type { DaemonDashboardStore } from "./dashboard/store.js";
|
|
3
4
|
import type { DaemonMcpProxyServer } from "./mcproxy/index.js";
|
|
4
5
|
import type { DaemonSessionRegistry } from "./session-registry.js";
|
|
5
6
|
export type DaemonCliOverrides = {
|
|
@@ -18,5 +19,7 @@ export type RunDaemonOptions = {
|
|
|
18
19
|
session?: string;
|
|
19
20
|
cliOverrides: DaemonCliOverrides;
|
|
20
21
|
debug?: boolean;
|
|
22
|
+
/** When set, diagnostics route into the dashboard instead of raw stderr writes. */
|
|
23
|
+
dashboard?: DaemonDashboardStore;
|
|
21
24
|
};
|
|
22
25
|
export declare function main(options: RunDaemonOptions): Promise<void>;
|
package/dist/daemon/index.js
CHANGED
|
@@ -3,9 +3,6 @@ import { CONFIG_ID_EFFORT, CONFIG_ID_MODE, CONFIG_ID_MODEL, CONFIG_ID_YOLO, } fr
|
|
|
3
3
|
import { HOOMAN_CHANNEL } from "../core/mcp/index.js";
|
|
4
4
|
import { attachmentPathsToAcpBlocks } from "./attachments.js";
|
|
5
5
|
import { KeyedTurnQueue } from "./queue.js";
|
|
6
|
-
function debug(text) {
|
|
7
|
-
stderr.write(`[daemon] ${text}\n`);
|
|
8
|
-
}
|
|
9
6
|
function resolveExternalKey(message, cliSessionFallback) {
|
|
10
7
|
const { server, channel } = message.meta.subscription;
|
|
11
8
|
const raw = message.meta.session?.trim() || cliSessionFallback?.trim();
|
|
@@ -76,8 +73,18 @@ async function applyCliOverrides(acpClient, sessionId, overrides) {
|
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
75
|
export async function main(options) {
|
|
76
|
+
const dashboard = options.dashboard;
|
|
77
|
+
function debug(text) {
|
|
78
|
+
if (dashboard) {
|
|
79
|
+
dashboard.addDiagnostic(text);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
stderr.write(`[daemon] ${text}\n`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
79
85
|
const channels = [HOOMAN_CHANNEL];
|
|
80
86
|
debug(`starting daemon for channel(s): ${channels.join(", ")}`);
|
|
87
|
+
dashboard?.setChannels(channels);
|
|
81
88
|
const queue = new KeyedTurnQueue();
|
|
82
89
|
async function ensureAcpSession(externalKey, userId, origin) {
|
|
83
90
|
if (options.registry.hasRuntime(externalKey)) {
|
|
@@ -154,6 +161,7 @@ export async function main(options) {
|
|
|
154
161
|
if (options.debug) {
|
|
155
162
|
debug(`raw → ${JSON.stringify(message.meta)}`);
|
|
156
163
|
}
|
|
164
|
+
dashboard?.onDequeued(externalKey, userId, origin, message.prompt, queue.length(externalKey));
|
|
157
165
|
let acpSessionId;
|
|
158
166
|
try {
|
|
159
167
|
acpSessionId = await ensureAcpSession(externalKey, userId, origin);
|
|
@@ -161,22 +169,27 @@ export async function main(options) {
|
|
|
161
169
|
catch (error) {
|
|
162
170
|
const text = error instanceof Error ? error.message : String(error);
|
|
163
171
|
debug(`session setup failed → ${externalKey}: ${text}`);
|
|
164
|
-
|
|
172
|
+
dashboard?.onSessionSetupFailed(externalKey, text);
|
|
173
|
+
// No runtime was ever registered for this attempt, so `markIdle` would
|
|
174
|
+
// find nothing and the acquired slot would leak — release it directly.
|
|
175
|
+
options.registry.releaseFailedSlot(externalKey);
|
|
165
176
|
return;
|
|
166
177
|
}
|
|
178
|
+
dashboard?.onSessionReady(externalKey, acpSessionId);
|
|
167
179
|
try {
|
|
168
180
|
debug(`invoking agent → ${tag} session=${externalKey} acp=${acpSessionId}`);
|
|
169
181
|
const prompt = await toPromptBlocks(message);
|
|
170
|
-
await options.acpClient.prompt({
|
|
182
|
+
const response = await options.acpClient.prompt({
|
|
171
183
|
sessionId: acpSessionId,
|
|
172
184
|
prompt,
|
|
173
185
|
meta: { "hooman/origin": origin },
|
|
174
186
|
});
|
|
175
|
-
debug(`completed → ${tag} session=${externalKey} acp=${acpSessionId}`);
|
|
187
|
+
debug(`completed → ${tag} session=${externalKey} acp=${acpSessionId} stopReason=${response.stopReason}`);
|
|
176
188
|
}
|
|
177
189
|
catch (error) {
|
|
178
190
|
const text = error instanceof Error ? error.message : String(error);
|
|
179
191
|
debug(`turn failed → ${tag} session=${externalKey} acp=${acpSessionId}: ${text}`);
|
|
192
|
+
dashboard?.onPromptFailed(externalKey, text);
|
|
180
193
|
}
|
|
181
194
|
finally {
|
|
182
195
|
options.registry.markIdle(externalKey, queue.length(externalKey) > 1);
|
|
@@ -184,7 +197,9 @@ export async function main(options) {
|
|
|
184
197
|
}
|
|
185
198
|
const handle = await options.manager.subscribeToChannels(channels, (message) => {
|
|
186
199
|
debug(`received notification → ${message.meta.subscription.server}:${message.meta.subscription.channel}`);
|
|
187
|
-
|
|
200
|
+
const key = resolveExternalKey(message, options.session);
|
|
201
|
+
queue.push(key, () => runTurn(message));
|
|
202
|
+
dashboard?.onEnqueued(key, queue.length(key));
|
|
188
203
|
});
|
|
189
204
|
debug(`subscribed → ${formatSubscriptions(handle.subscriptions)}`);
|
|
190
205
|
const stopper = new Promise((resolve) => {
|
|
@@ -197,6 +212,7 @@ export async function main(options) {
|
|
|
197
212
|
}
|
|
198
213
|
finally {
|
|
199
214
|
debug("stopping daemon");
|
|
215
|
+
dashboard?.setDraining(true);
|
|
200
216
|
handle.unsubscribe();
|
|
201
217
|
await queue.drain();
|
|
202
218
|
await options.registry.shutdown();
|
package/dist/daemon/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAKtC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAOtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon/queue.js
CHANGED
|
@@ -17,10 +17,19 @@ export class KeyedTurnQueue {
|
|
|
17
17
|
};
|
|
18
18
|
state.length += 1;
|
|
19
19
|
this.#tails.set(key, state);
|
|
20
|
+
// Swallow task rejections here: `state.tail` is chained with `.then()`,
|
|
21
|
+
// so a rejected tail would skip every subsequent `.then()` callback for
|
|
22
|
+
// this key, permanently poisoning the queue instead of just failing one
|
|
23
|
+
// turn. Callers that care about per-task failure (e.g. `runTurn`) already
|
|
24
|
+
// catch their own errors; this is a backstop against anything that slips
|
|
25
|
+
// past that.
|
|
20
26
|
state.tail = state.tail.then(async () => {
|
|
21
27
|
try {
|
|
22
28
|
await task();
|
|
23
29
|
}
|
|
30
|
+
catch {
|
|
31
|
+
/* ignore: never poison the chain for this key */
|
|
32
|
+
}
|
|
24
33
|
finally {
|
|
25
34
|
state.length -= 1;
|
|
26
35
|
if (state.length === 0) {
|
package/dist/daemon/queue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/daemon/queue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,cAAc;IACzB,MAAM,GAAG,IAAI,GAAG,EAAmD,CAAC;IAEpE,sFAAsF;IAC/E,MAAM,CAAC,GAAW;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,iFAAiF;IAC1E,IAAI,CAAC,GAAW,EAAE,IAAyB;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI;YACpC,MAAM,EAAE,CAAC;YACT,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE;SACxB,CAAC;QACF,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,IAAI,CAAC;gBACH,MAAM,IAAI,EAAE,CAAC;YACf,CAAC;oBAAS,CAAC;gBACT,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;gBAClB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0EAA0E;IACnE,KAAK,CAAC,KAAK;QAChB,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/daemon/queue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,cAAc;IACzB,MAAM,GAAG,IAAI,GAAG,EAAmD,CAAC;IAEpE,sFAAsF;IAC/E,MAAM,CAAC,GAAW;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,iFAAiF;IAC1E,IAAI,CAAC,GAAW,EAAE,IAAyB;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI;YACpC,MAAM,EAAE,CAAC;YACT,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE;SACxB,CAAC;QACF,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC5B,wEAAwE;QACxE,wEAAwE;QACxE,wEAAwE;QACxE,0EAA0E;QAC1E,yEAAyE;QACzE,aAAa;QACb,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtC,IAAI,CAAC;gBACH,MAAM,IAAI,EAAE,CAAC;YACf,CAAC;YAAC,MAAM,CAAC;gBACP,iDAAiD;YACnD,CAAC;oBAAS,CAAC;gBACT,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;gBAClB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0EAA0E;IACnE,KAAK,CAAC,KAAK;QAChB,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,CAAC;CACF"}
|
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import type { ChannelOrigin } from "../core/approvals/channel-ask.js";
|
|
2
|
+
/** Why a runtime session's pool slot was released. */
|
|
3
|
+
export type DaemonDisposeReason = "idle_timeout" | "pool_pressure" | "shutdown" | "child_exit";
|
|
4
|
+
export type DaemonRegistryEvent = {
|
|
5
|
+
type: "slot_waiting";
|
|
6
|
+
externalKey: string;
|
|
7
|
+
} | {
|
|
8
|
+
type: "slot_acquired";
|
|
9
|
+
externalKey: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: "active";
|
|
12
|
+
externalKey: string;
|
|
13
|
+
acpSessionId: string;
|
|
14
|
+
userId?: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: "idle";
|
|
17
|
+
externalKey: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: "disposed";
|
|
20
|
+
externalKey: string;
|
|
21
|
+
acpSessionId: string;
|
|
22
|
+
reason: DaemonDisposeReason;
|
|
23
|
+
};
|
|
2
24
|
export type DaemonSessionRegistryOptions = {
|
|
3
25
|
/** Bound on concurrently active ACP sessions. Must be a positive integer. */
|
|
4
26
|
maxActiveSessions: number;
|
|
5
27
|
/** Ordinary idle-close delay after a session becomes non-busy. `0` disables it (pressure eviction still applies). */
|
|
6
28
|
idleTimeoutMs: number;
|
|
7
|
-
/** Called to close an ACP session (idle timeout, pool pressure, or shutdown).
|
|
29
|
+
/** Called to close an ACP session (idle timeout, pool pressure, or shutdown). May throw; cleanup still runs. */
|
|
8
30
|
onClose: (externalKey: string, acpSessionId: string) => Promise<void>;
|
|
31
|
+
/** Notified on every pool/lifecycle transition, for dashboard/diagnostics consumers. */
|
|
32
|
+
onEvent?: (event: DaemonRegistryEvent) => void;
|
|
9
33
|
};
|
|
10
34
|
/**
|
|
11
35
|
* Tracks the daemon's channel-conversation → ACP-session bindings, the
|
|
@@ -33,6 +57,22 @@ export declare class DaemonSessionRegistry {
|
|
|
33
57
|
* when eviction and waiting happen concurrently.
|
|
34
58
|
*/
|
|
35
59
|
acquireSlot(externalKey: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Releases a pool slot acquired via {@link acquireSlot} when session setup
|
|
62
|
+
* fails *before* a runtime was ever registered — otherwise the key would
|
|
63
|
+
* stay parked in `#activeKeys` forever (no runtime for `markIdle` to find),
|
|
64
|
+
* slowly exhausting the pool across repeated failures.
|
|
65
|
+
*/
|
|
66
|
+
releaseFailedSlot(externalKey: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Drops every runtime entry (but keeps pool slots reserved) after the
|
|
69
|
+
* shared ACP child process exits unexpectedly. `hasRuntime()` then returns
|
|
70
|
+
* `false` for every key, so the next turn for each falls back to
|
|
71
|
+
* `resumeSession()` against the persisted ACP session ID on the fresh
|
|
72
|
+
* child, instead of silently prompting a runtime the new child never
|
|
73
|
+
* created.
|
|
74
|
+
*/
|
|
75
|
+
invalidateRuntimes(): void;
|
|
36
76
|
/** Registers a newly created/resumed active session and marks it busy for the in-flight turn. */
|
|
37
77
|
registerActive(binding: {
|
|
38
78
|
externalKey: string;
|
|
@@ -62,5 +102,11 @@ export declare class DaemonSessionRegistry {
|
|
|
62
102
|
markIdle(externalKey: string, hasQueuedWork: boolean): void;
|
|
63
103
|
/** Rejects queued waiters, closes every active session, and stops granting new slots. */
|
|
64
104
|
shutdown(): Promise<void>;
|
|
105
|
+
/** Snapshot pool occupancy for dashboard/diagnostics consumers. */
|
|
106
|
+
poolStats(): {
|
|
107
|
+
active: number;
|
|
108
|
+
max: number;
|
|
109
|
+
waiting: number;
|
|
110
|
+
};
|
|
65
111
|
get isShuttingDown(): boolean;
|
|
66
112
|
}
|