pi-subagents 0.40.0 → 0.41.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 +76 -0
- package/README.md +246 -525
- package/agents/oracle.md +1 -0
- package/package.json +12 -4
- package/prompts/parallel-context-build.md +1 -1
- package/prompts/parallel-handoff-plan.md +1 -1
- package/prompts/review-loop.md +1 -1
- package/skills/pi-subagents/SKILL.md +6 -6
- package/skills/pi-subagents/references/constraints-and-recipes.md +19 -26
- package/skills/pi-subagents/references/execution-controls.md +98 -97
- package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
- package/skills/pi-subagents/references/prompting-and-roles.md +18 -27
- package/src/agents/agent-management.ts +155 -65
- package/src/agents/agent-serializer.ts +19 -0
- package/src/agents/agents.ts +154 -71
- package/src/agents/chain-serializer.ts +10 -7
- package/src/agents/frontmatter.ts +5 -3
- package/src/agents/identity.ts +1 -1
- package/src/agents/proactive-skills.ts +13 -10
- package/src/agents/skills.ts +23 -6
- package/src/api/control-channel.ts +4 -0
- package/src/api/delegation.ts +26 -194
- package/src/api/external-runs.ts +129 -0
- package/src/api/intercom-bridge.ts +3 -0
- package/src/api/pi-args.ts +5 -0
- package/src/api/preflight.ts +3 -3
- package/src/api/shared-types.ts +19 -0
- package/src/extension/config.ts +10 -0
- package/src/extension/control-notices.ts +5 -39
- package/src/extension/doctor.ts +10 -9
- package/src/extension/fanout-child.ts +7 -4
- package/src/extension/index.ts +232 -68
- package/src/extension/rpc.ts +18 -12
- package/src/extension/schemas.ts +48 -37
- package/src/extension/tool-description.ts +36 -86
- package/src/inspectors/herdr/actions.ts +229 -0
- package/src/inspectors/herdr/client.ts +130 -0
- package/src/inspectors/herdr/inspector-runner.ts +141 -0
- package/src/inspectors/herdr/project-panes.ts +154 -0
- package/src/integrations/herdr-status.ts +330 -0
- package/src/intercom/intercom-bridge.ts +3 -2
- package/src/intercom/result-intercom.ts +5 -1
- package/src/missions/actions.ts +372 -0
- package/src/missions/lifecycle.ts +314 -0
- package/src/missions/store.ts +442 -0
- package/src/missions/types.ts +135 -0
- package/src/policy/authority.ts +46 -0
- package/src/profiles/profiles.ts +29 -3
- package/src/runs/background/async-execution.ts +98 -49
- package/src/runs/background/async-job-tracker.ts +10 -2
- package/src/runs/background/async-resume.ts +6 -6
- package/src/runs/background/async-status.ts +29 -1
- package/src/runs/background/auto-drain.ts +3 -3
- package/src/runs/background/chain-append.ts +3 -2
- package/src/runs/background/control-channel.ts +9 -7
- package/src/runs/background/fleet-view.ts +3 -4
- package/src/runs/background/notify.ts +2 -1
- package/src/runs/background/process-terminal.ts +5 -5
- package/src/runs/background/result-watcher.ts +13 -5
- package/src/runs/background/run-id-resolver.ts +3 -3
- package/src/runs/background/run-status.ts +35 -8
- package/src/runs/background/scheduled-runs.ts +602 -375
- package/src/runs/background/stale-run-reconciler.ts +3 -3
- package/src/runs/background/subagent-runner.ts +608 -445
- package/src/runs/background/subagent-wait.ts +50 -9
- package/src/runs/background/wait-subscriptions.ts +253 -0
- package/src/runs/background/wait-tool.ts +12 -4
- package/src/runs/foreground/async-steering-action.ts +3 -3
- package/src/runs/foreground/chain-clarify.ts +8 -4
- package/src/runs/foreground/chain-execution.ts +56 -30
- package/src/runs/foreground/execution.ts +15 -2
- package/src/runs/foreground/subagent-executor.ts +1023 -273
- package/src/runs/shared/acceptance.ts +28 -6
- package/src/runs/shared/child-protocol.ts +302 -22
- package/src/runs/shared/dynamic-fanout.ts +1 -1
- package/src/runs/shared/external-cli-runner.ts +130 -0
- package/src/runs/shared/long-running-guard.ts +42 -1
- package/src/runs/shared/nested-events.ts +59 -5
- package/src/runs/shared/nested-render.ts +9 -4
- package/src/runs/shared/parallel-handoff.ts +86 -2
- package/src/runs/shared/parallel-utils.ts +11 -2
- package/src/runs/shared/permissions.ts +95 -0
- package/src/runs/shared/pi-args.ts +11 -1
- package/src/runs/shared/pi-spawn.ts +11 -1
- package/src/runs/shared/run-history.ts +1 -1
- package/src/runs/shared/subagent-prompt-runtime.ts +36 -5
- package/src/runs/shared/subagent-startup-retry.ts +5 -2
- package/src/runs/shared/turn-budget.ts +6 -6
- package/src/runs/shared/worktree.ts +122 -12
- package/src/shared/accessible-dir.ts +29 -7
- package/src/shared/artifacts.ts +18 -1
- package/src/shared/fork-context.ts +3 -2
- package/src/shared/launch-contract.ts +1 -0
- package/src/shared/settings.ts +10 -0
- package/src/shared/types.ts +156 -14
- package/src/shared/utils.ts +8 -6
- package/src/slash/delegation-adapters.ts +32 -194
- package/src/slash/delegation-request.ts +43 -126
- package/src/slash/prompt-template-bridge.ts +158 -205
- package/src/slash/prompt-workflows.ts +21 -57
- package/src/slash/slash-bridge.ts +14 -0
- package/src/slash/slash-commands.ts +31 -632
- package/src/slash/subagents-admin.ts +18 -14
- package/src/tui/fleet-status.ts +156 -21
- package/src/tui/fleet-transcript.ts +110 -5
- package/src/tui/fleet.ts +56 -24
- package/src/tui/render.ts +291 -109
- package/src/types/pi-runtime-compat.d.ts +14 -0
- package/src/watchdog/lsp-diagnostics.ts +12 -7
- package/src/watchdog/model-selection.ts +2 -2
- package/src/watchdog/permission-arbiter.ts +145 -0
- package/src/watchdog/register-child.ts +1 -1
- package/src/watchdog/register-main.ts +1 -1
- package/src/watchdog/review.ts +4 -1
- package/src/watchdog/runtime.ts +3 -2
- package/src/workflows/chat-progress.ts +140 -0
- package/src/workflows/scripted-workflow.ts +415 -0
- package/agents/advisor.md +0 -73
- package/src/extension/chain-validation.ts +0 -181
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SUBAGENT_ASYNC_COMPLETE_EVENT,
|
|
3
|
+
SUBAGENT_ASYNC_STARTED_EVENT,
|
|
4
|
+
SUBAGENT_CONTROL_EVENT,
|
|
5
|
+
} from "../shared/types.ts";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_SOURCE = "pi-subagents:herdr";
|
|
8
|
+
const DEFAULT_TTL_MS = 120_000;
|
|
9
|
+
const DEFAULT_REFRESH_MS = 45_000;
|
|
10
|
+
|
|
11
|
+
let metadataReportSeq = Date.now() * 1000;
|
|
12
|
+
|
|
13
|
+
function nextMetadataReportSeq(): number {
|
|
14
|
+
metadataReportSeq = Math.max(metadataReportSeq + 1, Date.now() * 1000);
|
|
15
|
+
return metadataReportSeq;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface HerdrStatusBridgeEvents {
|
|
19
|
+
on(event: string, handler: (data: unknown) => void): (() => void) | void;
|
|
20
|
+
emit(event: string, data: unknown): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface HerdrStatusRun {
|
|
24
|
+
id: string;
|
|
25
|
+
agent?: string;
|
|
26
|
+
agents?: string[];
|
|
27
|
+
needsAttention?: boolean;
|
|
28
|
+
attentionLabel?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface HerdrStatusBridgeOptions {
|
|
32
|
+
events: HerdrStatusBridgeEvents;
|
|
33
|
+
env?: Record<string, string | undefined>;
|
|
34
|
+
/** Current authoritative active-run projection, used before TTL refresh. */
|
|
35
|
+
getRuns?: () => Iterable<HerdrStatusRun>;
|
|
36
|
+
runHerdr: (args: readonly string[]) => void | Promise<void>;
|
|
37
|
+
ttlMs?: number;
|
|
38
|
+
refreshMs?: number;
|
|
39
|
+
timers?: {
|
|
40
|
+
setInterval: typeof setInterval;
|
|
41
|
+
clearInterval: typeof clearInterval;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface HerdrStatusBridge {
|
|
46
|
+
/**
|
|
47
|
+
* Binds the pane owner. Only the root interactive session may publish pane
|
|
48
|
+
* metadata: headless parents (print/json), non-UI harnesses, and child
|
|
49
|
+
* runtimes must never fight the pane's lifecycle authority over display
|
|
50
|
+
* state. Also re-syncs runs that survived a reload/resume.
|
|
51
|
+
*/
|
|
52
|
+
sessionStarted(input: { hasUI: boolean; runs: Iterable<HerdrStatusRun> }): void;
|
|
53
|
+
agentStarted(): void;
|
|
54
|
+
flush(): Promise<void>;
|
|
55
|
+
dispose(): void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
59
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function startedRun(data: unknown): HerdrStatusRun | undefined {
|
|
63
|
+
if (!isRecord(data) || typeof data.id !== "string" || !data.id) return undefined;
|
|
64
|
+
return {
|
|
65
|
+
id: data.id,
|
|
66
|
+
...(typeof data.agent === "string" ? { agent: data.agent } : {}),
|
|
67
|
+
...(Array.isArray(data.agents) && data.agents.every((agent) => typeof agent === "string") ? { agents: data.agents as string[] } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function completedRunId(data: unknown): string | undefined {
|
|
72
|
+
if (!isRecord(data)) return undefined;
|
|
73
|
+
const id = typeof data.runId === "string" ? data.runId : data.id;
|
|
74
|
+
return typeof id === "string" && id.length > 0 ? id : undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function attentionNotice(data: unknown): { runId: string; label: string } | undefined {
|
|
78
|
+
if (!isRecord(data) || data.source !== "async" || !isRecord(data.event)) return undefined;
|
|
79
|
+
if (data.event.type !== "needs_attention" || typeof data.event.runId !== "string" || !data.event.runId) return undefined;
|
|
80
|
+
const label = typeof data.noticeText === "string" && data.noticeText
|
|
81
|
+
? data.noticeText
|
|
82
|
+
: typeof data.event.message === "string" && data.event.message
|
|
83
|
+
? data.event.message
|
|
84
|
+
: "subagent needs attention";
|
|
85
|
+
return { runId: data.event.runId, label };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function registerHerdrStatusBridge(options: HerdrStatusBridgeOptions): HerdrStatusBridge {
|
|
89
|
+
const env = options.env ?? process.env;
|
|
90
|
+
const paneId = env.HERDR_PANE_ID;
|
|
91
|
+
const enabled = env.HERDR_ENV === "1" && typeof paneId === "string" && paneId.length > 0;
|
|
92
|
+
const runHerdr = options.runHerdr;
|
|
93
|
+
const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
94
|
+
const refreshMs = options.refreshMs ?? DEFAULT_REFRESH_MS;
|
|
95
|
+
const timers = options.timers ?? { setInterval, clearInterval };
|
|
96
|
+
const runs = new Map<string, HerdrStatusRun>();
|
|
97
|
+
const attentionLabels = new Map<string, string>();
|
|
98
|
+
const acknowledgedAttention = new Set<string>();
|
|
99
|
+
const subscriptions: Array<() => void> = [];
|
|
100
|
+
let rootSession = false;
|
|
101
|
+
let published = false;
|
|
102
|
+
let busyRaised = false;
|
|
103
|
+
let busyLabel: string | undefined;
|
|
104
|
+
let blockedRaised = false;
|
|
105
|
+
let blockedLabel: string | undefined;
|
|
106
|
+
let disposed = false;
|
|
107
|
+
let pendingReport: readonly string[] | undefined;
|
|
108
|
+
let draining = false;
|
|
109
|
+
let drainPromise = Promise.resolve();
|
|
110
|
+
let refreshTimer: ReturnType<typeof setInterval> | undefined;
|
|
111
|
+
|
|
112
|
+
const label = (): string => {
|
|
113
|
+
const agents = [...new Set([...runs.values()].flatMap((run) => run.agents?.length ? run.agents : run.agent ? [run.agent] : []))];
|
|
114
|
+
const who = agents.length > 0
|
|
115
|
+
? ` (${agents.slice(0, 3).join(", ")}${agents.length > 3 ? ", …" : ""})`
|
|
116
|
+
: "";
|
|
117
|
+
return `⏳ ${runs.size} subagent${runs.size === 1 ? "" : "s"}${who}`;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const enqueue = (args: readonly string[]): void => {
|
|
121
|
+
pendingReport = args;
|
|
122
|
+
if (draining) return;
|
|
123
|
+
draining = true;
|
|
124
|
+
drainPromise = (async () => {
|
|
125
|
+
while (pendingReport) {
|
|
126
|
+
const next = pendingReport;
|
|
127
|
+
pendingReport = undefined;
|
|
128
|
+
try {
|
|
129
|
+
await runHerdr(next);
|
|
130
|
+
} catch {
|
|
131
|
+
// Herdr integration is best effort; a later state transition or TTL
|
|
132
|
+
// refresh retries with the newest desired snapshot.
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
})().finally(() => {
|
|
136
|
+
draining = false;
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const publish = (): void => {
|
|
141
|
+
if (!enabled || !rootSession || disposed || !paneId) return;
|
|
142
|
+
if (runs.size === 0 && !published) return;
|
|
143
|
+
const seq = String(nextMetadataReportSeq());
|
|
144
|
+
if (runs.size === 0) {
|
|
145
|
+
published = false;
|
|
146
|
+
enqueue([
|
|
147
|
+
"pane", "report-metadata", paneId,
|
|
148
|
+
"--source", DEFAULT_SOURCE,
|
|
149
|
+
"--agent", "pi",
|
|
150
|
+
"--applies-to-source", "herdr:pi",
|
|
151
|
+
"--clear-state-labels",
|
|
152
|
+
"--clear-token", "summary",
|
|
153
|
+
"--seq", seq,
|
|
154
|
+
]);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const text = label();
|
|
158
|
+
published = true;
|
|
159
|
+
enqueue([
|
|
160
|
+
"pane", "report-metadata", paneId,
|
|
161
|
+
"--source", DEFAULT_SOURCE,
|
|
162
|
+
"--agent", "pi",
|
|
163
|
+
"--applies-to-source", "herdr:pi",
|
|
164
|
+
"--state-label", `idle=${text}`,
|
|
165
|
+
"--state-label", `done=${text}`,
|
|
166
|
+
"--state-label", `working=${text}`,
|
|
167
|
+
"--token", `summary=${text}`,
|
|
168
|
+
"--ttl-ms", String(ttlMs),
|
|
169
|
+
"--seq", seq,
|
|
170
|
+
]);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const syncRefreshTimer = (): void => {
|
|
174
|
+
if (runs.size > 0 && refreshMs > 0 && !refreshTimer) {
|
|
175
|
+
refreshTimer = timers.setInterval(() => refresh(), refreshMs);
|
|
176
|
+
refreshTimer.unref?.();
|
|
177
|
+
} else if ((runs.size === 0 || refreshMs <= 0) && refreshTimer) {
|
|
178
|
+
timers.clearInterval(refreshTimer);
|
|
179
|
+
refreshTimer = undefined;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const syncBusy = (): void => {
|
|
184
|
+
if (!enabled || !rootSession || disposed) return;
|
|
185
|
+
if (runs.size > 0) {
|
|
186
|
+
const text = label();
|
|
187
|
+
if (busyRaised && busyLabel === text) return;
|
|
188
|
+
if (busyRaised) options.events.emit("herdr:busy", { active: false });
|
|
189
|
+
busyRaised = true;
|
|
190
|
+
busyLabel = text;
|
|
191
|
+
options.events.emit("herdr:busy", { active: true, label: text });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (busyRaised) {
|
|
195
|
+
busyRaised = false;
|
|
196
|
+
busyLabel = undefined;
|
|
197
|
+
options.events.emit("herdr:busy", { active: false });
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const syncBlocked = (): void => {
|
|
202
|
+
if (!enabled || !rootSession || disposed) return;
|
|
203
|
+
const nextLabel = [...attentionLabels.values()].at(-1);
|
|
204
|
+
if (nextLabel !== undefined) {
|
|
205
|
+
if (blockedRaised && blockedLabel === nextLabel) return;
|
|
206
|
+
// Herdr's sibling overlay contract is counted. Lower before changing
|
|
207
|
+
// the active label so this bridge continues to own exactly one count.
|
|
208
|
+
if (blockedRaised) options.events.emit("herdr:blocked", { active: false });
|
|
209
|
+
blockedRaised = true;
|
|
210
|
+
blockedLabel = nextLabel;
|
|
211
|
+
options.events.emit("herdr:blocked", { active: true, label: nextLabel });
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (blockedRaised) {
|
|
215
|
+
blockedRaised = false;
|
|
216
|
+
blockedLabel = undefined;
|
|
217
|
+
options.events.emit("herdr:blocked", { active: false });
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const clearAttention = (): void => {
|
|
222
|
+
attentionLabels.clear();
|
|
223
|
+
syncBlocked();
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const raiseAttention = (runId: string, labelText: string): void => {
|
|
227
|
+
if (!rootSession || attentionLabels.has(runId)) return;
|
|
228
|
+
acknowledgedAttention.delete(runId);
|
|
229
|
+
attentionLabels.set(runId, labelText);
|
|
230
|
+
syncBlocked();
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const replaceRuns = (nextRuns: Iterable<HerdrStatusRun>): void => {
|
|
234
|
+
const nextAttention = new Map<string, string>();
|
|
235
|
+
const activeIds = new Set<string>();
|
|
236
|
+
runs.clear();
|
|
237
|
+
for (const run of nextRuns) {
|
|
238
|
+
if (!run || typeof run.id !== "string" || !run.id) continue;
|
|
239
|
+
activeIds.add(run.id);
|
|
240
|
+
runs.set(run.id, { ...run });
|
|
241
|
+
if (!run.needsAttention) {
|
|
242
|
+
acknowledgedAttention.delete(run.id);
|
|
243
|
+
} else if (!acknowledgedAttention.has(run.id)) {
|
|
244
|
+
nextAttention.set(run.id, run.attentionLabel || attentionLabels.get(run.id) || "subagent needs attention");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const id of acknowledgedAttention) {
|
|
248
|
+
if (!activeIds.has(id)) acknowledgedAttention.delete(id);
|
|
249
|
+
}
|
|
250
|
+
attentionLabels.clear();
|
|
251
|
+
for (const [id, labelText] of nextAttention) attentionLabels.set(id, labelText);
|
|
252
|
+
syncBusy();
|
|
253
|
+
syncRefreshTimer();
|
|
254
|
+
syncBlocked();
|
|
255
|
+
publish();
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const refresh = (): void => {
|
|
259
|
+
if (!options.getRuns) {
|
|
260
|
+
publish();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
replaceRuns(options.getRuns());
|
|
265
|
+
} catch {
|
|
266
|
+
// Keep the last known active projection and retry on the next refresh.
|
|
267
|
+
publish();
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const subscribe = (event: string, handler: (data: unknown) => void): void => {
|
|
272
|
+
const unsubscribe = options.events.on(event, handler);
|
|
273
|
+
if (typeof unsubscribe === "function") subscriptions.push(unsubscribe);
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
if (enabled) {
|
|
277
|
+
subscribe(SUBAGENT_ASYNC_STARTED_EVENT, (data) => {
|
|
278
|
+
if (!rootSession) return;
|
|
279
|
+
const run = startedRun(data);
|
|
280
|
+
if (!run) return;
|
|
281
|
+
acknowledgedAttention.delete(run.id);
|
|
282
|
+
runs.set(run.id, run);
|
|
283
|
+
syncBusy();
|
|
284
|
+
syncRefreshTimer();
|
|
285
|
+
publish();
|
|
286
|
+
});
|
|
287
|
+
subscribe(SUBAGENT_ASYNC_COMPLETE_EVENT, (data) => {
|
|
288
|
+
if (!rootSession) return;
|
|
289
|
+
const id = completedRunId(data);
|
|
290
|
+
if (!id || !runs.delete(id)) return;
|
|
291
|
+
acknowledgedAttention.delete(id);
|
|
292
|
+
if (attentionLabels.delete(id)) syncBlocked();
|
|
293
|
+
syncBusy();
|
|
294
|
+
syncRefreshTimer();
|
|
295
|
+
publish();
|
|
296
|
+
});
|
|
297
|
+
subscribe(SUBAGENT_CONTROL_EVENT, (data) => {
|
|
298
|
+
if (!rootSession) return;
|
|
299
|
+
const notice = attentionNotice(data);
|
|
300
|
+
if (!notice || !runs.has(notice.runId)) return;
|
|
301
|
+
raiseAttention(notice.runId, notice.label);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
agentStarted() {
|
|
307
|
+
for (const id of attentionLabels.keys()) acknowledgedAttention.add(id);
|
|
308
|
+
clearAttention();
|
|
309
|
+
},
|
|
310
|
+
sessionStarted({ hasUI, runs: restoredRuns }) {
|
|
311
|
+
if (!enabled || disposed || hasUI !== true) return;
|
|
312
|
+
rootSession = true;
|
|
313
|
+
replaceRuns(restoredRuns);
|
|
314
|
+
},
|
|
315
|
+
async flush() {
|
|
316
|
+
while (draining || pendingReport) await drainPromise;
|
|
317
|
+
},
|
|
318
|
+
dispose() {
|
|
319
|
+
if (disposed) return;
|
|
320
|
+
clearAttention();
|
|
321
|
+
acknowledgedAttention.clear();
|
|
322
|
+
runs.clear();
|
|
323
|
+
syncBusy();
|
|
324
|
+
syncRefreshTimer();
|
|
325
|
+
publish();
|
|
326
|
+
for (const unsubscribe of subscriptions) unsubscribe();
|
|
327
|
+
disposed = true;
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
}
|
|
@@ -53,6 +53,7 @@ interface ResolveIntercomBridgeInput {
|
|
|
53
53
|
config: ExtensionConfig["intercomBridge"];
|
|
54
54
|
context: "fresh" | "fork" | undefined;
|
|
55
55
|
orchestratorTarget?: string;
|
|
56
|
+
cwd?: string;
|
|
56
57
|
settingsDir?: string;
|
|
57
58
|
agentDir?: string;
|
|
58
59
|
}
|
|
@@ -81,12 +82,12 @@ export function resolveIntercomBridgeMode(value: unknown): IntercomBridgeMode {
|
|
|
81
82
|
|
|
82
83
|
function resolveIntercomBridgeConfig(value: ExtensionConfig["intercomBridge"]): Required<IntercomBridgeConfig> {
|
|
83
84
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
84
|
-
return { mode: "always", instructionFile: "", resultDelivery:
|
|
85
|
+
return { mode: "always", instructionFile: "", resultDelivery: false };
|
|
85
86
|
}
|
|
86
87
|
return {
|
|
87
88
|
mode: resolveIntercomBridgeMode(value.mode),
|
|
88
89
|
instructionFile: typeof value.instructionFile === "string" ? value.instructionFile : "",
|
|
89
|
-
resultDelivery: value.resultDelivery
|
|
90
|
+
resultDelivery: value.resultDelivery === true,
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
93
|
|
|
@@ -113,6 +113,8 @@ function compactNestedRun(run: NestedRunSummary | PublicNestedRunSummary, depth
|
|
|
113
113
|
state: run.state,
|
|
114
114
|
...(run.agent ? { agent: run.agent } : {}),
|
|
115
115
|
...(run.agents?.length ? { agents: run.agents.slice(0, 12) } : {}),
|
|
116
|
+
...(run.model ? { model: run.model } : {}),
|
|
117
|
+
...(run.thinking ? { thinking: run.thinking } : {}),
|
|
116
118
|
...(run.currentStep !== undefined ? { currentStep: run.currentStep } : {}),
|
|
117
119
|
...(run.chainStepCount !== undefined ? { chainStepCount: run.chainStepCount } : {}),
|
|
118
120
|
...(run.parallelGroups?.length ? { parallelGroups: run.parallelGroups.slice(0, 8) } : {}),
|
|
@@ -131,6 +133,8 @@ function compactNestedRun(run: NestedRunSummary | PublicNestedRunSummary, depth
|
|
|
131
133
|
...(run.steps?.length ? { steps: run.steps.slice(0, 12).map((step) => ({
|
|
132
134
|
agent: step.agent,
|
|
133
135
|
status: step.status,
|
|
136
|
+
...(step.model ? { model: step.model } : {}),
|
|
137
|
+
...(step.thinking ? { thinking: step.thinking } : {}),
|
|
134
138
|
...(step.sessionFile ? { sessionFile: step.sessionFile } : {}),
|
|
135
139
|
...(step.activityState ? { activityState: step.activityState } : {}),
|
|
136
140
|
...(step.lastActivityAt !== undefined ? { lastActivityAt: step.lastActivityAt } : {}),
|
|
@@ -315,7 +319,7 @@ export async function deliverSubagentResultIntercomEvent(
|
|
|
315
319
|
payload: SubagentResultIntercomPayload,
|
|
316
320
|
timeoutMs = 500,
|
|
317
321
|
): Promise<boolean> {
|
|
318
|
-
return deliverSubagentIntercomMessageEvent(events, payload.to, payload.message, timeoutMs, payload);
|
|
322
|
+
return deliverSubagentIntercomMessageEvent(events, payload.to, payload.message, timeoutMs, payload as unknown as Record<string, unknown>);
|
|
319
323
|
}
|
|
320
324
|
|
|
321
325
|
export async function deliverSubagentIntercomMessageEvent(
|