agent-nuvira 3.3.3 → 3.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -5
- package/dist/agent-sdk/src/agent.d.ts +2 -0
- package/dist/agent-sdk/src/agent.d.ts.map +1 -1
- package/dist/agent-sdk/src/define.d.ts +64 -0
- package/dist/agent-sdk/src/define.d.ts.map +1 -0
- package/dist/agent-sdk/src/define.js +76 -0
- package/dist/agent-sdk/src/define.js.map +1 -0
- package/dist/agent-sdk/src/index.d.ts +9 -0
- package/dist/agent-sdk/src/index.d.ts.map +1 -1
- package/dist/agent-sdk/src/index.js +9 -0
- package/dist/agent-sdk/src/index.js.map +1 -1
- package/dist/agent-sdk/src/scaffold.d.ts +11 -0
- package/dist/agent-sdk/src/scaffold.d.ts.map +1 -1
- package/dist/agent-sdk/src/scaffold.js +16 -6
- package/dist/agent-sdk/src/scaffold.js.map +1 -1
- package/dist/agents/long-form-plan.d.ts.map +1 -1
- package/dist/agents/long-form-plan.js +2 -1
- package/dist/agents/long-form-plan.js.map +1 -1
- package/dist/agents/orchestrator.d.ts.map +1 -1
- package/dist/agents/orchestrator.js +5 -4
- package/dist/agents/orchestrator.js.map +1 -1
- package/dist/cli/agent.d.ts +2 -2
- package/dist/cli/agent.js +10 -10
- package/dist/cli/chat.d.ts +94 -0
- package/dist/cli/chat.d.ts.map +1 -1
- package/dist/cli/chat.js +354 -20
- package/dist/cli/chat.js.map +1 -1
- package/dist/cli/cli-program.d.ts.map +1 -1
- package/dist/cli/cli-program.js +5 -0
- package/dist/cli/cli-program.js.map +1 -1
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +9 -1
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +3 -2
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/edit.js +2 -2
- package/dist/cli/eval.d.ts +17 -0
- package/dist/cli/eval.d.ts.map +1 -1
- package/dist/cli/eval.js +105 -2
- package/dist/cli/eval.js.map +1 -1
- package/dist/cli/execute.d.ts +16 -1
- package/dist/cli/execute.d.ts.map +1 -1
- package/dist/cli/execute.js +192 -22
- package/dist/cli/execute.js.map +1 -1
- package/dist/cli/loop-executor.d.ts +55 -0
- package/dist/cli/loop-executor.d.ts.map +1 -1
- package/dist/cli/loop-executor.js +212 -13
- package/dist/cli/loop-executor.js.map +1 -1
- package/dist/cli/model.d.ts.map +1 -1
- package/dist/cli/model.js +9 -8
- package/dist/cli/model.js.map +1 -1
- package/dist/cli/models.d.ts +1 -1
- package/dist/cli/models.js +4 -4
- package/dist/cli/parity.d.ts +85 -0
- package/dist/cli/parity.d.ts.map +1 -0
- package/dist/cli/parity.js +506 -0
- package/dist/cli/parity.js.map +1 -0
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +2 -1
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/retrieval.d.ts.map +1 -1
- package/dist/cli/retrieval.js +5 -4
- package/dist/cli/retrieval.js.map +1 -1
- package/dist/cli/sdk.js +4 -4
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli/trace.d.ts.map +1 -1
- package/dist/cli/trace.js +2 -1
- package/dist/cli/trace.js.map +1 -1
- package/dist/cli/workflow.js +2 -2
- package/dist/cli/workflow.js.map +1 -1
- package/dist/config/process-env.d.ts +136 -0
- package/dist/config/process-env.d.ts.map +1 -0
- package/dist/config/process-env.js +217 -0
- package/dist/config/process-env.js.map +1 -0
- package/dist/config/types.d.ts +44 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/findings/verdicts.d.ts +241 -0
- package/dist/findings/verdicts.d.ts.map +1 -0
- package/dist/findings/verdicts.js +284 -0
- package/dist/findings/verdicts.js.map +1 -0
- package/dist/gateway/adapters.d.ts +65 -0
- package/dist/gateway/adapters.d.ts.map +1 -1
- package/dist/gateway/adapters.js +216 -10
- package/dist/gateway/adapters.js.map +1 -1
- package/dist/gateway/channel-directory.d.ts +31 -0
- package/dist/gateway/channel-directory.d.ts.map +1 -1
- package/dist/gateway/channel-directory.js +40 -0
- package/dist/gateway/channel-directory.js.map +1 -1
- package/dist/gateway/gateway-log.d.ts +1 -1
- package/dist/gateway/gateway-log.d.ts.map +1 -1
- package/dist/gateway/gateway-log.js.map +1 -1
- package/dist/gateway/hooks.d.ts +87 -19
- package/dist/gateway/hooks.d.ts.map +1 -1
- package/dist/gateway/hooks.js +62 -23
- package/dist/gateway/hooks.js.map +1 -1
- package/dist/gateway/inbound-media.d.ts +147 -0
- package/dist/gateway/inbound-media.d.ts.map +1 -0
- package/dist/gateway/inbound-media.js +317 -0
- package/dist/gateway/inbound-media.js.map +1 -0
- package/dist/gateway/inbox.d.ts +8 -1
- package/dist/gateway/inbox.d.ts.map +1 -1
- package/dist/gateway/inbox.js.map +1 -1
- package/dist/gateway/platform-config.d.ts +14 -0
- package/dist/gateway/platform-config.d.ts.map +1 -1
- package/dist/gateway/platform-config.js +26 -8
- package/dist/gateway/platform-config.js.map +1 -1
- package/dist/gateway/realtime.d.ts +114 -0
- package/dist/gateway/realtime.d.ts.map +1 -0
- package/dist/gateway/realtime.js +402 -0
- package/dist/gateway/realtime.js.map +1 -0
- package/dist/gateway/registry.d.ts +31 -0
- package/dist/gateway/registry.d.ts.map +1 -1
- package/dist/gateway/registry.js +224 -4
- package/dist/gateway/registry.js.map +1 -1
- package/dist/gateway/whatsapp/baileys-bridge.d.ts +11 -1
- package/dist/gateway/whatsapp/baileys-bridge.d.ts.map +1 -1
- package/dist/gateway/whatsapp/baileys-bridge.js +123 -4
- package/dist/gateway/whatsapp/baileys-bridge.js.map +1 -1
- package/dist/gateway/whatsapp/bridge.d.ts +6 -2
- package/dist/gateway/whatsapp/bridge.d.ts.map +1 -1
- package/dist/gateway/whatsapp/bridge.js.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/inference/factory.d.ts +14 -0
- package/dist/inference/factory.d.ts.map +1 -1
- package/dist/inference/factory.js +17 -0
- package/dist/inference/factory.js.map +1 -1
- package/dist/inference/groq-adapter.d.ts +2 -0
- package/dist/inference/groq-adapter.d.ts.map +1 -1
- package/dist/inference/groq-adapter.js +16 -6
- package/dist/inference/groq-adapter.js.map +1 -1
- package/dist/inference/tools.d.ts.map +1 -1
- package/dist/inference/tools.js +29 -0
- package/dist/inference/tools.js.map +1 -1
- package/dist/learning/benchmark.d.ts.map +1 -1
- package/dist/learning/benchmark.js +3 -2
- package/dist/learning/benchmark.js.map +1 -1
- package/dist/learning/continuation.d.ts.map +1 -1
- package/dist/learning/continuation.js +2 -1
- package/dist/learning/continuation.js.map +1 -1
- package/dist/learning/cost-tracker.d.ts.map +1 -1
- package/dist/learning/cost-tracker.js +2 -1
- package/dist/learning/cost-tracker.js.map +1 -1
- package/dist/learning/deferred-task.d.ts.map +1 -1
- package/dist/learning/deferred-task.js +13 -4
- package/dist/learning/deferred-task.js.map +1 -1
- package/dist/learning/eval-framework.d.ts.map +1 -1
- package/dist/learning/eval-framework.js +2 -1
- package/dist/learning/eval-framework.js.map +1 -1
- package/dist/learning/long-form.d.ts.map +1 -1
- package/dist/learning/long-form.js +2 -1
- package/dist/learning/long-form.js.map +1 -1
- package/dist/learning/model-reachability.d.ts +95 -0
- package/dist/learning/model-reachability.d.ts.map +1 -0
- package/dist/learning/model-reachability.js +111 -0
- package/dist/learning/model-reachability.js.map +1 -0
- package/dist/learning/model-registry.d.ts +22 -0
- package/dist/learning/model-registry.d.ts.map +1 -1
- package/dist/learning/model-registry.js +26 -1
- package/dist/learning/model-registry.js.map +1 -1
- package/dist/learning/model-verify-job.d.ts +131 -0
- package/dist/learning/model-verify-job.d.ts.map +1 -0
- package/dist/learning/model-verify-job.js +221 -0
- package/dist/learning/model-verify-job.js.map +1 -0
- package/dist/learning/reasoning-cache.d.ts.map +1 -1
- package/dist/learning/reasoning-cache.js +2 -1
- package/dist/learning/reasoning-cache.js.map +1 -1
- package/dist/learning/reasoning-trace.d.ts +37 -1
- package/dist/learning/reasoning-trace.d.ts.map +1 -1
- package/dist/learning/reasoning-trace.js +66 -0
- package/dist/learning/reasoning-trace.js.map +1 -1
- package/dist/learning/resilient-call.d.ts.map +1 -1
- package/dist/learning/resilient-call.js +2 -1
- package/dist/learning/resilient-call.js.map +1 -1
- package/dist/learning/retrieval.d.ts.map +1 -1
- package/dist/learning/retrieval.js +2 -1
- package/dist/learning/retrieval.js.map +1 -1
- package/dist/learning/seeded-benchmark.d.ts +160 -0
- package/dist/learning/seeded-benchmark.d.ts.map +1 -0
- package/dist/learning/seeded-benchmark.js +321 -0
- package/dist/learning/seeded-benchmark.js.map +1 -0
- package/dist/learning/seeded-bugs.d.ts +142 -0
- package/dist/learning/seeded-bugs.d.ts.map +1 -0
- package/dist/learning/seeded-bugs.js +535 -0
- package/dist/learning/seeded-bugs.js.map +1 -0
- package/dist/learning/step-checkpoint.d.ts +127 -0
- package/dist/learning/step-checkpoint.d.ts.map +1 -0
- package/dist/learning/step-checkpoint.js +244 -0
- package/dist/learning/step-checkpoint.js.map +1 -0
- package/dist/nlu/intent-confirm.d.ts +23 -1
- package/dist/nlu/intent-confirm.d.ts.map +1 -1
- package/dist/nlu/intent-confirm.js +85 -2
- package/dist/nlu/intent-confirm.js.map +1 -1
- package/dist/nlu/learnings.d.ts +7 -0
- package/dist/nlu/learnings.d.ts.map +1 -1
- package/dist/nlu/learnings.js +7 -0
- package/dist/nlu/learnings.js.map +1 -1
- package/dist/observability/debug-log.d.ts +250 -0
- package/dist/observability/debug-log.d.ts.map +1 -0
- package/dist/observability/debug-log.js +500 -0
- package/dist/observability/debug-log.js.map +1 -0
- package/dist/observability/event-bus.d.ts.map +1 -1
- package/dist/observability/event-bus.js +4 -1
- package/dist/observability/event-bus.js.map +1 -1
- package/dist/observability/otel.d.ts +278 -0
- package/dist/observability/otel.d.ts.map +1 -0
- package/dist/observability/otel.js +590 -0
- package/dist/observability/otel.js.map +1 -0
- package/dist/parity/drivers.d.ts +99 -0
- package/dist/parity/drivers.d.ts.map +1 -0
- package/dist/parity/drivers.js +1362 -0
- package/dist/parity/drivers.js.map +1 -0
- package/dist/parity/graph.d.ts +73 -0
- package/dist/parity/graph.d.ts.map +1 -0
- package/dist/parity/graph.js +162 -0
- package/dist/parity/graph.js.map +1 -0
- package/dist/parity/matrix.d.ts +105 -0
- package/dist/parity/matrix.d.ts.map +1 -0
- package/dist/parity/matrix.js +352 -0
- package/dist/parity/matrix.js.map +1 -0
- package/dist/parity/observation.d.ts +444 -0
- package/dist/parity/observation.d.ts.map +1 -0
- package/dist/parity/observation.js +333 -0
- package/dist/parity/observation.js.map +1 -0
- package/dist/parity/scenarios.d.ts +229 -0
- package/dist/parity/scenarios.d.ts.map +1 -0
- package/dist/parity/scenarios.js +175 -0
- package/dist/parity/scenarios.js.map +1 -0
- package/dist/parity/surfaces.d.ts +122 -0
- package/dist/parity/surfaces.d.ts.map +1 -0
- package/dist/parity/surfaces.js +190 -0
- package/dist/parity/surfaces.js.map +1 -0
- package/dist/runtime/fault-injection.d.ts +173 -0
- package/dist/runtime/fault-injection.d.ts.map +1 -0
- package/dist/runtime/fault-injection.js +281 -0
- package/dist/runtime/fault-injection.js.map +1 -0
- package/dist/tools/child-agent-entry.d.ts +23 -0
- package/dist/tools/child-agent-entry.d.ts.map +1 -0
- package/dist/tools/child-agent-entry.js +129 -0
- package/dist/tools/child-agent-entry.js.map +1 -0
- package/dist/tools/child-agent-runtime.d.ts +124 -0
- package/dist/tools/child-agent-runtime.d.ts.map +1 -0
- package/dist/tools/child-agent-runtime.js +704 -0
- package/dist/tools/child-agent-runtime.js.map +1 -0
- package/dist/tools/coding-tools.d.ts.map +1 -1
- package/dist/tools/coding-tools.js +82 -10
- package/dist/tools/coding-tools.js.map +1 -1
- package/dist/tools/delegation-system.d.ts +31 -0
- package/dist/tools/delegation-system.d.ts.map +1 -1
- package/dist/tools/delegation-system.js +70 -9
- package/dist/tools/delegation-system.js.map +1 -1
- package/dist/tools/extract/docx.d.ts +27 -0
- package/dist/tools/extract/docx.d.ts.map +1 -0
- package/dist/tools/extract/docx.js +48 -0
- package/dist/tools/extract/docx.js.map +1 -0
- package/dist/tools/extract/html-text.d.ts +27 -0
- package/dist/tools/extract/html-text.d.ts.map +1 -0
- package/dist/tools/extract/html-text.js +86 -0
- package/dist/tools/extract/html-text.js.map +1 -0
- package/dist/tools/extract/pdf-ocr.d.ts +58 -0
- package/dist/tools/extract/pdf-ocr.d.ts.map +1 -0
- package/dist/tools/extract/pdf-ocr.js +116 -0
- package/dist/tools/extract/pdf-ocr.js.map +1 -0
- package/dist/tools/extract/pdf.d.ts +65 -0
- package/dist/tools/extract/pdf.d.ts.map +1 -0
- package/dist/tools/extract/pdf.js +197 -0
- package/dist/tools/extract/pdf.js.map +1 -0
- package/dist/tools/extract/pptx.d.ts +32 -0
- package/dist/tools/extract/pptx.d.ts.map +1 -0
- package/dist/tools/extract/pptx.js +77 -0
- package/dist/tools/extract/pptx.js.map +1 -0
- package/dist/tools/extract/xlsx.d.ts +47 -0
- package/dist/tools/extract/xlsx.d.ts.map +1 -0
- package/dist/tools/extract/xlsx.js +111 -0
- package/dist/tools/extract/xlsx.js.map +1 -0
- package/dist/tools/finding-tool.d.ts +76 -0
- package/dist/tools/finding-tool.d.ts.map +1 -0
- package/dist/tools/finding-tool.js +125 -0
- package/dist/tools/finding-tool.js.map +1 -0
- package/dist/tools/messaging-tools.d.ts +41 -11
- package/dist/tools/messaging-tools.d.ts.map +1 -1
- package/dist/tools/messaging-tools.js +104 -55
- package/dist/tools/messaging-tools.js.map +1 -1
- package/dist/tools/neutts-synth.d.ts +27 -3
- package/dist/tools/neutts-synth.d.ts.map +1 -1
- package/dist/tools/neutts-synth.js +57 -13
- package/dist/tools/neutts-synth.js.map +1 -1
- package/dist/tools/pipeline-tool.d.ts +43 -1
- package/dist/tools/pipeline-tool.d.ts.map +1 -1
- package/dist/tools/pipeline-tool.js +13 -2
- package/dist/tools/pipeline-tool.js.map +1 -1
- package/dist/tools/read-extract.d.ts +116 -45
- package/dist/tools/read-extract.d.ts.map +1 -1
- package/dist/tools/read-extract.js +494 -158
- package/dist/tools/read-extract.js.map +1 -1
- package/dist/tools/registry.d.ts +2 -2
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +152 -23
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/subagent-refusal.d.ts +15 -0
- package/dist/tools/subagent-refusal.d.ts.map +1 -0
- package/dist/tools/subagent-refusal.js +18 -0
- package/dist/tools/subagent-refusal.js.map +1 -0
- package/dist/tools/subagent-spawner.d.ts +122 -0
- package/dist/tools/subagent-spawner.d.ts.map +1 -1
- package/dist/tools/subagent-spawner.js +249 -28
- package/dist/tools/subagent-spawner.js.map +1 -1
- package/dist/tools/tool-hooks.d.ts +177 -0
- package/dist/tools/tool-hooks.d.ts.map +1 -0
- package/dist/tools/tool-hooks.js +427 -0
- package/dist/tools/tool-hooks.js.map +1 -0
- package/dist/tools/tool-loop.d.ts +82 -0
- package/dist/tools/tool-loop.d.ts.map +1 -1
- package/dist/tools/tool-loop.js +167 -9
- package/dist/tools/tool-loop.js.map +1 -1
- package/dist/tools/tool-refusal.d.ts +68 -0
- package/dist/tools/tool-refusal.d.ts.map +1 -0
- package/dist/tools/tool-refusal.js +78 -0
- package/dist/tools/tool-refusal.js.map +1 -0
- package/dist/tools/toolsets.d.ts +8 -0
- package/dist/tools/toolsets.d.ts.map +1 -1
- package/dist/tools/toolsets.js +12 -2
- package/dist/tools/toolsets.js.map +1 -1
- package/dist/tools/vision-tools.d.ts +88 -83
- package/dist/tools/vision-tools.d.ts.map +1 -1
- package/dist/tools/vision-tools.js +134 -103
- package/dist/tools/vision-tools.js.map +1 -1
- package/dist/tools/worktree.d.ts +210 -0
- package/dist/tools/worktree.d.ts.map +1 -0
- package/dist/tools/worktree.js +374 -0
- package/dist/tools/worktree.js.map +1 -0
- package/dist/utils/format.d.ts +3 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +32 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/web-dashboard/attachment-extract.d.ts +64 -0
- package/dist/web-dashboard/attachment-extract.d.ts.map +1 -0
- package/dist/web-dashboard/attachment-extract.js +154 -0
- package/dist/web-dashboard/attachment-extract.js.map +1 -0
- package/dist/web-dashboard/chat-console.d.ts +108 -1
- package/dist/web-dashboard/chat-console.d.ts.map +1 -1
- package/dist/web-dashboard/chat-console.js +36 -0
- package/dist/web-dashboard/chat-console.js.map +1 -1
- package/dist/web-dashboard/hub-data.d.ts +37 -0
- package/dist/web-dashboard/hub-data.d.ts.map +1 -1
- package/dist/web-dashboard/hub-data.js +61 -1
- package/dist/web-dashboard/hub-data.js.map +1 -1
- package/dist/web-dashboard/process-env-inventory.d.ts +57 -0
- package/dist/web-dashboard/process-env-inventory.d.ts.map +1 -0
- package/dist/web-dashboard/process-env-inventory.js +96 -0
- package/dist/web-dashboard/process-env-inventory.js.map +1 -0
- package/dist/web-dashboard/server.d.ts +14 -0
- package/dist/web-dashboard/server.d.ts.map +1 -1
- package/dist/web-dashboard/server.js +493 -30
- package/dist/web-dashboard/server.js.map +1 -1
- package/dist/web-dashboard/src/types.d.ts +261 -48
- package/dist/web-dashboard/src/types.d.ts.map +1 -1
- package/package.json +18 -3
- package/src/web-dashboard/public/assets/{index-Cyd6tIew.css → index-CIJ6FHHZ.css} +1 -1
- package/src/web-dashboard/public/assets/index-CsySzR41.js +207 -0
- package/src/web-dashboard/public/assets/index-CsySzR41.js.map +1 -0
- package/src/web-dashboard/public/index.html +2 -2
- package/dist/tools/child-agent-worker.js +0 -212
- package/src/web-dashboard/public/assets/index-CxDj7p6i.js +0 -207
- package/src/web-dashboard/public/assets/index-CxDj7p6i.js.map +0 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The refusal a subagent raises when it cannot do real work.
|
|
3
|
+
*
|
|
4
|
+
* A subagent that cannot run must say so with a machine-readable reason — the
|
|
5
|
+
* same contract every tool follows (`tool-refusal.ts`). It exists as its own
|
|
6
|
+
* module because it crosses a process boundary: the child throws it, serialises
|
|
7
|
+
* its `code` + message over IPC, and the parent records it as the task's error
|
|
8
|
+
* instead of reporting a task that never ran as completed.
|
|
9
|
+
*/
|
|
10
|
+
import type { ToolRefusalCode } from './tool-refusal.js';
|
|
11
|
+
export declare class SubagentRefusalError extends Error {
|
|
12
|
+
readonly code: ToolRefusalCode;
|
|
13
|
+
constructor(code: ToolRefusalCode, message: string);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=subagent-refusal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-refusal.d.ts","sourceRoot":"","sources":["../../src/tools/subagent-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;gBAEnB,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM;CAKnD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The refusal a subagent raises when it cannot do real work.
|
|
3
|
+
*
|
|
4
|
+
* A subagent that cannot run must say so with a machine-readable reason — the
|
|
5
|
+
* same contract every tool follows (`tool-refusal.ts`). It exists as its own
|
|
6
|
+
* module because it crosses a process boundary: the child throws it, serialises
|
|
7
|
+
* its `code` + message over IPC, and the parent records it as the task's error
|
|
8
|
+
* instead of reporting a task that never ran as completed.
|
|
9
|
+
*/
|
|
10
|
+
export class SubagentRefusalError extends Error {
|
|
11
|
+
code;
|
|
12
|
+
constructor(code, message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'SubagentRefusalError';
|
|
15
|
+
this.code = code;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=subagent-refusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-refusal.js","sourceRoot":"","sources":["../../src/tools/subagent-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,CAAkB;IAE/B,YAAY,IAAqB,EAAE,OAAe;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -38,7 +38,27 @@ export interface SubagentConfig {
|
|
|
38
38
|
cwd?: string;
|
|
39
39
|
/** Environment variables */
|
|
40
40
|
env?: Record<string, string>;
|
|
41
|
+
/**
|
|
42
|
+
* WS5 (#27) — run this child in its OWN git worktree of `cwd`, and return the
|
|
43
|
+
* diff against the commit it started from.
|
|
44
|
+
*
|
|
45
|
+
* The isolation is made by the PARENT, not asked of the child: the child is a
|
|
46
|
+
* separate process that resolves its own config and could decline, and a child
|
|
47
|
+
* that quietly declined would be the worst outcome — a parent that believes the
|
|
48
|
+
* work happened in a worktree while it happened in the real tree. So the parent
|
|
49
|
+
* creates the worktree, forks INTO it, and measures the diff itself.
|
|
50
|
+
*/
|
|
51
|
+
worktree?: boolean;
|
|
52
|
+
/** Keep the worktree after the run instead of removing it (default: remove). */
|
|
53
|
+
keepWorktree?: boolean;
|
|
41
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* WS5 (#27) — how the resume request reaches the child: the inherited
|
|
57
|
+
* `NUVIRA_RESUME` (see `SubagentRuntimeConfig.resume`). The child resolves it from
|
|
58
|
+
* its own environment, exactly as an in-process surface does, so one request
|
|
59
|
+
* means the same thing on both sides of the fork.
|
|
60
|
+
*/
|
|
61
|
+
export declare const SUBAGENT_RESUME_ENV = "NUVIRA_RESUME";
|
|
42
62
|
export interface SubagentState {
|
|
43
63
|
/** Subagent ID */
|
|
44
64
|
id: string;
|
|
@@ -52,6 +72,42 @@ export interface SubagentState {
|
|
|
52
72
|
result?: string;
|
|
53
73
|
/** Error */
|
|
54
74
|
error?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Typed refusal code when the child refused (see `tool-refusal.ts`), carried
|
|
77
|
+
* across the process boundary so the caller sees WHY, not just an exit code.
|
|
78
|
+
*/
|
|
79
|
+
refusalCode?: string;
|
|
80
|
+
/** Provider that actually served the run (reported by the child). */
|
|
81
|
+
provider?: string;
|
|
82
|
+
/** Model that actually served the run, when the child named one. */
|
|
83
|
+
model?: string;
|
|
84
|
+
/** How tool calls travelled: `native`, `json` (fallback) or `none`. */
|
|
85
|
+
transport?: string;
|
|
86
|
+
/**
|
|
87
|
+
* WS1 — the findings the child recorded, in call order, with the gate's
|
|
88
|
+
* verdict. Accumulated from its `finding` progress frames so a subagent run
|
|
89
|
+
* reports the same wire shape every other surface reports.
|
|
90
|
+
*/
|
|
91
|
+
findings?: import('../findings/verdicts.js').WireFinding[];
|
|
92
|
+
/** WS5 (#27) — the isolated worktree this run used, when it was isolated. */
|
|
93
|
+
worktree?: string;
|
|
94
|
+
/** WS5 (#27) — the commit the isolated run's diff is measured against. */
|
|
95
|
+
worktreeBase?: string;
|
|
96
|
+
/** WS5 (#27) — what the isolated run changed (filled in when it ends). */
|
|
97
|
+
worktreeDiff?: import('./worktree.js').WorktreeDiff;
|
|
98
|
+
/** WS5 (#27) — true when the worktree was removed after the run. */
|
|
99
|
+
worktreeRemoved?: boolean;
|
|
100
|
+
/** WS5 (#27) — the child's own resume report, when it was asked to resume. */
|
|
101
|
+
resume?: import('../learning/step-checkpoint.js').ResumeOutcome;
|
|
102
|
+
/**
|
|
103
|
+
* G1 — the child's own verification verdict: it mutated the workspace and
|
|
104
|
+
* nothing observed the result. Recorded from the child's result frame, so a
|
|
105
|
+
* delegated run's unverified edit is visible to the parent's dashboard, CLI and
|
|
106
|
+
* findings the same way an in-process turn's is.
|
|
107
|
+
*/
|
|
108
|
+
unverifiedEdit?: boolean;
|
|
109
|
+
/** G1/G2 — the child's answer claimed a code change no verification backed. */
|
|
110
|
+
unverifiedEditClaim?: boolean;
|
|
55
111
|
/** LLM calls made */
|
|
56
112
|
llmCalls: number;
|
|
57
113
|
/** Tokens used */
|
|
@@ -65,6 +121,21 @@ export interface SubagentState {
|
|
|
65
121
|
/** Duration in ms */
|
|
66
122
|
durationMs?: number;
|
|
67
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Decide a child's terminal state from what it actually reported.
|
|
126
|
+
*
|
|
127
|
+
* `handleExit` used to synthesise a success here — a child that exited 0 having
|
|
128
|
+
* sent no `result` message was marked `completed` with
|
|
129
|
+
* `result: 'Task completed successfully'`, so `subagent wait` returned success
|
|
130
|
+
* for a run whose output never existed. That is the fabricated-success defect of
|
|
131
|
+
* TOOL_TRUTHFULNESS_TRACKER finding #4, and it is the reason this decision is a
|
|
132
|
+
* separate, exported, tested function rather than three inline branches: no
|
|
133
|
+
* result means the child reported nothing, which is a failure, never a success.
|
|
134
|
+
*/
|
|
135
|
+
export declare function classifyChildExit(result: string | undefined, code: number | null, signal: NodeJS.Signals | null): {
|
|
136
|
+
status: SubagentStatus;
|
|
137
|
+
error?: string;
|
|
138
|
+
};
|
|
68
139
|
export interface SubagentResult {
|
|
69
140
|
/** Subagent ID */
|
|
70
141
|
id: string;
|
|
@@ -74,6 +145,19 @@ export interface SubagentResult {
|
|
|
74
145
|
result: string;
|
|
75
146
|
/** Error if failed */
|
|
76
147
|
error?: string;
|
|
148
|
+
/** Typed refusal code when the child refused, when it reported one. */
|
|
149
|
+
refusalCode?: string;
|
|
150
|
+
/** Provider that served the run. */
|
|
151
|
+
provider?: string;
|
|
152
|
+
/** Model that served the run, when the child reported one. */
|
|
153
|
+
model?: string;
|
|
154
|
+
/** Tool transport the run used: `native`, `json` or `none`. */
|
|
155
|
+
transport?: string;
|
|
156
|
+
/**
|
|
157
|
+
* WS1 — the findings this run recorded, in call order, with the gate's
|
|
158
|
+
* verdict — the child's own report, carried across the process boundary.
|
|
159
|
+
*/
|
|
160
|
+
findings?: import('../findings/verdicts.js').WireFinding[];
|
|
77
161
|
/** LLM calls made */
|
|
78
162
|
llmCalls: number;
|
|
79
163
|
/** Tokens used */
|
|
@@ -84,9 +168,36 @@ export interface SubagentResult {
|
|
|
84
168
|
durationMs: number;
|
|
85
169
|
/** Full log */
|
|
86
170
|
log: string[];
|
|
171
|
+
/**
|
|
172
|
+
* WS5 (#27) — the isolation this run had, and what it changed. Present only
|
|
173
|
+
* when isolation was asked for; `removed` says whether the directory is still
|
|
174
|
+
* on disk, so a caller can point at it or say it is gone.
|
|
175
|
+
*/
|
|
176
|
+
worktree?: {
|
|
177
|
+
dir: string;
|
|
178
|
+
base: string;
|
|
179
|
+
diff: import('./worktree.js').WorktreeDiff;
|
|
180
|
+
removed: boolean;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* WS5 (#27) — what the CHILD's resume replayed, and what it saved. Present only
|
|
184
|
+
* when a resume was asked for; read from the frame the child sent, so it is the
|
|
185
|
+
* child's own count rather than something the parent inferred.
|
|
186
|
+
*/
|
|
187
|
+
resume?: import('../learning/step-checkpoint.js').ResumeOutcome;
|
|
188
|
+
/**
|
|
189
|
+
* G1 — the child's own verification verdict, carried across the fork. Present
|
|
190
|
+
* (and `true`) only when the child reported it: like `findings`, an absent flag
|
|
191
|
+
* means the child did not claim it, never that the edit was verified.
|
|
192
|
+
*/
|
|
193
|
+
unverifiedEdit?: boolean;
|
|
194
|
+
/** G1/G2 — the child's answer claimed a code change no verification backed. */
|
|
195
|
+
unverifiedEditClaim?: boolean;
|
|
87
196
|
}
|
|
88
197
|
export declare class SubagentManager extends EventEmitter {
|
|
89
198
|
private subagents;
|
|
199
|
+
/** WS5 (#27) — the live worktree of each isolated run, keyed by subagent id. */
|
|
200
|
+
private worktrees;
|
|
90
201
|
private processes;
|
|
91
202
|
private maxConcurrent;
|
|
92
203
|
private maxDepth;
|
|
@@ -132,6 +243,17 @@ export declare class SubagentManager extends EventEmitter {
|
|
|
132
243
|
*/
|
|
133
244
|
readResult(id: string): SubagentResult | null;
|
|
134
245
|
private handleMessage;
|
|
246
|
+
/**
|
|
247
|
+
* Record which provider/model/transport the child is serving this run with.
|
|
248
|
+
*
|
|
249
|
+
* The child announces them on its FIRST frame — before it can fail — and repeats
|
|
250
|
+
* them on the result and error frames. Recording from every frame (not just the
|
|
251
|
+
* result) is what makes a FAILED run attributable: a subagent that its provider
|
|
252
|
+
* rejected used to land as a bare error with no provider, model or transport, so
|
|
253
|
+
* the dashboard showed a failure with nothing to debug it by — exactly backwards,
|
|
254
|
+
* since a run that produced no output is the one that needs the attribution.
|
|
255
|
+
*/
|
|
256
|
+
private recordIdentity;
|
|
135
257
|
private handleExit;
|
|
136
258
|
private buildResult;
|
|
137
259
|
private saveState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-spawner.d.ts","sourceRoot":"","sources":["../../src/tools/subagent-spawner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"subagent-spawner.d.ts","sourceRoot":"","sources":["../../src/tools/subagent-spawner.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,19 +14,89 @@
|
|
|
14
14
|
* Hermes equivalent: delegate_tool.py (3931 lines) — actual agent spawning
|
|
15
15
|
*/
|
|
16
16
|
import { fork } from 'node:child_process';
|
|
17
|
-
import {
|
|
17
|
+
import { resolveNuviraDataPath } from '../config/paths.js';
|
|
18
18
|
import { randomUUID } from 'node:crypto';
|
|
19
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'node:fs';
|
|
19
|
+
import { createWriteStream, existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'node:fs';
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { EventEmitter } from 'node:events';
|
|
22
22
|
import { logger } from '../utils/logger.js';
|
|
23
|
+
// WS3 (#25) — the W3C parent this child should continue, read from the ACTIVE
|
|
24
|
+
// span (the tool call that spawned it), plus the env key it travels in.
|
|
25
|
+
import { childTraceEnv, TRACEPARENT_ENV } from '../observability/otel.js';
|
|
26
|
+
// WS5 (#27) — the env key the child resolves its resume request from.
|
|
27
|
+
import { RESUME_ENABLE_ENV } from '../learning/step-checkpoint.js';
|
|
28
|
+
// WS5 (#27) — delegation-level isolation: the parent makes the worktree, forks
|
|
29
|
+
// INTO it, and measures the diff itself (see SubagentConfig.worktree).
|
|
30
|
+
import { createIsolatedWorktree, discardWorktree, worktreeDiff, worktreeEnv, worktreeRefusal, } from './worktree.js';
|
|
31
|
+
/**
|
|
32
|
+
* How long the exit path may spend on git.
|
|
33
|
+
*
|
|
34
|
+
* Deliberately far below the creation budget: this runs inside the child's exit
|
|
35
|
+
* handler, so every millisecond here is a millisecond the manager's own event
|
|
36
|
+
* loop is blocked. A diff that cannot be produced in five seconds is reported as
|
|
37
|
+
* "no changes could be measured", which is honest, rather than stalling a
|
|
38
|
+
* server that may be answering other sessions.
|
|
39
|
+
*/
|
|
40
|
+
const WORKTREE_EXIT_TIMEOUT_MS = 5_000;
|
|
41
|
+
/**
|
|
42
|
+
* WS5 (#27) — how the resume request reaches the child: the inherited
|
|
43
|
+
* `NUVIRA_RESUME` (see `SubagentRuntimeConfig.resume`). The child resolves it from
|
|
44
|
+
* its own environment, exactly as an in-process surface does, so one request
|
|
45
|
+
* means the same thing on both sides of the fork.
|
|
46
|
+
*/
|
|
47
|
+
export const SUBAGENT_RESUME_ENV = RESUME_ENABLE_ENV;
|
|
48
|
+
/**
|
|
49
|
+
* Decide a child's terminal state from what it actually reported.
|
|
50
|
+
*
|
|
51
|
+
* `handleExit` used to synthesise a success here — a child that exited 0 having
|
|
52
|
+
* sent no `result` message was marked `completed` with
|
|
53
|
+
* `result: 'Task completed successfully'`, so `subagent wait` returned success
|
|
54
|
+
* for a run whose output never existed. That is the fabricated-success defect of
|
|
55
|
+
* TOOL_TRUTHFULNESS_TRACKER finding #4, and it is the reason this decision is a
|
|
56
|
+
* separate, exported, tested function rather than three inline branches: no
|
|
57
|
+
* result means the child reported nothing, which is a failure, never a success.
|
|
58
|
+
*/
|
|
59
|
+
export function classifyChildExit(result, code, signal) {
|
|
60
|
+
if (result)
|
|
61
|
+
return { status: 'completed' };
|
|
62
|
+
if (code === 0)
|
|
63
|
+
return { status: 'failed', error: 'Subagent exited without reporting a result' };
|
|
64
|
+
return { status: 'failed', error: signal ? `Killed by ${signal}` : `Exit code ${code}` };
|
|
65
|
+
}
|
|
23
66
|
// ─── Subagent Manager ─────────────────────────────────────────────────────
|
|
24
|
-
|
|
67
|
+
// `resolveNuviraDataPath` (not `resolveNuviraHome`) so a process pointed at an
|
|
68
|
+
// isolated config dir writes its subagent state there too — every other state file
|
|
69
|
+
// the agent persists resolves through it, and a test can then inspect a run without
|
|
70
|
+
// touching the developer's real ~/.nuvira.
|
|
71
|
+
const SUBAGENT_DIR = resolveNuviraDataPath('cache', 'subagents');
|
|
25
72
|
const STATE_DIR = join(SUBAGENT_DIR, 'state');
|
|
26
73
|
const LOG_DIR = join(SUBAGENT_DIR, 'logs');
|
|
27
74
|
const RESULT_DIR = join(SUBAGENT_DIR, 'results');
|
|
75
|
+
/**
|
|
76
|
+
* The file to fork.
|
|
77
|
+
*
|
|
78
|
+
* A compiled build has `dist/tools/child-agent-entry.js` beside this module and
|
|
79
|
+
* plain `node` runs it. A source run (tsx/vitest) has the TypeScript original
|
|
80
|
+
* instead, which node cannot parse — it is forked through the tsx loader. The two
|
|
81
|
+
* layouts used to be handled by one hardcoded `.js` path, which failed BOTH ways:
|
|
82
|
+
* compiled, the build never emitted that file (allowJs is false, so `fork()` threw
|
|
83
|
+
* ENOENT); from source, it was a CommonJS file inside a `"type": "module"`
|
|
84
|
+
* package and died on `require is not defined`. That is why no subagent ever ran.
|
|
85
|
+
*/
|
|
86
|
+
function resolveChildEntry() {
|
|
87
|
+
const dir = import.meta.dirname;
|
|
88
|
+
const compiled = join(dir, 'child-agent-entry.js');
|
|
89
|
+
if (existsSync(compiled))
|
|
90
|
+
return { entry: compiled };
|
|
91
|
+
const source = join(dir, 'child-agent-entry.ts');
|
|
92
|
+
if (existsSync(source))
|
|
93
|
+
return { entry: source, execArgv: ['--import', 'tsx'] };
|
|
94
|
+
throw new Error(`subagent entry not found beside ${dir} (expected child-agent-entry.js or .ts) — the build is incomplete`);
|
|
95
|
+
}
|
|
28
96
|
export class SubagentManager extends EventEmitter {
|
|
29
97
|
subagents = new Map();
|
|
98
|
+
/** WS5 (#27) — the live worktree of each isolated run, keyed by subagent id. */
|
|
99
|
+
worktrees = new Map();
|
|
30
100
|
processes = new Map();
|
|
31
101
|
maxConcurrent = 3;
|
|
32
102
|
maxDepth = 1;
|
|
@@ -62,6 +132,8 @@ export class SubagentManager extends EventEmitter {
|
|
|
62
132
|
const check = this.canSpawn();
|
|
63
133
|
if (!check.allowed)
|
|
64
134
|
throw new Error(check.reason);
|
|
135
|
+
/** WS5 — the worktree this run is isolated in, when one was asked for. */
|
|
136
|
+
let worktree = null;
|
|
65
137
|
const id = randomUUID();
|
|
66
138
|
const state = {
|
|
67
139
|
id,
|
|
@@ -75,29 +147,80 @@ export class SubagentManager extends EventEmitter {
|
|
|
75
147
|
this.subagents.set(id, state);
|
|
76
148
|
this.saveState(state);
|
|
77
149
|
try {
|
|
150
|
+
// WS5 (#27) — isolation, made by the parent BEFORE the fork. A refusal is a
|
|
151
|
+
// FAILED spawn rather than an unisolated run: the caller asked for isolation
|
|
152
|
+
// on purpose, and a run that silently happened in the real tree is the exact
|
|
153
|
+
// outcome this capability exists to prevent.
|
|
154
|
+
if (config.worktree) {
|
|
155
|
+
const repoCwd = config.cwd || process.cwd();
|
|
156
|
+
worktree = createIsolatedWorktree({ repoCwd, label: config.goal });
|
|
157
|
+
if (!worktree) {
|
|
158
|
+
const why = worktreeRefusal(repoCwd) ?? 'the worktree could not be created';
|
|
159
|
+
throw new Error(`Cannot isolate this subagent: ${why}`);
|
|
160
|
+
}
|
|
161
|
+
state.worktree = worktree.dir;
|
|
162
|
+
state.worktreeBase = worktree.base;
|
|
163
|
+
this.worktrees.set(id, { handle: worktree, keep: config.keepWorktree === true });
|
|
164
|
+
this.emit('progress', id, {
|
|
165
|
+
phase: 'worktree',
|
|
166
|
+
dir: worktree.dir,
|
|
167
|
+
base: worktree.base,
|
|
168
|
+
sourceDirty: worktree.sourceDirty,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
78
171
|
// Spawn child process
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
172
|
+
const { entry, execArgv } = resolveChildEntry();
|
|
173
|
+
// WS3 (#25) — hand the child the trace it belongs to. The loop makes the
|
|
174
|
+
// tool span ACTIVE around this call, so `childTraceEnv()` reads the real
|
|
175
|
+
// parent out of the active context (never out of module state, which two
|
|
176
|
+
// interleaved turns in one server would share). It is set or DELETED
|
|
177
|
+
// explicitly rather than merged: a `TRACEPARENT` inherited from this
|
|
178
|
+
// process's own environment is not the child's parent, and a stale one
|
|
179
|
+
// would graft the child onto a trace nobody is running.
|
|
180
|
+
const traceEnv = childTraceEnv();
|
|
181
|
+
const childEnv = {
|
|
182
|
+
...process.env,
|
|
183
|
+
...config.env,
|
|
184
|
+
SUBAGENT_ID: id,
|
|
185
|
+
SUBAGENT_GOAL: config.goal,
|
|
186
|
+
SUBAGENT_PROVIDER: config.provider || 'auto',
|
|
187
|
+
SUBAGENT_MODEL: config.model || 'auto',
|
|
188
|
+
SUBAGENT_MAX_LLM_CALLS: String(config.maxLlmCalls || 50),
|
|
189
|
+
SUBAGENT_MAX_TOKENS: String(config.maxTokens || 100_000),
|
|
190
|
+
SUBAGENT_TOOLS: JSON.stringify(config.tools || []),
|
|
191
|
+
SUBAGENT_BLOCKED_TOOLS: JSON.stringify(config.blockedTools || []),
|
|
192
|
+
};
|
|
193
|
+
const traceparent = traceEnv[TRACEPARENT_ENV];
|
|
194
|
+
if (traceparent)
|
|
195
|
+
childEnv[TRACEPARENT_ENV] = traceparent;
|
|
196
|
+
else
|
|
197
|
+
delete childEnv[TRACEPARENT_ENV];
|
|
198
|
+
// WS5 — the resume request travels as the environment the child resolves it
|
|
199
|
+
// from. INHERITED when the caller does not name one (unlike the traceparent
|
|
200
|
+
// above, which is explicitly cleared): a parent run that was asked to resume
|
|
201
|
+
// is asking for its children's model calls to be replayed too, and a child
|
|
202
|
+
// with no record of its own simply records a fresh one. An explicit
|
|
203
|
+
// `false` is how a caller opts a child out of that.
|
|
204
|
+
// WS5 — the child's cwd IS the isolation, and it is told so in its
|
|
205
|
+
// environment: a tool inside the run can then report which worktree it is
|
|
206
|
+
// working in instead of guessing, and a nested spawn can isolate from it.
|
|
207
|
+
if (worktree)
|
|
208
|
+
Object.assign(childEnv, worktreeEnv(worktree));
|
|
209
|
+
const child = fork(entry, [], {
|
|
210
|
+
cwd: worktree?.dir ?? config.cwd ?? process.cwd(),
|
|
211
|
+
...(execArgv ? { execArgv } : {}),
|
|
212
|
+
env: childEnv,
|
|
93
213
|
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
94
214
|
});
|
|
215
|
+
logger.info(`Subagent: forked ${entry}${execArgv ? ` (via ${execArgv.join(' ')})` : ''}`);
|
|
95
216
|
state.pid = child.pid;
|
|
96
217
|
state.status = 'running';
|
|
97
218
|
this.processes.set(id, child);
|
|
98
|
-
// Set up log file
|
|
219
|
+
// Set up log file. This used to be `require('node:fs')` INSIDE an ESM
|
|
220
|
+
// module, so it threw `require is not defined` immediately after the fork
|
|
221
|
+
// and `spawn()` rejected before the child was ever tracked.
|
|
99
222
|
const logFile = join(LOG_DIR, `${id}.log`);
|
|
100
|
-
const logStream =
|
|
223
|
+
const logStream = createWriteStream(logFile, { flags: 'a' });
|
|
101
224
|
// Pipe stdout/stderr to log file
|
|
102
225
|
child.stdout?.pipe(logStream);
|
|
103
226
|
child.stderr?.pipe(logStream);
|
|
@@ -131,6 +254,15 @@ export class SubagentManager extends EventEmitter {
|
|
|
131
254
|
return state;
|
|
132
255
|
}
|
|
133
256
|
catch (err) {
|
|
257
|
+
// A spawn that failed AFTER the worktree was made leaves nothing behind:
|
|
258
|
+
// the run never happened, so neither should its directory.
|
|
259
|
+
if (worktree) {
|
|
260
|
+
const kept = this.worktrees.get(id)?.keep === true;
|
|
261
|
+
if (!kept)
|
|
262
|
+
discardWorktree(worktree, { timeoutMs: WORKTREE_EXIT_TIMEOUT_MS });
|
|
263
|
+
if (!kept)
|
|
264
|
+
this.worktrees.delete(id);
|
|
265
|
+
}
|
|
134
266
|
state.status = 'failed';
|
|
135
267
|
state.error = String(err);
|
|
136
268
|
state.endedAt = Date.now();
|
|
@@ -232,6 +364,17 @@ export class SubagentManager extends EventEmitter {
|
|
|
232
364
|
state.llmCalls = msg.llmCalls || state.llmCalls;
|
|
233
365
|
state.tokensUsed = msg.tokensUsed || state.tokensUsed;
|
|
234
366
|
state.toolCalls = msg.toolCalls || state.toolCalls;
|
|
367
|
+
// WS1 — a finding the child recorded. Appended, never replaced: a run
|
|
368
|
+
// can record several, and the order is part of what it did.
|
|
369
|
+
if (msg.finding && typeof msg.finding === 'object') {
|
|
370
|
+
state.findings = [...(state.findings ?? []), msg.finding];
|
|
371
|
+
}
|
|
372
|
+
// WS5 (#27) — the child's own resume report. A frame, not a return value:
|
|
373
|
+
// the child is a separate process, and this is its only channel back.
|
|
374
|
+
if (msg.resume && typeof msg.resume === 'object') {
|
|
375
|
+
state.resume = msg.resume;
|
|
376
|
+
}
|
|
377
|
+
this.recordIdentity(state, msg);
|
|
235
378
|
this.saveState(state);
|
|
236
379
|
this.emit('progress', id, msg);
|
|
237
380
|
break;
|
|
@@ -240,25 +383,80 @@ export class SubagentManager extends EventEmitter {
|
|
|
240
383
|
state.llmCalls = msg.llmCalls || state.llmCalls;
|
|
241
384
|
state.tokensUsed = msg.tokensUsed || state.tokensUsed;
|
|
242
385
|
state.toolCalls = msg.toolCalls || state.toolCalls;
|
|
386
|
+
// G1 — the child's verification verdict, read off its result frame. Only
|
|
387
|
+
// a truthy flag is recorded: the child omits it when the edit WAS verified,
|
|
388
|
+
// so `undefined` here means "not claimed", and never `false`.
|
|
389
|
+
if (msg.unverifiedEdit === true)
|
|
390
|
+
state.unverifiedEdit = true;
|
|
391
|
+
if (msg.unverifiedEditClaim === true)
|
|
392
|
+
state.unverifiedEditClaim = true;
|
|
393
|
+
this.recordIdentity(state, msg);
|
|
394
|
+
this.saveState(state);
|
|
395
|
+
break;
|
|
396
|
+
case 'error':
|
|
397
|
+
// The child's OWN reason. Without this the message was dropped and the
|
|
398
|
+
// parent could only report "Exit code 1".
|
|
399
|
+
state.error = msg.error || 'Subagent reported an error';
|
|
400
|
+
if (msg.code)
|
|
401
|
+
state.refusalCode = msg.code;
|
|
402
|
+
this.recordIdentity(state, msg);
|
|
403
|
+
this.saveState(state);
|
|
243
404
|
break;
|
|
244
405
|
}
|
|
245
406
|
}
|
|
407
|
+
/**
|
|
408
|
+
* Record which provider/model/transport the child is serving this run with.
|
|
409
|
+
*
|
|
410
|
+
* The child announces them on its FIRST frame — before it can fail — and repeats
|
|
411
|
+
* them on the result and error frames. Recording from every frame (not just the
|
|
412
|
+
* result) is what makes a FAILED run attributable: a subagent that its provider
|
|
413
|
+
* rejected used to land as a bare error with no provider, model or transport, so
|
|
414
|
+
* the dashboard showed a failure with nothing to debug it by — exactly backwards,
|
|
415
|
+
* since a run that produced no output is the one that needs the attribution.
|
|
416
|
+
*/
|
|
417
|
+
recordIdentity(state, msg) {
|
|
418
|
+
if (msg.provider)
|
|
419
|
+
state.provider = String(msg.provider);
|
|
420
|
+
if (msg.model)
|
|
421
|
+
state.model = String(msg.model);
|
|
422
|
+
if (msg.transport)
|
|
423
|
+
state.transport = String(msg.transport);
|
|
424
|
+
}
|
|
246
425
|
handleExit(id, code, signal) {
|
|
247
426
|
const state = this.subagents.get(id);
|
|
248
427
|
if (!state)
|
|
249
428
|
return;
|
|
250
429
|
state.endedAt = Date.now();
|
|
251
430
|
state.durationMs = state.endedAt - state.startedAt;
|
|
252
|
-
if (state.
|
|
253
|
-
|
|
431
|
+
if (state.status === 'killed' || state.status === 'timeout') {
|
|
432
|
+
// The killer already recorded why; do not overwrite it with an exit code.
|
|
254
433
|
}
|
|
255
|
-
else if (
|
|
256
|
-
|
|
257
|
-
state.
|
|
434
|
+
else if (state.error) {
|
|
435
|
+
// The child said why it failed — that reason outranks its exit code.
|
|
436
|
+
state.status = 'failed';
|
|
258
437
|
}
|
|
259
438
|
else {
|
|
260
|
-
state.
|
|
261
|
-
state.
|
|
439
|
+
const outcome = classifyChildExit(state.result, code, signal);
|
|
440
|
+
state.status = outcome.status;
|
|
441
|
+
if (outcome.error)
|
|
442
|
+
state.error = outcome.error;
|
|
443
|
+
}
|
|
444
|
+
// WS5 (#27) — what an isolated run changed, measured from the parent, and the
|
|
445
|
+
// teardown. Both happen BEFORE the result is built and emitted, so the diff
|
|
446
|
+
// rides on the result its caller is waiting for: a diff reported later (or by
|
|
447
|
+
// a separate command) is a diff most callers never see. A KILLED run is
|
|
448
|
+
// measured too — "what had it changed when you stopped it" is exactly the
|
|
449
|
+
// question a teardown needs answered.
|
|
450
|
+
const isolated = this.worktrees.get(id);
|
|
451
|
+
if (isolated) {
|
|
452
|
+
state.worktreeDiff = worktreeDiff(isolated.handle, { timeoutMs: WORKTREE_EXIT_TIMEOUT_MS });
|
|
453
|
+
if (isolated.keep) {
|
|
454
|
+
state.worktreeRemoved = false;
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
state.worktreeRemoved = discardWorktree(isolated.handle, { timeoutMs: WORKTREE_EXIT_TIMEOUT_MS });
|
|
458
|
+
}
|
|
459
|
+
this.worktrees.delete(id);
|
|
262
460
|
}
|
|
263
461
|
this.saveState(state);
|
|
264
462
|
this.processes.delete(id);
|
|
@@ -269,8 +467,13 @@ export class SubagentManager extends EventEmitter {
|
|
|
269
467
|
this.emit(`completed:${id}`, result);
|
|
270
468
|
}
|
|
271
469
|
else {
|
|
272
|
-
|
|
273
|
-
|
|
470
|
+
// The child's typed refusal (when it reported one) rides on the error, so
|
|
471
|
+
// `waitForCompletion`'s rejection is actionable instead of a bare message.
|
|
472
|
+
const failure = new Error(state.error);
|
|
473
|
+
if (state.refusalCode)
|
|
474
|
+
failure.code = state.refusalCode;
|
|
475
|
+
this.emit('failed', id, failure);
|
|
476
|
+
this.emit(`failed:${id}`, failure);
|
|
274
477
|
}
|
|
275
478
|
}
|
|
276
479
|
buildResult(state) {
|
|
@@ -279,6 +482,24 @@ export class SubagentManager extends EventEmitter {
|
|
|
279
482
|
success: state.status === 'completed',
|
|
280
483
|
result: state.result || '',
|
|
281
484
|
error: state.error,
|
|
485
|
+
...(state.refusalCode ? { refusalCode: state.refusalCode } : {}),
|
|
486
|
+
...(state.provider ? { provider: state.provider } : {}),
|
|
487
|
+
...(state.model ? { model: state.model } : {}),
|
|
488
|
+
...(state.transport ? { transport: state.transport } : {}),
|
|
489
|
+
...(state.findings && state.findings.length > 0 ? { findings: state.findings } : {}),
|
|
490
|
+
...(state.resume ? { resume: state.resume } : {}),
|
|
491
|
+
...(state.unverifiedEdit ? { unverifiedEdit: true } : {}),
|
|
492
|
+
...(state.unverifiedEditClaim ? { unverifiedEditClaim: true } : {}),
|
|
493
|
+
...(state.worktree && state.worktreeBase && state.worktreeDiff
|
|
494
|
+
? {
|
|
495
|
+
worktree: {
|
|
496
|
+
dir: state.worktree,
|
|
497
|
+
base: state.worktreeBase,
|
|
498
|
+
diff: state.worktreeDiff,
|
|
499
|
+
removed: state.worktreeRemoved === true,
|
|
500
|
+
},
|
|
501
|
+
}
|
|
502
|
+
: {}),
|
|
282
503
|
llmCalls: state.llmCalls,
|
|
283
504
|
tokensUsed: state.tokensUsed,
|
|
284
505
|
toolCalls: state.toolCalls,
|