@kenkaiiii/ggcoder 5.15.1 → 5.17.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/assets/end-notification.mp3 +0 -0
- package/assets/skills/evidence-led-ui/LICENSES.md +68 -0
- package/assets/skills/evidence-led-ui/SKILL.md +139 -0
- package/{LICENSE → assets/skills/evidence-led-ui/corpus/awesome-design-md/LICENSE} +1 -1
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/airbnb/DESIGN.md +545 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/airtable/DESIGN.md +554 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/apple/DESIGN.md +562 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/binance/DESIGN.md +634 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/bmw/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/bmw-m/DESIGN.md +503 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/bugatti/DESIGN.md +454 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/cal/DESIGN.md +542 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/claude/DESIGN.md +589 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/clay/DESIGN.md +541 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/clickhouse/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/cohere/DESIGN.md +451 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/coinbase/DESIGN.md +570 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/composio/DESIGN.md +506 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/cursor/DESIGN.md +537 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/dell-1996/DESIGN.md +632 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/elevenlabs/DESIGN.md +504 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/expo/DESIGN.md +526 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/ferrari/DESIGN.md +531 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/figma/DESIGN.md +578 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/framer/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/hashicorp/DESIGN.md +575 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/hp/DESIGN.md +670 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/ibm/DESIGN.md +550 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/intercom/DESIGN.md +546 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/kraken/DESIGN.md +125 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/lamborghini/DESIGN.md +288 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/linear.app/DESIGN.md +548 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/lovable/DESIGN.md +298 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mastercard/DESIGN.md +365 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/meta/DESIGN.md +683 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/minimax/DESIGN.md +746 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mintlify/DESIGN.md +852 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/miro/DESIGN.md +825 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mistral.ai/DESIGN.md +773 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/mongodb/DESIGN.md +767 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/nike/DESIGN.md +575 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/nintendo-2001/DESIGN.md +649 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/notion/DESIGN.md +821 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/nvidia/DESIGN.md +640 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/ollama/DESIGN.md +539 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/opencode.ai/DESIGN.md +521 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/pinterest/DESIGN.md +597 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/playstation/DESIGN.md +661 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/posthog/DESIGN.md +690 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/raycast/DESIGN.md +669 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/renault/DESIGN.md +589 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/replicate/DESIGN.md +616 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/resend/DESIGN.md +585 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/revolut/DESIGN.md +636 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/runwayml/DESIGN.md +244 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/sanity/DESIGN.md +357 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/sentry/DESIGN.md +551 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/shopify/DESIGN.md +516 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/slack/DESIGN.md +482 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/spacex/DESIGN.md +363 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/spotify/DESIGN.md +246 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/starbucks/DESIGN.md +580 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/stripe/DESIGN.md +487 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/supabase/DESIGN.md +462 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/superhuman/DESIGN.md +448 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/tesla/DESIGN.md +286 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/theverge/DESIGN.md +339 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/together.ai/DESIGN.md +633 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/uber/DESIGN.md +636 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/vercel/DESIGN.md +736 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/vodafone/DESIGN.md +538 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/voltagent/DESIGN.md +521 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/warp/DESIGN.md +526 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/webflow/DESIGN.md +588 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/wired/DESIGN.md +497 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/wise/DESIGN.md +544 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/x.ai/DESIGN.md +465 -0
- package/assets/skills/evidence-led-ui/corpus/awesome-design-md/design-md/zapier/DESIGN.md +537 -0
- package/assets/skills/evidence-led-ui/data/corpus-manifest.json +768 -0
- package/assets/skills/evidence-led-ui/data/observations.json +47053 -0
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +203 -0
- package/assets/skills/evidence-led-ui/references/archetypes.md +97 -0
- package/assets/skills/evidence-led-ui/references/craft-rulings.md +167 -0
- package/assets/skills/evidence-led-ui/references/methodology.md +72 -0
- package/assets/skills/evidence-led-ui/references/observed-patterns.md +68 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +120 -0
- package/assets/skills/evidence-led-ui/references/provenance.md +117 -0
- package/assets/skills/evidence-led-ui/references/quality-rubric.md +126 -0
- package/dist/app-sidecar.js +161 -48
- package/dist/app-sidecar.js.map +1 -1
- package/dist/chat-agents/general.test.js +3 -0
- package/dist/chat-agents/general.test.js.map +1 -1
- package/dist/chat-agents/jiwa.d.ts +53 -0
- package/dist/chat-agents/jiwa.d.ts.map +1 -0
- package/dist/chat-agents/jiwa.js +352 -0
- package/dist/chat-agents/jiwa.js.map +1 -0
- package/dist/chat-agents/jiwa.test.d.ts +2 -0
- package/dist/chat-agents/jiwa.test.d.ts.map +1 -0
- package/dist/chat-agents/jiwa.test.js +66 -0
- package/dist/chat-agents/jiwa.test.js.map +1 -0
- package/dist/chat-agents/shared.d.ts.map +1 -1
- package/dist/chat-agents/shared.js +5 -1
- package/dist/chat-agents/shared.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session-review-coverage.test.d.ts +2 -0
- package/dist/core/agent-session-review-coverage.test.d.ts.map +1 -0
- package/dist/core/agent-session-review-coverage.test.js +57 -0
- package/dist/core/agent-session-review-coverage.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +13 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +143 -38
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +1 -1
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/event-bus.d.ts +2 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/ideal-review.d.ts +27 -0
- package/dist/core/ideal-review.d.ts.map +1 -1
- package/dist/core/ideal-review.js +64 -0
- package/dist/core/ideal-review.js.map +1 -1
- package/dist/core/ideal-review.test.js +34 -1
- package/dist/core/ideal-review.test.js.map +1 -1
- package/dist/core/ken-prompt.d.ts +3 -3
- package/dist/core/ken-prompt.d.ts.map +1 -1
- package/dist/core/ken-prompt.js +10 -10
- package/dist/core/ken-prompt.js.map +1 -1
- package/dist/core/ken-prompt.test.js +17 -0
- package/dist/core/ken-prompt.test.js.map +1 -1
- package/dist/core/loop-breaker.d.ts +23 -16
- package/dist/core/loop-breaker.d.ts.map +1 -1
- package/dist/core/loop-breaker.js +52 -11
- package/dist/core/loop-breaker.js.map +1 -1
- package/dist/core/loop-breaker.test.js +37 -16
- package/dist/core/loop-breaker.test.js.map +1 -1
- package/dist/core/lsp/client.d.ts +3 -0
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +20 -0
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/manager.d.ts +32 -9
- package/dist/core/lsp/manager.d.ts.map +1 -1
- package/dist/core/lsp/manager.js +89 -37
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/manager.test.js +56 -4
- package/dist/core/lsp/manager.test.js.map +1 -1
- package/dist/core/run-lifecycle.d.ts +40 -0
- package/dist/core/run-lifecycle.d.ts.map +1 -0
- package/dist/core/run-lifecycle.js +95 -0
- package/dist/core/run-lifecycle.js.map +1 -0
- package/dist/core/run-lifecycle.test.d.ts +2 -0
- package/dist/core/run-lifecycle.test.d.ts.map +1 -0
- package/dist/core/run-lifecycle.test.js +64 -0
- package/dist/core/run-lifecycle.test.js.map +1 -0
- package/dist/core/session-manager.d.ts +25 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +66 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-manager.test.js +80 -2
- package/dist/core/session-manager.test.js.map +1 -1
- package/dist/core/skills-routing.test.d.ts +2 -0
- package/dist/core/skills-routing.test.d.ts.map +1 -0
- package/dist/core/skills-routing.test.js +70 -0
- package/dist/core/skills-routing.test.js.map +1 -0
- package/dist/core/skills.d.ts +2 -0
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +32 -9
- package/dist/core/skills.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +40 -3
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +342 -30
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +189 -3
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/core/subagent-store.d.ts +20 -0
- package/dist/core/subagent-store.d.ts.map +1 -0
- package/dist/core/subagent-store.js +177 -0
- package/dist/core/subagent-store.js.map +1 -0
- package/dist/core/subagent-store.test.d.ts +2 -0
- package/dist/core/subagent-store.test.d.ts.map +1 -0
- package/dist/core/subagent-store.test.js +94 -0
- package/dist/core/subagent-store.test.js.map +1 -0
- package/dist/modes/agent-home-mode.d.ts.map +1 -1
- package/dist/modes/agent-home-mode.js +10 -3
- package/dist/modes/agent-home-mode.js.map +1 -1
- package/dist/modes/serve-mode.d.ts.map +1 -1
- package/dist/modes/serve-mode.js +10 -3
- package/dist/modes/serve-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +13 -3
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/system-prompt.js +2 -2
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +3 -0
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +8 -3
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/tasks.d.ts +1 -1
- package/dist/tools/web-fetch.d.ts +1 -1
- package/dist/ui/App.d.ts +7 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +63 -17
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +1 -0
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +3 -3
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/Footer.test.d.ts +2 -0
- package/dist/ui/components/Footer.test.d.ts.map +1 -0
- package/dist/ui/components/Footer.test.js +16 -0
- package/dist/ui/components/Footer.test.js.map +1 -0
- package/dist/ui/components/SkillsOverlay.d.ts.map +1 -1
- package/dist/ui/components/SkillsOverlay.js +8 -3
- package/dist/ui/components/SkillsOverlay.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +8 -3
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +71 -26
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.test.js +27 -0
- package/dist/ui/hooks/useAgentLoop.test.js.map +1 -1
- package/dist/ui/hooks/useSessionPersistence.d.ts +4 -2
- package/dist/ui/hooks/useSessionPersistence.d.ts.map +1 -1
- package/dist/ui/hooks/useSessionPersistence.js +7 -1
- package/dist/ui/hooks/useSessionPersistence.js.map +1 -1
- package/dist/ui/render.d.ts +7 -0
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +4 -0
- package/dist/ui/render.js.map +1 -1
- package/package.json +6 -5
package/dist/core/skills.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { Provider, ThinkingLevel } from "@kenkaiiii/gg-ai";
|
|
1
|
+
import type { Message, Provider, ThinkingLevel } from "@kenkaiiii/gg-ai";
|
|
2
2
|
import type { AgentDefinition } from "./agents.js";
|
|
3
|
-
|
|
3
|
+
import { SubAgentStore } from "./subagent-store.js";
|
|
4
|
+
export type SubAgentState = "starting" | "running" | "completed" | "failed" | "interrupted" | "closed" | "reaped";
|
|
4
5
|
export interface SubAgentSnapshot {
|
|
5
6
|
agent_id: string;
|
|
6
7
|
task_name: string;
|
|
@@ -17,6 +18,13 @@ export interface SubAgentSnapshot {
|
|
|
17
18
|
};
|
|
18
19
|
output?: string;
|
|
19
20
|
error?: string;
|
|
21
|
+
agent_name?: string;
|
|
22
|
+
provider?: string;
|
|
23
|
+
model?: string;
|
|
24
|
+
child_session_id?: string;
|
|
25
|
+
child_session_path?: string;
|
|
26
|
+
collected?: boolean;
|
|
27
|
+
recovered?: boolean;
|
|
20
28
|
}
|
|
21
29
|
export interface SubAgentManagerOptions {
|
|
22
30
|
cwd: string;
|
|
@@ -29,40 +37,69 @@ export interface SubAgentManagerOptions {
|
|
|
29
37
|
onState?: (snapshot: SubAgentSnapshot) => void;
|
|
30
38
|
workerEntry?: string;
|
|
31
39
|
idleTimeoutMs?: number;
|
|
40
|
+
store?: SubAgentStore;
|
|
41
|
+
sessionRootDir?: string;
|
|
32
42
|
}
|
|
43
|
+
/** Shared pre-finalization hook used by both AgentSession and the Ink host. */
|
|
44
|
+
export declare function buildSubAgentCompletionFollowUp(manager: Pick<SubAgentManager, "completionGateMessage"> | undefined): Message[] | null;
|
|
33
45
|
export declare class SubAgentManager {
|
|
34
46
|
private readonly options;
|
|
35
47
|
private readonly workers;
|
|
36
48
|
private readonly snapshots;
|
|
37
49
|
private readonly listeners;
|
|
38
50
|
private shuttingDown;
|
|
51
|
+
private shutdownPromise?;
|
|
52
|
+
private readonly store;
|
|
53
|
+
private readonly sessionRootDir;
|
|
54
|
+
private parentSessionId?;
|
|
55
|
+
private persistQueue;
|
|
56
|
+
private persistPending;
|
|
57
|
+
private persistScheduled;
|
|
39
58
|
constructor(options: SubAgentManagerOptions);
|
|
59
|
+
/** Restore bounded history; dead in-flight workers become honestly interrupted. */
|
|
60
|
+
hydrate(parentSessionId: string): Promise<void>;
|
|
61
|
+
/** Rebind durable child history after parent compaction creates a continuation. */
|
|
62
|
+
rebindParentSession(parentSessionId: string): Promise<void>;
|
|
63
|
+
/** A genuinely new parent starts with no unrelated child history. */
|
|
64
|
+
resetParentSession(parentSessionId: string): Promise<void>;
|
|
65
|
+
waitForPersistence(): Promise<void>;
|
|
40
66
|
spawn(taskName: string, task: string, agentName?: string): Promise<SubAgentSnapshot>;
|
|
41
67
|
sendMessage(agentId: string, message: string): Promise<number>;
|
|
42
68
|
followup(agentId: string, task: string): Promise<SubAgentSnapshot>;
|
|
43
|
-
interrupt(agentId: string): Promise<SubAgentSnapshot>;
|
|
69
|
+
interrupt(agentId: string, collectResult?: boolean): Promise<SubAgentSnapshot>;
|
|
44
70
|
subscribe(listener: (snapshot: SubAgentSnapshot) => void): () => void;
|
|
45
71
|
list(): SubAgentSnapshot[];
|
|
46
72
|
wait(agentIds?: string[], condition?: "any" | "all", timeoutMs?: number): Promise<{
|
|
47
73
|
timed_out: boolean;
|
|
48
74
|
agents: SubAgentSnapshot[];
|
|
49
75
|
}>;
|
|
76
|
+
completionGate(): {
|
|
77
|
+
active: SubAgentSnapshot[];
|
|
78
|
+
uncollected: SubAgentSnapshot[];
|
|
79
|
+
unresolved: number;
|
|
80
|
+
};
|
|
81
|
+
completionGateMessage(): string | undefined;
|
|
50
82
|
interruptAll(): Promise<void>;
|
|
51
83
|
shutdownAll(): Promise<void>;
|
|
52
84
|
/** Synchronous process-exit fallback: terminate detached process groups immediately. */
|
|
53
85
|
shutdownAllNow(): void;
|
|
86
|
+
private markCollected;
|
|
87
|
+
private spawnWorkerProcess;
|
|
88
|
+
private respawnRecovered;
|
|
54
89
|
private attach;
|
|
55
90
|
private handleFrame;
|
|
56
91
|
private request;
|
|
57
92
|
private waitForChange;
|
|
58
93
|
private publish;
|
|
59
94
|
private snapshot;
|
|
95
|
+
private queuePersist;
|
|
60
96
|
private elapsed;
|
|
61
97
|
private activeCount;
|
|
62
98
|
private isActive;
|
|
63
99
|
private isTerminal;
|
|
64
100
|
private requireWorker;
|
|
65
101
|
private assertAvailable;
|
|
102
|
+
private assertChildSessionPath;
|
|
66
103
|
private createId;
|
|
67
104
|
private scheduleIdleReap;
|
|
68
105
|
private reapExcessIdle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-manager.d.ts","sourceRoot":"","sources":["../../src/core/subagent-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subagent-manager.d.ts","sourceRoot":"","sources":["../../src/core/subagent-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,aAAa,EAAgC,MAAM,qBAAqB,CAAC;AAalF,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,SAAS,GACT,WAAW,GACX,QAAQ,GACR,aAAa,GACb,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,QAAQ,CAAC;IAC5B,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,aAAa,GAAG,SAAS,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA4BD,+EAA+E;AAC/E,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,uBAAuB,CAAC,GAAG,SAAS,GAClE,OAAO,EAAE,GAAG,IAAI,CAGlB;AAED,qBAAa,eAAe;IAad,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmD;IAC7E,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAC,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,gBAAgB,CAAS;gBAEJ,OAAO,EAAE,sBAAsB;IAM5D,mFAAmF;IAC7E,OAAO,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CrD,mFAAmF;IAC7E,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjE,qEAAqE;IAC/D,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1D,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqFpF,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO9D,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0BlE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,UAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWjF,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,MAAM,IAAI;IAKrE,IAAI,IAAI,gBAAgB,EAAE;IAMpB,IAAI,CACR,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,SAAS,GAAE,KAAK,GAAG,KAAa,EAChC,SAAS,SAAkB,GAC1B,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,gBAAgB,EAAE,CAAA;KAAE,CAAC;IA6C9D,cAAc,IAAI;QAChB,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAC3B,WAAW,EAAE,gBAAgB,EAAE,CAAC;QAChC,UAAU,EAAE,MAAM,CAAC;KACpB;IASD,qBAAqB,IAAI,MAAM,GAAG,SAAS;IAgBrC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAU7B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAUlC,wFAAwF;IACxF,cAAc,IAAI,IAAI;IAKtB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,kBAAkB;YAaZ,gBAAgB;IAuE9B,OAAO,CAAC,MAAM;IA+Bd,OAAO,CAAC,WAAW;IAkDnB,OAAO,CAAC,OAAO;IAgBf,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,YAAY;IAiCpB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,IAAI;YAcE,KAAK;IAyBnB,OAAO,CAAC,IAAI;CAyBb"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { createInterface } from "node:readline";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { getAppPaths } from "@kenkaiiii/gg-core";
|
|
6
|
+
import { SubAgentStore } from "./subagent-store.js";
|
|
7
|
+
import { SessionManager } from "./session-manager.js";
|
|
8
|
+
import { log } from "./logger.js";
|
|
4
9
|
import { boundSubAgentOutput, childSubAgentEnv, childThinkingLevel, resolveSubAgentCliEntry, selectSubAgent, subAgentCacheKey, SUB_AGENT_MAX_STDERR_CHARS, } from "../tools/subagent-shared.js";
|
|
5
10
|
const ACTIVE_LIMIT = 4;
|
|
6
11
|
const RETAINED_WORKER_LIMIT = 8;
|
|
@@ -13,14 +18,94 @@ function activity(name, args) {
|
|
|
13
18
|
const value = Object.values(args).find((candidate) => typeof candidate === "string");
|
|
14
19
|
return value ? `${name}: ${String(value).slice(0, 60)}` : name;
|
|
15
20
|
}
|
|
21
|
+
/** Shared pre-finalization hook used by both AgentSession and the Ink host. */
|
|
22
|
+
export function buildSubAgentCompletionFollowUp(manager) {
|
|
23
|
+
const message = manager?.completionGateMessage();
|
|
24
|
+
return message ? [{ role: "user", content: message }] : null;
|
|
25
|
+
}
|
|
16
26
|
export class SubAgentManager {
|
|
17
27
|
options;
|
|
18
28
|
workers = new Map();
|
|
19
29
|
snapshots = new Map();
|
|
20
30
|
listeners = new Set();
|
|
21
31
|
shuttingDown = false;
|
|
32
|
+
shutdownPromise;
|
|
33
|
+
store;
|
|
34
|
+
sessionRootDir;
|
|
35
|
+
parentSessionId;
|
|
36
|
+
persistQueue = Promise.resolve();
|
|
37
|
+
persistPending = false;
|
|
38
|
+
persistScheduled = false;
|
|
22
39
|
constructor(options) {
|
|
23
40
|
this.options = options;
|
|
41
|
+
const paths = getAppPaths();
|
|
42
|
+
this.store = options.store ?? new SubAgentStore(paths.subagentsDir);
|
|
43
|
+
this.sessionRootDir = options.sessionRootDir ?? paths.subagentSessionsDir;
|
|
44
|
+
}
|
|
45
|
+
/** Restore bounded history; dead in-flight workers become honestly interrupted. */
|
|
46
|
+
async hydrate(parentSessionId) {
|
|
47
|
+
if (this.workers.size > 0) {
|
|
48
|
+
await this.shutdownAll();
|
|
49
|
+
this.workers.clear();
|
|
50
|
+
this.shuttingDown = false;
|
|
51
|
+
this.shutdownPromise = undefined;
|
|
52
|
+
}
|
|
53
|
+
await this.waitForPersistence();
|
|
54
|
+
this.parentSessionId = parentSessionId;
|
|
55
|
+
this.snapshots.clear();
|
|
56
|
+
const records = await this.store.load(this.options.cwd, parentSessionId);
|
|
57
|
+
for (const persisted of records) {
|
|
58
|
+
const snapshot = {
|
|
59
|
+
...persisted,
|
|
60
|
+
...(persisted.state === "starting" || persisted.state === "running"
|
|
61
|
+
? {
|
|
62
|
+
state: "interrupted",
|
|
63
|
+
error: "Interrupted by process restart",
|
|
64
|
+
updated_at: Date.now(),
|
|
65
|
+
recovered: true,
|
|
66
|
+
}
|
|
67
|
+
: { recovered: true }),
|
|
68
|
+
};
|
|
69
|
+
this.snapshots.set(snapshot.agent_id, snapshot);
|
|
70
|
+
this.options.onState?.(snapshot);
|
|
71
|
+
for (const listener of this.listeners)
|
|
72
|
+
listener(snapshot);
|
|
73
|
+
}
|
|
74
|
+
this.queuePersist();
|
|
75
|
+
await this.waitForPersistence();
|
|
76
|
+
const referencedChildSessions = await this.store.listChildSessionPaths();
|
|
77
|
+
await new SessionManager(this.sessionRootDir)
|
|
78
|
+
.pruneOldSessions({
|
|
79
|
+
maxAgeDays: 30,
|
|
80
|
+
keepPaths: referencedChildSessions,
|
|
81
|
+
})
|
|
82
|
+
.catch((error) => {
|
|
83
|
+
log("WARN", "subagent", "Failed to prune old subagent sessions", {
|
|
84
|
+
error: error instanceof Error ? error.message : String(error),
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** Rebind durable child history after parent compaction creates a continuation. */
|
|
89
|
+
async rebindParentSession(parentSessionId) {
|
|
90
|
+
await this.waitForPersistence();
|
|
91
|
+
this.parentSessionId = parentSessionId;
|
|
92
|
+
this.queuePersist();
|
|
93
|
+
await this.persistQueue;
|
|
94
|
+
}
|
|
95
|
+
/** A genuinely new parent starts with no unrelated child history. */
|
|
96
|
+
async resetParentSession(parentSessionId) {
|
|
97
|
+
await this.shutdownAll();
|
|
98
|
+
await this.waitForPersistence();
|
|
99
|
+
this.shuttingDown = false;
|
|
100
|
+
this.shutdownPromise = undefined;
|
|
101
|
+
this.workers.clear();
|
|
102
|
+
this.snapshots.clear();
|
|
103
|
+
this.parentSessionId = parentSessionId;
|
|
104
|
+
this.queuePersist();
|
|
105
|
+
await this.persistQueue;
|
|
106
|
+
}
|
|
107
|
+
async waitForPersistence() {
|
|
108
|
+
await this.persistQueue;
|
|
24
109
|
}
|
|
25
110
|
async spawn(taskName, task, agentName) {
|
|
26
111
|
this.assertAvailable();
|
|
@@ -39,12 +124,7 @@ export class SubAgentManager {
|
|
|
39
124
|
throw new Error(`Unknown agent: "${agentName}"`);
|
|
40
125
|
const now = Date.now();
|
|
41
126
|
const agentId = this.createId();
|
|
42
|
-
const child =
|
|
43
|
-
cwd: this.options.cwd,
|
|
44
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
45
|
-
env: childSubAgentEnv(),
|
|
46
|
-
detached: process.platform !== "win32",
|
|
47
|
-
});
|
|
127
|
+
const child = this.spawnWorkerProcess();
|
|
48
128
|
const record = {
|
|
49
129
|
agent_id: agentId,
|
|
50
130
|
task_name: taskName,
|
|
@@ -55,6 +135,10 @@ export class SubAgentManager {
|
|
|
55
135
|
turn_count: 0,
|
|
56
136
|
tool_use_count: 0,
|
|
57
137
|
token_usage: { input: 0, output: 0 },
|
|
138
|
+
agent_name: selection.agentDef?.name,
|
|
139
|
+
provider,
|
|
140
|
+
model: selection.model,
|
|
141
|
+
collected: false,
|
|
58
142
|
process: child,
|
|
59
143
|
requests: new Map(),
|
|
60
144
|
requestSequence: 0,
|
|
@@ -65,8 +149,9 @@ export class SubAgentManager {
|
|
|
65
149
|
this.workers.set(agentId, record);
|
|
66
150
|
this.publish(record);
|
|
67
151
|
this.attach(record);
|
|
152
|
+
await this.waitForPersistence();
|
|
68
153
|
try {
|
|
69
|
-
await this.request(record, "initialize", {
|
|
154
|
+
const initialized = await this.request(record, "initialize", {
|
|
70
155
|
options: {
|
|
71
156
|
provider,
|
|
72
157
|
model: selection.model,
|
|
@@ -77,16 +162,29 @@ export class SubAgentManager {
|
|
|
77
162
|
thinkingLevel: childThinkingLevel(this.options.getThinkingLevel()),
|
|
78
163
|
allowedTools: selection.agentDef?.tools.length ? selection.agentDef.tools : undefined,
|
|
79
164
|
promptCacheKey: subAgentCacheKey(this.options.getCacheKey?.(), selection.model, selection.agentDef?.name ?? "default"),
|
|
165
|
+
sessionRootDir: this.sessionRootDir,
|
|
80
166
|
},
|
|
81
167
|
});
|
|
168
|
+
record.child_session_id =
|
|
169
|
+
typeof initialized.child_session_id === "string" ? initialized.child_session_id : undefined;
|
|
170
|
+
if (typeof initialized.model === "string")
|
|
171
|
+
record.model = initialized.model;
|
|
172
|
+
record.child_session_path =
|
|
173
|
+
typeof initialized.child_session_path === "string"
|
|
174
|
+
? this.assertChildSessionPath(initialized.child_session_path)
|
|
175
|
+
: undefined;
|
|
176
|
+
this.publish(record);
|
|
177
|
+
await this.waitForPersistence();
|
|
82
178
|
await this.request(record, "start", { task });
|
|
83
179
|
record.state = "running";
|
|
84
180
|
record.updated_at = Date.now();
|
|
85
181
|
this.publish(record);
|
|
182
|
+
await this.waitForPersistence();
|
|
86
183
|
return this.snapshot(record);
|
|
87
184
|
}
|
|
88
185
|
catch (error) {
|
|
89
186
|
this.fail(record, error);
|
|
187
|
+
await this.waitForPersistence();
|
|
90
188
|
throw error;
|
|
91
189
|
}
|
|
92
190
|
}
|
|
@@ -99,7 +197,13 @@ export class SubAgentManager {
|
|
|
99
197
|
}
|
|
100
198
|
async followup(agentId, task) {
|
|
101
199
|
this.assertAvailable();
|
|
102
|
-
|
|
200
|
+
let worker = this.workers.get(agentId);
|
|
201
|
+
if (!worker) {
|
|
202
|
+
const recovered = this.snapshots.get(agentId);
|
|
203
|
+
if (!recovered)
|
|
204
|
+
throw new Error(`Unknown agent: ${agentId}`);
|
|
205
|
+
worker = await this.respawnRecovered(recovered);
|
|
206
|
+
}
|
|
103
207
|
if (worker.state === "running" || worker.state === "starting") {
|
|
104
208
|
throw new Error(`Agent ${agentId} already has an active turn`);
|
|
105
209
|
}
|
|
@@ -109,19 +213,24 @@ export class SubAgentManager {
|
|
|
109
213
|
worker.taskOutput = "";
|
|
110
214
|
worker.output = undefined;
|
|
111
215
|
worker.error = undefined;
|
|
216
|
+
worker.collected = false;
|
|
112
217
|
await this.request(worker, "followup", { task });
|
|
113
218
|
worker.state = "running";
|
|
114
219
|
worker.updated_at = Date.now();
|
|
115
220
|
this.publish(worker);
|
|
221
|
+
await this.waitForPersistence();
|
|
116
222
|
return this.snapshot(worker);
|
|
117
223
|
}
|
|
118
|
-
async interrupt(agentId) {
|
|
224
|
+
async interrupt(agentId, collectResult = true) {
|
|
119
225
|
const worker = this.requireWorker(agentId);
|
|
120
226
|
if (worker.state !== "running")
|
|
121
227
|
throw new Error(`Agent ${agentId} is not running`);
|
|
122
228
|
const changed = this.waitForChange(agentId);
|
|
123
229
|
await this.request(worker, "interrupt");
|
|
124
230
|
await changed;
|
|
231
|
+
if (collectResult)
|
|
232
|
+
this.markCollected(agentId);
|
|
233
|
+
await this.waitForPersistence();
|
|
125
234
|
return this.snapshot(worker);
|
|
126
235
|
}
|
|
127
236
|
subscribe(listener) {
|
|
@@ -147,17 +256,29 @@ export class SubAgentManager {
|
|
|
147
256
|
const boundedTimeout = Math.min(Math.max(timeoutMs, 0), MAX_WAIT_MS);
|
|
148
257
|
const terminal = () => ids.filter((id) => this.isTerminal(this.snapshots.get(id)?.state));
|
|
149
258
|
const ready = () => condition === "all" ? terminal().length === ids.length : terminal().length > 0;
|
|
259
|
+
const deadline = Date.now() + boundedTimeout;
|
|
150
260
|
let timedOut = false;
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
261
|
+
while (!ready()) {
|
|
262
|
+
const remaining = deadline - Date.now();
|
|
263
|
+
if (remaining <= 0) {
|
|
264
|
+
timedOut = true;
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
const pendingIds = ids.filter((id) => !this.isTerminal(this.snapshots.get(id)?.state));
|
|
268
|
+
const changed = await Promise.race([
|
|
269
|
+
Promise.race(pendingIds.map((id) => this.waitForChange(id))).then(() => true),
|
|
270
|
+
new Promise((resolve) => setTimeout(() => resolve(false), remaining)),
|
|
271
|
+
]);
|
|
272
|
+
if (!changed && !ready())
|
|
273
|
+
timedOut = true;
|
|
274
|
+
if (!changed)
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
for (const id of ids) {
|
|
278
|
+
if (this.isTerminal(this.snapshots.get(id)?.state))
|
|
279
|
+
this.markCollected(id);
|
|
160
280
|
}
|
|
281
|
+
await this.waitForPersistence();
|
|
161
282
|
let chars = 0;
|
|
162
283
|
const agents = ids.map((id) => {
|
|
163
284
|
const snapshot = { ...this.snapshots.get(id) };
|
|
@@ -170,16 +291,39 @@ export class SubAgentManager {
|
|
|
170
291
|
});
|
|
171
292
|
return { timed_out: timedOut, agents };
|
|
172
293
|
}
|
|
294
|
+
completionGate() {
|
|
295
|
+
const snapshots = this.list();
|
|
296
|
+
const active = snapshots.filter((snapshot) => this.isActive(snapshot));
|
|
297
|
+
const uncollected = snapshots.filter((snapshot) => this.isTerminal(snapshot.state) && snapshot.collected !== true);
|
|
298
|
+
return { active, uncollected, unresolved: active.length + uncollected.length };
|
|
299
|
+
}
|
|
300
|
+
completionGateMessage() {
|
|
301
|
+
const gate = this.completionGate();
|
|
302
|
+
if (gate.unresolved === 0)
|
|
303
|
+
return undefined;
|
|
304
|
+
const activeIds = gate.active.map((snapshot) => snapshot.agent_id).sort();
|
|
305
|
+
const uncollectedIds = gate.uncollected.map((snapshot) => snapshot.agent_id).sort();
|
|
306
|
+
const unresolvedIds = [...new Set([...activeIds, ...uncollectedIds])];
|
|
307
|
+
return [
|
|
308
|
+
"Child-agent completion gate: the parent cannot finish with unresolved child work.",
|
|
309
|
+
`Unresolved agent IDs: ${unresolvedIds.join(", ")}.`,
|
|
310
|
+
activeIds.length > 0
|
|
311
|
+
? `Active agent IDs: ${activeIds.join(", ")}. Wait for them with wait_agent, or interrupt them before collecting their terminal result.`
|
|
312
|
+
: "All children are terminal, but their results have not been collected.",
|
|
313
|
+
`Call wait_agent with agent_ids [${unresolvedIds.map((id) => `"${id}"`).join(", ")}] and condition "all" before finishing.`,
|
|
314
|
+
].join("\n");
|
|
315
|
+
}
|
|
173
316
|
async interruptAll() {
|
|
174
317
|
await Promise.allSettled([...this.workers.values()]
|
|
175
318
|
.filter((worker) => this.isActive(worker))
|
|
176
|
-
.map((worker) => worker.state === "starting" ? this.close(worker) : this.interrupt(worker.agent_id)));
|
|
319
|
+
.map((worker) => worker.state === "starting" ? this.close(worker) : this.interrupt(worker.agent_id, false)));
|
|
177
320
|
}
|
|
178
321
|
async shutdownAll() {
|
|
179
|
-
if (this.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
322
|
+
if (!this.shutdownPromise) {
|
|
323
|
+
this.shuttingDown = true;
|
|
324
|
+
this.shutdownPromise = Promise.allSettled([...this.workers.values()].map((worker) => this.close(worker, false, true))).then(() => undefined);
|
|
325
|
+
}
|
|
326
|
+
await this.shutdownPromise;
|
|
183
327
|
}
|
|
184
328
|
/** Synchronous process-exit fallback: terminate detached process groups immediately. */
|
|
185
329
|
shutdownAllNow() {
|
|
@@ -187,6 +331,100 @@ export class SubAgentManager {
|
|
|
187
331
|
for (const worker of this.workers.values())
|
|
188
332
|
this.kill(worker);
|
|
189
333
|
}
|
|
334
|
+
markCollected(agentId) {
|
|
335
|
+
const worker = this.workers.get(agentId);
|
|
336
|
+
if (worker) {
|
|
337
|
+
worker.collected = true;
|
|
338
|
+
worker.updated_at = Date.now();
|
|
339
|
+
this.publish(worker);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const snapshot = this.snapshots.get(agentId);
|
|
343
|
+
if (!snapshot)
|
|
344
|
+
return;
|
|
345
|
+
const collected = { ...snapshot, collected: true, updated_at: Date.now() };
|
|
346
|
+
this.snapshots.set(agentId, collected);
|
|
347
|
+
this.options.onState?.(collected);
|
|
348
|
+
for (const listener of this.listeners)
|
|
349
|
+
listener(collected);
|
|
350
|
+
this.queuePersist();
|
|
351
|
+
}
|
|
352
|
+
spawnWorkerProcess() {
|
|
353
|
+
return spawn(process.execPath, [this.options.workerEntry ?? resolveSubAgentCliEntry(), "--subagent-worker"], {
|
|
354
|
+
cwd: this.options.cwd,
|
|
355
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
356
|
+
env: childSubAgentEnv(),
|
|
357
|
+
detached: process.platform !== "win32",
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
async respawnRecovered(snapshot) {
|
|
361
|
+
if (!snapshot.child_session_path) {
|
|
362
|
+
throw new Error(`Agent ${snapshot.agent_id} was reaped and has no recoverable child session`);
|
|
363
|
+
}
|
|
364
|
+
const agentDef = snapshot.agent_name
|
|
365
|
+
? this.options.agents.find((candidate) => candidate.name === snapshot.agent_name)
|
|
366
|
+
: undefined;
|
|
367
|
+
const provider = snapshot.provider ?? this.options.getProvider();
|
|
368
|
+
const model = snapshot.model ?? this.options.getModel();
|
|
369
|
+
const parentModel = this.options.getModel();
|
|
370
|
+
const childSessionPath = this.assertChildSessionPath(snapshot.child_session_path);
|
|
371
|
+
const child = this.spawnWorkerProcess();
|
|
372
|
+
const worker = {
|
|
373
|
+
...snapshot,
|
|
374
|
+
state: "starting",
|
|
375
|
+
updated_at: Date.now(),
|
|
376
|
+
current_activity: undefined,
|
|
377
|
+
output: undefined,
|
|
378
|
+
error: undefined,
|
|
379
|
+
collected: false,
|
|
380
|
+
recovered: false,
|
|
381
|
+
process: child,
|
|
382
|
+
requests: new Map(),
|
|
383
|
+
requestSequence: 0,
|
|
384
|
+
stderr: "",
|
|
385
|
+
taskOutput: "",
|
|
386
|
+
turnResolvers: new Set(),
|
|
387
|
+
};
|
|
388
|
+
this.workers.set(worker.agent_id, worker);
|
|
389
|
+
this.publish(worker);
|
|
390
|
+
this.attach(worker);
|
|
391
|
+
await this.waitForPersistence();
|
|
392
|
+
try {
|
|
393
|
+
const initialized = await this.request(worker, "initialize", {
|
|
394
|
+
options: {
|
|
395
|
+
provider,
|
|
396
|
+
model,
|
|
397
|
+
fallbackModel: model === parentModel ? undefined : parentModel,
|
|
398
|
+
cwd: this.options.cwd,
|
|
399
|
+
baseUrl: this.options.getBaseUrl?.(),
|
|
400
|
+
systemPrompt: agentDef?.systemPrompt,
|
|
401
|
+
thinkingLevel: childThinkingLevel(this.options.getThinkingLevel()),
|
|
402
|
+
allowedTools: agentDef?.tools.length ? agentDef.tools : undefined,
|
|
403
|
+
promptCacheKey: subAgentCacheKey(this.options.getCacheKey?.(), model, agentDef?.name ?? "default"),
|
|
404
|
+
sessionRootDir: this.sessionRootDir,
|
|
405
|
+
childSessionPath,
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
if (typeof initialized.child_session_id === "string") {
|
|
409
|
+
worker.child_session_id = initialized.child_session_id;
|
|
410
|
+
}
|
|
411
|
+
if (typeof initialized.child_session_path === "string") {
|
|
412
|
+
worker.child_session_path = this.assertChildSessionPath(initialized.child_session_path);
|
|
413
|
+
}
|
|
414
|
+
if (typeof initialized.model === "string")
|
|
415
|
+
worker.model = initialized.model;
|
|
416
|
+
worker.state = snapshot.state;
|
|
417
|
+
worker.updated_at = Date.now();
|
|
418
|
+
this.publish(worker);
|
|
419
|
+
await this.waitForPersistence();
|
|
420
|
+
return worker;
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
this.fail(worker, error);
|
|
424
|
+
await this.waitForPersistence();
|
|
425
|
+
throw error;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
190
428
|
attach(worker) {
|
|
191
429
|
const lines = createInterface({ input: worker.process.stdout });
|
|
192
430
|
lines.on("line", (line) => {
|
|
@@ -242,7 +480,8 @@ export class SubAgentManager {
|
|
|
242
480
|
worker.token_usage.output += usage?.outputTokens ?? 0;
|
|
243
481
|
}
|
|
244
482
|
worker.updated_at = Date.now();
|
|
245
|
-
|
|
483
|
+
const durableProgress = event === "tool_call_start" || event === "turn_end";
|
|
484
|
+
this.publish(worker, durableProgress);
|
|
246
485
|
return;
|
|
247
486
|
}
|
|
248
487
|
if (frame.type === "turn_complete") {
|
|
@@ -254,6 +493,8 @@ export class SubAgentManager {
|
|
|
254
493
|
: "failed";
|
|
255
494
|
worker.output = boundSubAgentOutput(String(frame.output ?? worker.taskOutput));
|
|
256
495
|
worker.error = frame.error ? String(frame.error) : undefined;
|
|
496
|
+
if (typeof frame.model === "string")
|
|
497
|
+
worker.model = frame.model;
|
|
257
498
|
worker.current_activity = undefined;
|
|
258
499
|
worker.updated_at = Date.now();
|
|
259
500
|
this.publish(worker);
|
|
@@ -280,7 +521,7 @@ export class SubAgentManager {
|
|
|
280
521
|
worker.turnResolvers.add(resolve);
|
|
281
522
|
});
|
|
282
523
|
}
|
|
283
|
-
publish(worker) {
|
|
524
|
+
publish(worker, persist = true) {
|
|
284
525
|
const snapshot = this.snapshot(worker);
|
|
285
526
|
this.snapshots.delete(worker.agent_id);
|
|
286
527
|
this.snapshots.set(worker.agent_id, snapshot);
|
|
@@ -289,9 +530,65 @@ export class SubAgentManager {
|
|
|
289
530
|
this.options.onState?.(snapshot);
|
|
290
531
|
for (const listener of this.listeners)
|
|
291
532
|
listener(snapshot);
|
|
533
|
+
if (persist)
|
|
534
|
+
this.queuePersist();
|
|
292
535
|
}
|
|
293
536
|
snapshot(worker) {
|
|
294
|
-
return {
|
|
537
|
+
return {
|
|
538
|
+
agent_id: worker.agent_id,
|
|
539
|
+
task_name: worker.task_name,
|
|
540
|
+
state: worker.state,
|
|
541
|
+
started_at: worker.started_at,
|
|
542
|
+
updated_at: worker.updated_at,
|
|
543
|
+
elapsed_ms: this.elapsed(worker),
|
|
544
|
+
current_activity: worker.current_activity,
|
|
545
|
+
turn_count: worker.turn_count,
|
|
546
|
+
tool_use_count: worker.tool_use_count,
|
|
547
|
+
token_usage: { ...worker.token_usage },
|
|
548
|
+
output: worker.output,
|
|
549
|
+
error: worker.error,
|
|
550
|
+
agent_name: worker.agent_name,
|
|
551
|
+
provider: worker.provider,
|
|
552
|
+
model: worker.model,
|
|
553
|
+
child_session_id: worker.child_session_id,
|
|
554
|
+
child_session_path: worker.child_session_path,
|
|
555
|
+
collected: worker.collected,
|
|
556
|
+
recovered: worker.recovered,
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
queuePersist() {
|
|
560
|
+
if (!this.parentSessionId)
|
|
561
|
+
return;
|
|
562
|
+
this.persistPending = true;
|
|
563
|
+
if (this.persistScheduled)
|
|
564
|
+
return;
|
|
565
|
+
this.persistScheduled = true;
|
|
566
|
+
this.persistQueue = this.persistQueue
|
|
567
|
+
.catch(() => { })
|
|
568
|
+
.then(async () => {
|
|
569
|
+
while (this.persistPending) {
|
|
570
|
+
this.persistPending = false;
|
|
571
|
+
const parentSessionId = this.parentSessionId;
|
|
572
|
+
if (!parentSessionId)
|
|
573
|
+
continue;
|
|
574
|
+
const records = [...this.snapshots.values()].map((snapshot) => ({
|
|
575
|
+
...snapshot,
|
|
576
|
+
token_usage: { ...snapshot.token_usage },
|
|
577
|
+
}));
|
|
578
|
+
await this.store.save(this.options.cwd, parentSessionId, records);
|
|
579
|
+
}
|
|
580
|
+
})
|
|
581
|
+
.catch((error) => {
|
|
582
|
+
this.persistPending = false;
|
|
583
|
+
log("WARN", "subagent", "Failed to persist subagent state", {
|
|
584
|
+
error: error instanceof Error ? error.message : String(error),
|
|
585
|
+
});
|
|
586
|
+
})
|
|
587
|
+
.finally(() => {
|
|
588
|
+
this.persistScheduled = false;
|
|
589
|
+
if (this.persistPending)
|
|
590
|
+
this.queuePersist();
|
|
591
|
+
});
|
|
295
592
|
}
|
|
296
593
|
elapsed(snapshot) {
|
|
297
594
|
return ((this.isTerminal(snapshot.state) ? snapshot.updated_at : Date.now()) - snapshot.started_at);
|
|
@@ -303,7 +600,11 @@ export class SubAgentManager {
|
|
|
303
600
|
return worker.state === "starting" || worker.state === "running";
|
|
304
601
|
}
|
|
305
602
|
isTerminal(state) {
|
|
306
|
-
return (state === "completed" ||
|
|
603
|
+
return (state === "completed" ||
|
|
604
|
+
state === "failed" ||
|
|
605
|
+
state === "interrupted" ||
|
|
606
|
+
state === "closed" ||
|
|
607
|
+
state === "reaped");
|
|
307
608
|
}
|
|
308
609
|
requireWorker(agentId) {
|
|
309
610
|
const worker = this.workers.get(agentId);
|
|
@@ -315,6 +616,14 @@ export class SubAgentManager {
|
|
|
315
616
|
if (this.shuttingDown)
|
|
316
617
|
throw new Error("Subagent manager is shutting down");
|
|
317
618
|
}
|
|
619
|
+
assertChildSessionPath(candidate) {
|
|
620
|
+
const root = path.resolve(this.sessionRootDir);
|
|
621
|
+
const resolved = path.resolve(candidate);
|
|
622
|
+
if (!resolved.startsWith(`${root}${path.sep}`) || path.extname(resolved) !== ".jsonl") {
|
|
623
|
+
throw new Error("Recovered child session path is outside the subagent session root");
|
|
624
|
+
}
|
|
625
|
+
return resolved;
|
|
626
|
+
}
|
|
318
627
|
createId() {
|
|
319
628
|
let id;
|
|
320
629
|
do
|
|
@@ -333,7 +642,7 @@ export class SubAgentManager {
|
|
|
333
642
|
.filter((worker) => this.isTerminal(worker.state))
|
|
334
643
|
.sort((a, b) => a.updated_at - b.updated_at);
|
|
335
644
|
while (idle.length > RETAINED_WORKER_LIMIT)
|
|
336
|
-
void this.close(idle.shift());
|
|
645
|
+
void this.close(idle.shift(), true);
|
|
337
646
|
}
|
|
338
647
|
fail(worker, error, kill = true) {
|
|
339
648
|
if (this.isTerminal(worker.state))
|
|
@@ -352,7 +661,7 @@ export class SubAgentManager {
|
|
|
352
661
|
if (kill)
|
|
353
662
|
this.kill(worker);
|
|
354
663
|
}
|
|
355
|
-
async close(worker) {
|
|
664
|
+
async close(worker, reaped = false, preserveTerminal = false) {
|
|
356
665
|
clearTimeout(worker.idleTimer);
|
|
357
666
|
if (worker.process.stdin?.writable) {
|
|
358
667
|
await Promise.race([
|
|
@@ -368,7 +677,10 @@ export class SubAgentManager {
|
|
|
368
677
|
for (const resolve of worker.turnResolvers)
|
|
369
678
|
resolve();
|
|
370
679
|
worker.turnResolvers.clear();
|
|
371
|
-
|
|
680
|
+
if (reaped)
|
|
681
|
+
worker.state = "reaped";
|
|
682
|
+
else if (!preserveTerminal || !this.isTerminal(worker.state))
|
|
683
|
+
worker.state = "closed";
|
|
372
684
|
worker.updated_at = Date.now();
|
|
373
685
|
this.publish(worker);
|
|
374
686
|
this.workers.delete(worker.agent_id);
|