@namzu/cli 25.0.1 → 26.0.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/CHANGELOG.md +265 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +9 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/acp.js +5 -0
- package/dist/commands/acp.js.map +1 -1
- package/dist/commands/drain.d.ts.map +1 -1
- package/dist/commands/drain.js +5 -0
- package/dist/commands/drain.js.map +1 -1
- package/dist/commands/run-stream.d.ts.map +1 -1
- package/dist/commands/run-stream.js +5 -0
- package/dist/commands/run-stream.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +5 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +47 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +24 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/config/tool-result-screens.d.ts +103 -0
- package/dist/config/tool-result-screens.d.ts.map +1 -0
- package/dist/config/tool-result-screens.js +104 -0
- package/dist/config/tool-result-screens.js.map +1 -0
- package/dist/context/doctrine.d.ts +4 -2
- package/dist/context/doctrine.d.ts.map +1 -1
- package/dist/context/doctrine.js +4 -2
- package/dist/context/doctrine.js.map +1 -1
- package/dist/integrations/mcp/servers.d.ts +30 -0
- package/dist/integrations/mcp/servers.d.ts.map +1 -1
- package/dist/integrations/mcp/servers.js +32 -1
- package/dist/integrations/mcp/servers.js.map +1 -1
- package/dist/integrations/resident/session-step.d.ts.map +1 -1
- package/dist/integrations/resident/session-step.js +5 -0
- package/dist/integrations/resident/session-step.js.map +1 -1
- package/dist/integrations/subagents/activity.d.ts +285 -11
- package/dist/integrations/subagents/activity.d.ts.map +1 -1
- package/dist/integrations/subagents/activity.js +334 -31
- package/dist/integrations/subagents/activity.js.map +1 -1
- package/dist/integrations/subagents/replay.d.ts +46 -0
- package/dist/integrations/subagents/replay.d.ts.map +1 -0
- package/dist/integrations/subagents/replay.js +193 -0
- package/dist/integrations/subagents/replay.js.map +1 -0
- package/dist/integrations/subagents/runs.d.ts +72 -0
- package/dist/integrations/subagents/runs.d.ts.map +1 -0
- package/dist/integrations/subagents/runs.js +155 -0
- package/dist/integrations/subagents/runs.js.map +1 -0
- package/dist/integrations/subagents/runtime.d.ts +21 -0
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +134 -2
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/tui/AgentExplorer.d.ts +46 -2
- package/dist/tui/AgentExplorer.d.ts.map +1 -1
- package/dist/tui/AgentExplorer.js +261 -22
- package/dist/tui/AgentExplorer.js.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +456 -28
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/ChoicePicker.d.ts +2 -0
- package/dist/tui/ChoicePicker.d.ts.map +1 -1
- package/dist/tui/ChoicePicker.js +3 -1
- package/dist/tui/ChoicePicker.js.map +1 -1
- package/dist/tui/Composer.d.ts +10 -7
- package/dist/tui/Composer.d.ts.map +1 -1
- package/dist/tui/Composer.js +2 -7
- package/dist/tui/Composer.js.map +1 -1
- package/dist/tui/StatusBar.d.ts +56 -10
- package/dist/tui/StatusBar.d.ts.map +1 -1
- package/dist/tui/StatusBar.js +106 -35
- package/dist/tui/StatusBar.js.map +1 -1
- package/dist/tui/agent.d.ts +46 -1
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +55 -5
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/choice-selection.d.ts +3 -1
- package/dist/tui/choice-selection.d.ts.map +1 -1
- package/dist/tui/choice-selection.js +2 -2
- package/dist/tui/choice-selection.js.map +1 -1
- package/dist/tui/permission-review.d.ts.map +1 -1
- package/dist/tui/permission-review.js +14 -2
- package/dist/tui/permission-review.js.map +1 -1
- package/dist/tui/slashCommands.d.ts +40 -0
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +62 -3
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/types.d.ts +12 -0
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { RunDiskStore, readRunEventsIn, } from '@namzu/sdk';
|
|
4
|
+
import { SubagentActivityMonitor, } from './activity.js';
|
|
5
|
+
/**
|
|
6
|
+
* Session directories scanned when looking for a conversation's saved
|
|
7
|
+
* children.
|
|
8
|
+
*
|
|
9
|
+
* Each delegated child is given its OWN session directory, so the children of
|
|
10
|
+
* one parent run are spread across as many of them as the parent launched
|
|
11
|
+
* children. A long-lived project accumulates those, and a scan with no
|
|
12
|
+
* ceiling would grow with the whole estate rather than with the conversation
|
|
13
|
+
* being opened. The scan is one `readdir` per directory and stops here.
|
|
14
|
+
*
|
|
15
|
+
* It is a bound, not a policy. Entries come back in the order the filesystem
|
|
16
|
+
* lists them, so past this many directories WHICH children are found stops
|
|
17
|
+
* being predictable — which is an argument for a prune command, not a
|
|
18
|
+
* substitute for one.
|
|
19
|
+
*/
|
|
20
|
+
const MAX_SCANNED_SESSION_DIRECTORIES = 2_000;
|
|
21
|
+
/**
|
|
22
|
+
* Children replayed into one monitor, matching the live monitor's own
|
|
23
|
+
* retention. Replay walks the newest first and stops at this many, so a
|
|
24
|
+
* conversation that delegated thousands of times opens its most recent work
|
|
25
|
+
* instead of its whole history.
|
|
26
|
+
*/
|
|
27
|
+
const MAX_REPLAYED_CHILDREN = 80;
|
|
28
|
+
/**
|
|
29
|
+
* Every delegated child saved under one conversation's parent runs, newest
|
|
30
|
+
* first.
|
|
31
|
+
*
|
|
32
|
+
* Two directory shapes have to meet here. A conversation's own runs are
|
|
33
|
+
* `<sessionsRoot>/<sessionId>/runs/<runId>`, which is where the parent run
|
|
34
|
+
* ids come from after a restart has forgotten them. A child's evidence is
|
|
35
|
+
* `<sessionsRoot>/<childSessionId>/runs/<parentRunId>/children/<childRunId>`,
|
|
36
|
+
* under the child's session and not the parent's — so finding a child means
|
|
37
|
+
* asking every session directory whether it holds a `runs/` entry named after
|
|
38
|
+
* one of this conversation's runs.
|
|
39
|
+
*
|
|
40
|
+
* That ordering is deliberate: one `readdir` per session directory answers
|
|
41
|
+
* the question for all of that directory's children at once, where probing
|
|
42
|
+
* each parent run inside each session directory would multiply the two
|
|
43
|
+
* counts. A child session directory holds exactly one parent run id, so the
|
|
44
|
+
* inner listing runs only where there is something to list.
|
|
45
|
+
*
|
|
46
|
+
* READ-ONLY throughout. Nothing here creates a directory, and in particular
|
|
47
|
+
* nothing binds a `RunDiskStore`, which would mint the run directory it was
|
|
48
|
+
* asked about.
|
|
49
|
+
*/
|
|
50
|
+
export async function listSavedChildren(scope) {
|
|
51
|
+
const parentRunIds = new Set(await directoryNames(join(scope.sessionsRoot, scope.sessionId, 'runs')));
|
|
52
|
+
if (parentRunIds.size === 0)
|
|
53
|
+
return [];
|
|
54
|
+
const sessionIds = await directoryNames(scope.sessionsRoot);
|
|
55
|
+
const found = [];
|
|
56
|
+
for (const sessionId of sessionIds.slice(0, MAX_SCANNED_SESSION_DIRECTORIES)) {
|
|
57
|
+
const runsDir = join(scope.sessionsRoot, sessionId, 'runs');
|
|
58
|
+
for (const runId of await directoryNames(runsDir)) {
|
|
59
|
+
if (!parentRunIds.has(runId))
|
|
60
|
+
continue;
|
|
61
|
+
try {
|
|
62
|
+
found.push(...(await RunDiskStore.listChildren(runsDir, runId)));
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
// One unreadable parent directory is not a reason to report that a
|
|
66
|
+
// conversation delegated nothing. Named so the operator can find it.
|
|
67
|
+
scope.log?.warn('Saved delegated children could not be listed', {
|
|
68
|
+
'namzu.subagent.replay.runs_dir': runsDir,
|
|
69
|
+
'namzu.subagent.replay.parent_run_id': runId,
|
|
70
|
+
'namzu.subagent.replay.error': errorMessage(error),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Newest first so the cap keeps the most recent work, then back into launch
|
|
76
|
+
// order, which is the order the cockpit lists a cohort in.
|
|
77
|
+
found.sort((left, right) => (right.startedAt ?? 0) - (left.startedAt ?? 0));
|
|
78
|
+
return found.slice(0, scope.maxChildren ?? MAX_REPLAYED_CHILDREN).reverse();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Replays saved children into the display shape the live monitor publishes.
|
|
82
|
+
*
|
|
83
|
+
* One monitor for the whole batch, in replay mode: its bounds, its grouping
|
|
84
|
+
* and its projection are the live ones, and its rows carry
|
|
85
|
+
* {@link SubagentActivity.replayed} so no surface offers to act on work that
|
|
86
|
+
* finished in another process.
|
|
87
|
+
*/
|
|
88
|
+
export async function replaySavedChildren(children, log) {
|
|
89
|
+
const monitor = new SubagentActivityMonitor({ replay: true });
|
|
90
|
+
for (const child of children) {
|
|
91
|
+
const evidence = await readChildEvidence(child, log);
|
|
92
|
+
monitor.replay({
|
|
93
|
+
agentId: child.agentId ?? child.agentName ?? child.id,
|
|
94
|
+
description: child.agentName ?? child.agentId ?? child.id,
|
|
95
|
+
...(child.model ? { model: child.model } : {}),
|
|
96
|
+
runId: child.id,
|
|
97
|
+
// A parent run is the display group a live cohort is keyed by, and
|
|
98
|
+
// the batch a child belonged to is not recorded on disk. Grouping
|
|
99
|
+
// every saved child of one parent run together is the coarsest
|
|
100
|
+
// answer that is still true; splitting them by anything else would
|
|
101
|
+
// invent a boundary the evidence does not have.
|
|
102
|
+
workflowId: child.parentRunId,
|
|
103
|
+
batchId: `saved:${child.parentRunId}`,
|
|
104
|
+
...(child.status ? { status: activityStatus(child.status) } : {}),
|
|
105
|
+
...(child.totalTokens !== undefined ? { tokens: child.totalTokens } : {}),
|
|
106
|
+
...(child.startedAt !== undefined ? { startedAt: child.startedAt } : {}),
|
|
107
|
+
...(child.endedAt !== undefined ? { completedAt: child.endedAt } : {}),
|
|
108
|
+
...(evidence.partial ? { partial: true } : {}),
|
|
109
|
+
}, evidence.events);
|
|
110
|
+
}
|
|
111
|
+
return monitor.getSnapshot();
|
|
112
|
+
}
|
|
113
|
+
/** Discovery and replay in one call, for a host that wants the whole list. */
|
|
114
|
+
export async function replaySavedChildrenFor(scope) {
|
|
115
|
+
return replaySavedChildren(await listSavedChildren(scope), scope.log);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* One child's durable events, and whether all of them could be read.
|
|
119
|
+
*
|
|
120
|
+
* Read strictly first, then tolerantly. The strict pass is not about
|
|
121
|
+
* refusing damaged evidence — it is the only way to LEARN that the evidence
|
|
122
|
+
* is damaged, because the tolerant reader's whole job is to skip a torn
|
|
123
|
+
* record and carry on, which leaves a truncated transcript indistinguishable
|
|
124
|
+
* from a short one. A replay that quietly showed four rows of a forty-row run
|
|
125
|
+
* would be the most misleading thing this view could do, so the damage is
|
|
126
|
+
* reported instead: the rows that survive are shown, and the transcript says
|
|
127
|
+
* it is partial.
|
|
128
|
+
*
|
|
129
|
+
* A transcript that cannot be read AT ALL — an unreadable file, or a
|
|
130
|
+
* compaction archive beside it that the tolerant read cannot skip past
|
|
131
|
+
* either — is the same answer taken to its limit: no rows, and partial. It is
|
|
132
|
+
* not a reason to leave the child out of the listing. `run.json` still
|
|
133
|
+
* records what the run did and when, dropping the row would say this child
|
|
134
|
+
* never existed, and a row that shows the facts it has under a notice saying
|
|
135
|
+
* the record is incomplete is the honest version of the same information.
|
|
136
|
+
*/
|
|
137
|
+
async function readChildEvidence(child, log) {
|
|
138
|
+
try {
|
|
139
|
+
return { events: await readRunEventsIn(child.dir, { integrity: 'strict' }), partial: false };
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Falls through to the tolerant read below.
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
return { events: await readRunEventsIn(child.dir), partial: true };
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
log?.warn('Saved child transcript could not be read', {
|
|
149
|
+
'namzu.subagent.replay.child_dir': child.dir,
|
|
150
|
+
'namzu.subagent.replay.error': errorMessage(error),
|
|
151
|
+
});
|
|
152
|
+
return { events: [], partial: true };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* A saved run status as the display status the monitor projects.
|
|
157
|
+
*
|
|
158
|
+
* `running` survives as `working` rather than being rewritten to a terminal
|
|
159
|
+
* value: a process killed mid-run genuinely did not record an ending, and
|
|
160
|
+
* claiming one would be a different lie from the one this view exists to
|
|
161
|
+
* avoid. Nothing is attached to the row either way — `replayed` is what says
|
|
162
|
+
* that, on every replayed row regardless of status.
|
|
163
|
+
*/
|
|
164
|
+
function activityStatus(status) {
|
|
165
|
+
switch (status) {
|
|
166
|
+
case 'idle':
|
|
167
|
+
return 'starting';
|
|
168
|
+
case 'pending':
|
|
169
|
+
return 'queued';
|
|
170
|
+
case 'running':
|
|
171
|
+
return 'working';
|
|
172
|
+
case 'completed':
|
|
173
|
+
return 'completed';
|
|
174
|
+
case 'failed':
|
|
175
|
+
return 'failed';
|
|
176
|
+
case 'cancelled':
|
|
177
|
+
return 'cancelled';
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/** Directory entries by name; an absent directory lists as nothing. */
|
|
181
|
+
async function directoryNames(dir) {
|
|
182
|
+
try {
|
|
183
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
184
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function errorMessage(error) {
|
|
191
|
+
return error instanceof Error ? error.message : String(error);
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../../src/integrations/subagents/replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type SubagentActivity } from './activity.js';
|
|
2
|
+
import { type SavedChildScope } from './replay.js';
|
|
3
|
+
/**
|
|
4
|
+
* One row of `/agents runs`: every child launched under one parent turn,
|
|
5
|
+
* whether that turn is still going or long settled.
|
|
6
|
+
*
|
|
7
|
+
* {@link id} is the parent run id every one of its children names —
|
|
8
|
+
* `workflowId` on a live {@link SubagentActivity}, `parentRunId` on a saved
|
|
9
|
+
* {@link import('@namzu/sdk').DelegatedChildRun} — so a row from either
|
|
10
|
+
* source addresses the same run the same way.
|
|
11
|
+
*/
|
|
12
|
+
export interface OrchestrationRun {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly startedAt: number;
|
|
16
|
+
readonly phases: readonly string[];
|
|
17
|
+
readonly agentsDone: number;
|
|
18
|
+
readonly agentsTotal: number;
|
|
19
|
+
readonly tokensTotal: number;
|
|
20
|
+
readonly elapsedMs: number;
|
|
21
|
+
/**
|
|
22
|
+
* Read from the live monitor because at least one child is still going.
|
|
23
|
+
*
|
|
24
|
+
* Never true for a row this module read from disk: a finished run is
|
|
25
|
+
* reported from `run.json`, the durable record, and not from whatever the
|
|
26
|
+
* live monitor still happens to retain of it — see
|
|
27
|
+
* {@link listSavedOrchestrationRuns}.
|
|
28
|
+
*/
|
|
29
|
+
readonly live: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parent turns THIS PROCESS is still tracking, one row per run id that has at
|
|
33
|
+
* least one non-terminal child.
|
|
34
|
+
*
|
|
35
|
+
* A group every one of whose members has already settled is left out: that
|
|
36
|
+
* run is better read from disk, where `run.json` is the record of fact, and
|
|
37
|
+
* reporting it here too would be a second, competing account of a run this
|
|
38
|
+
* function has no fresher information about than the disk copy already has.
|
|
39
|
+
* Its caller is what applies that rule — see {@link listSavedOrchestrationRuns}'s
|
|
40
|
+
* own doc — by excluding a live id from the disk pass.
|
|
41
|
+
*
|
|
42
|
+
* The row's name is the group's own `workflow` label, an explicit annotation
|
|
43
|
+
* when the delegating host supplied one and the neutral default otherwise —
|
|
44
|
+
* the live case is the ONE place that label is trustworthy, since the
|
|
45
|
+
* process that would know it is the one being asked. A saved run has no such
|
|
46
|
+
* label to read; see {@link listSavedOrchestrationRuns} for what it reports
|
|
47
|
+
* instead.
|
|
48
|
+
*/
|
|
49
|
+
export declare function liveOrchestrationRuns(agents: readonly SubagentActivity[], now: number): readonly OrchestrationRun[];
|
|
50
|
+
/**
|
|
51
|
+
* Finished parent turns read from disk, one row per parent run id
|
|
52
|
+
* {@link listSavedChildren} finds children under.
|
|
53
|
+
*
|
|
54
|
+
* Cheap by design: only `run.json` is read per child, the same evidence
|
|
55
|
+
* {@link listSavedChildren} already surfaces, and the parent turn's OWN
|
|
56
|
+
* `messages.json` for the row's name — never a child's transcript. A full
|
|
57
|
+
* replay (transcript included) happens once an operator actually opens one
|
|
58
|
+
* of these rows, not while building the list every one of them appears on.
|
|
59
|
+
*
|
|
60
|
+
* Named from the parent turn's own first words, read straight from
|
|
61
|
+
* `<sessionsRoot>/<sessionId>/runs/<parentRunId>/messages.json` — a saved
|
|
62
|
+
* child carries no `workflow` label to fall back to instead, because that
|
|
63
|
+
* label is display-only and reaches nowhere durable (see
|
|
64
|
+
* `docs/sdk/delegation-events.md`); the run that opened the turn is the
|
|
65
|
+
* nearest durable stand-in for what it was.
|
|
66
|
+
*
|
|
67
|
+
* Never reports a phase beyond the neutral default: a phase label is exactly
|
|
68
|
+
* as undurable as a workflow label, so nothing on disk can distinguish two
|
|
69
|
+
* saved phases from one.
|
|
70
|
+
*/
|
|
71
|
+
export declare function listSavedOrchestrationRuns(scope: SavedChildScope): Promise<readonly OrchestrationRun[]>;
|
|
72
|
+
//# sourceMappingURL=runs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runs.ts"],"names":[],"mappings":"AAIA,OAAO,EAGN,KAAK,gBAAgB,EAErB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,eAAe,EAAqB,MAAM,aAAa,CAAA;AAKrE;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACtB;AAiCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,SAAS,gBAAgB,EAAE,EACnC,GAAG,EAAE,MAAM,GACT,SAAS,gBAAgB,EAAE,CAyB7B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,0BAA0B,CAC/C,KAAK,EAAE,eAAe,GACpB,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CA6BtC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { isTerminalStatus as isTerminalRunStatus, readRunMessagesIn } from '@namzu/sdk';
|
|
3
|
+
import { DEFAULT_AGENT_PHASE, DEFAULT_AGENT_WORKFLOW, } from './activity.js';
|
|
4
|
+
import { listSavedChildren } from './replay.js';
|
|
5
|
+
/** Longest a run's display name gets before it is clipped, matching a conversation title's own bound. */
|
|
6
|
+
const MAX_RUN_NAME_CODE_UNITS = 60;
|
|
7
|
+
function isTerminalActivityStatus(status) {
|
|
8
|
+
return status === 'completed' || status === 'failed' || status === 'cancelled';
|
|
9
|
+
}
|
|
10
|
+
function isDefined(value) {
|
|
11
|
+
return value !== undefined;
|
|
12
|
+
}
|
|
13
|
+
/** A phase name per distinct phase a group's members declared, in launch order. */
|
|
14
|
+
function orderedPhaseNames(members) {
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const ordered = [];
|
|
17
|
+
for (const agent of [...members].sort((left, right) => left.phaseSequence - right.phaseSequence)) {
|
|
18
|
+
if (seen.has(agent.phase))
|
|
19
|
+
continue;
|
|
20
|
+
seen.add(agent.phase);
|
|
21
|
+
ordered.push(agent.phase);
|
|
22
|
+
}
|
|
23
|
+
return ordered;
|
|
24
|
+
}
|
|
25
|
+
/** A conversation-title-style clip: one line, `MAX_RUN_NAME_CODE_UNITS` wide, or the neutral default. */
|
|
26
|
+
function runName(text) {
|
|
27
|
+
const oneLine = text?.replace(/\s+/g, ' ').trim();
|
|
28
|
+
if (!oneLine)
|
|
29
|
+
return DEFAULT_AGENT_WORKFLOW;
|
|
30
|
+
return oneLine.length > MAX_RUN_NAME_CODE_UNITS
|
|
31
|
+
? `${oneLine.slice(0, MAX_RUN_NAME_CODE_UNITS - 1)}…`
|
|
32
|
+
: oneLine;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Parent turns THIS PROCESS is still tracking, one row per run id that has at
|
|
36
|
+
* least one non-terminal child.
|
|
37
|
+
*
|
|
38
|
+
* A group every one of whose members has already settled is left out: that
|
|
39
|
+
* run is better read from disk, where `run.json` is the record of fact, and
|
|
40
|
+
* reporting it here too would be a second, competing account of a run this
|
|
41
|
+
* function has no fresher information about than the disk copy already has.
|
|
42
|
+
* Its caller is what applies that rule — see {@link listSavedOrchestrationRuns}'s
|
|
43
|
+
* own doc — by excluding a live id from the disk pass.
|
|
44
|
+
*
|
|
45
|
+
* The row's name is the group's own `workflow` label, an explicit annotation
|
|
46
|
+
* when the delegating host supplied one and the neutral default otherwise —
|
|
47
|
+
* the live case is the ONE place that label is trustworthy, since the
|
|
48
|
+
* process that would know it is the one being asked. A saved run has no such
|
|
49
|
+
* label to read; see {@link listSavedOrchestrationRuns} for what it reports
|
|
50
|
+
* instead.
|
|
51
|
+
*/
|
|
52
|
+
export function liveOrchestrationRuns(agents, now) {
|
|
53
|
+
const groups = new Map();
|
|
54
|
+
for (const agent of agents) {
|
|
55
|
+
if (agent.replayed)
|
|
56
|
+
continue;
|
|
57
|
+
const group = groups.get(agent.workflowId);
|
|
58
|
+
if (group)
|
|
59
|
+
group.push(agent);
|
|
60
|
+
else
|
|
61
|
+
groups.set(agent.workflowId, [agent]);
|
|
62
|
+
}
|
|
63
|
+
const runs = [];
|
|
64
|
+
for (const [id, members] of groups) {
|
|
65
|
+
if (members.every((agent) => isTerminalActivityStatus(agent.status)))
|
|
66
|
+
continue;
|
|
67
|
+
const startedAt = Math.min(...members.map((agent) => agent.startedAt));
|
|
68
|
+
runs.push({
|
|
69
|
+
id,
|
|
70
|
+
name: runName(members[0]?.workflow),
|
|
71
|
+
startedAt,
|
|
72
|
+
phases: orderedPhaseNames(members),
|
|
73
|
+
agentsTotal: members.length,
|
|
74
|
+
agentsDone: members.filter((agent) => isTerminalActivityStatus(agent.status)).length,
|
|
75
|
+
tokensTotal: members.reduce((sum, agent) => sum + (agent.tokens ?? 0), 0),
|
|
76
|
+
elapsedMs: Math.max(0, now - startedAt),
|
|
77
|
+
live: true,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return runs;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Finished parent turns read from disk, one row per parent run id
|
|
84
|
+
* {@link listSavedChildren} finds children under.
|
|
85
|
+
*
|
|
86
|
+
* Cheap by design: only `run.json` is read per child, the same evidence
|
|
87
|
+
* {@link listSavedChildren} already surfaces, and the parent turn's OWN
|
|
88
|
+
* `messages.json` for the row's name — never a child's transcript. A full
|
|
89
|
+
* replay (transcript included) happens once an operator actually opens one
|
|
90
|
+
* of these rows, not while building the list every one of them appears on.
|
|
91
|
+
*
|
|
92
|
+
* Named from the parent turn's own first words, read straight from
|
|
93
|
+
* `<sessionsRoot>/<sessionId>/runs/<parentRunId>/messages.json` — a saved
|
|
94
|
+
* child carries no `workflow` label to fall back to instead, because that
|
|
95
|
+
* label is display-only and reaches nowhere durable (see
|
|
96
|
+
* `docs/sdk/delegation-events.md`); the run that opened the turn is the
|
|
97
|
+
* nearest durable stand-in for what it was.
|
|
98
|
+
*
|
|
99
|
+
* Never reports a phase beyond the neutral default: a phase label is exactly
|
|
100
|
+
* as undurable as a workflow label, so nothing on disk can distinguish two
|
|
101
|
+
* saved phases from one.
|
|
102
|
+
*/
|
|
103
|
+
export async function listSavedOrchestrationRuns(scope) {
|
|
104
|
+
const children = await listSavedChildren(scope);
|
|
105
|
+
const groups = new Map();
|
|
106
|
+
for (const child of children) {
|
|
107
|
+
const group = groups.get(child.parentRunId);
|
|
108
|
+
if (group)
|
|
109
|
+
group.push(child);
|
|
110
|
+
else
|
|
111
|
+
groups.set(child.parentRunId, [child]);
|
|
112
|
+
}
|
|
113
|
+
const runs = [];
|
|
114
|
+
for (const [id, members] of groups) {
|
|
115
|
+
const started = members.map((child) => child.startedAt).filter(isDefined);
|
|
116
|
+
const ended = members.map((child) => child.endedAt).filter(isDefined);
|
|
117
|
+
const startedAt = started.length > 0 ? Math.min(...started) : 0;
|
|
118
|
+
const finishedAt = ended.length > 0 ? Math.max(...ended) : startedAt;
|
|
119
|
+
runs.push({
|
|
120
|
+
id,
|
|
121
|
+
name: runName(await parentTurnFirstWords(scope, id)),
|
|
122
|
+
startedAt,
|
|
123
|
+
phases: [DEFAULT_AGENT_PHASE],
|
|
124
|
+
agentsTotal: members.length,
|
|
125
|
+
agentsDone: members.filter((child) => child.status !== undefined && isTerminalRunStatus(child.status)).length,
|
|
126
|
+
tokensTotal: members.reduce((sum, child) => sum + (child.totalTokens ?? 0), 0),
|
|
127
|
+
elapsedMs: Math.max(0, finishedAt - startedAt),
|
|
128
|
+
live: false,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return runs;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The opening line of the user turn that started `parentRunId`, or
|
|
135
|
+
* `undefined` when it cannot be read — a run still in flight has not written
|
|
136
|
+
* `messages.json` yet (see {@link import('@namzu/sdk').RunStore.writeMessages}),
|
|
137
|
+
* and an old or damaged one is not a reason to fail the whole listing.
|
|
138
|
+
*/
|
|
139
|
+
async function parentTurnFirstWords(scope, parentRunId) {
|
|
140
|
+
try {
|
|
141
|
+
const runDir = join(scope.sessionsRoot, scope.sessionId, 'runs', parentRunId);
|
|
142
|
+
const snapshot = await readRunMessagesIn(runDir);
|
|
143
|
+
const messages = snapshot.kind === 'unavailable' ? [] : snapshot.messages;
|
|
144
|
+
const first = messages.find((message) => message.role === 'user' && message.source === undefined);
|
|
145
|
+
return first?.role === 'user' ? first.content : undefined;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
scope.log?.warn('A saved parent turn could not be read for its name', {
|
|
149
|
+
'namzu.subagent.runs.parent_run_id': parentRunId,
|
|
150
|
+
'namzu.subagent.runs.error': error instanceof Error ? error.message : String(error),
|
|
151
|
+
});
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../../src/integrations/subagents/runs.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,17 @@
|
|
|
16
16
|
import { type AgentFileDefinition, type AuthorizationGateConfig, CompletionInbox, type LLMProvider, type PathBuilder, type Project, type ProjectInstructionContext, type ReactiveAgentConfig, type ReasoningEffort, type ResumeHandler, type RunEvent, type RunId, type SandboxProvider, type SessionId, type TaskScheduler, type ToolContext, type ToolDefinition, type ToolRegistryContract, type Topic } from '@namzu/sdk';
|
|
17
17
|
import type { RunLimitsConfig } from '../../config/schema.js';
|
|
18
18
|
import { type SubagentActivitySource } from './activity.js';
|
|
19
|
+
/**
|
|
20
|
+
* The parent's narration tool, named once.
|
|
21
|
+
*
|
|
22
|
+
* Exported because a second surface reads the name: the TUI drops the
|
|
23
|
+
* transcript row for a SUCCESSFUL call, since the line it wrote is already on
|
|
24
|
+
* screen above the rail and a row repeating it would print the sentence
|
|
25
|
+
* twice, the second time as protocol. A literal spelled in both places would
|
|
26
|
+
* drift the moment either is renamed, and the symptom would be a duplicated
|
|
27
|
+
* sentence rather than an error.
|
|
28
|
+
*/
|
|
29
|
+
export declare const NARRATION_TOOL_NAME = "narrate_work";
|
|
19
30
|
export declare const GENERAL_PURPOSE_SUBAGENT = "general-purpose";
|
|
20
31
|
/**
|
|
21
32
|
* The kernel's read-only delegate, with this application's doctrine under
|
|
@@ -112,6 +123,16 @@ export interface SubagentRuntime {
|
|
|
112
123
|
/** Queue a correction for an owned task that has not finished. */
|
|
113
124
|
readonly sendMessageTool: ToolDefinition;
|
|
114
125
|
readonly cancelAgentTool: ToolDefinition;
|
|
126
|
+
/**
|
|
127
|
+
* Write one line of commentary above the agent rail.
|
|
128
|
+
*
|
|
129
|
+
* Registered on the PARENT's registry only, like every other tool here, and
|
|
130
|
+
* only by a host that has an operator watching — see `createAgentSession`.
|
|
131
|
+
* A child's roster is whatever the host's `buildTools()` returns, which
|
|
132
|
+
* never carries this one: that is what makes narration the run's own voice
|
|
133
|
+
* rather than a child's, and the property a test holds.
|
|
134
|
+
*/
|
|
135
|
+
readonly narrationTool: ToolDefinition;
|
|
115
136
|
readonly allowedAgentIds: readonly string[];
|
|
116
137
|
/** Live, bounded observation of children created by this CLI session. */
|
|
117
138
|
readonly activity: SubagentActivitySource;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAGN,KAAK,mBAAmB,EAIxB,KAAK,uBAAuB,EAI5B,eAAe,EASf,KAAK,WAAW,EAEhB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,yBAAyB,EAE9B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAElB,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,SAAS,EAId,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAEzB,KAAK,KAAK,EAcV,MAAM,YAAY,CAAA;AAGnB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAE7D,OAAO,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runtime.ts"],"names":[],"mappings":"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"}
|