@stigmer/runner 3.15.0 → 3.15.2-dev.20260913223433
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -4
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +14 -0
- package/dist/__test-utils__/execution-record-fixture.js +4 -0
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
- package/dist/__test-utils__/file-review-projection.d.ts +40 -0
- package/dist/__test-utils__/file-review-projection.js +136 -0
- package/dist/__test-utils__/file-review-projection.js.map +1 -0
- package/dist/__test-utils__/harness-contract/types.d.ts +23 -1
- package/dist/__test-utils__/harness-contract/types.js +15 -0
- package/dist/__test-utils__/harness-contract/types.js.map +1 -1
- package/dist/__test-utils__/hermetic-activity.d.ts +44 -12
- package/dist/__test-utils__/hermetic-activity.js +52 -14
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/model-registry-fixture.d.ts +32 -7
- package/dist/__test-utils__/model-registry-fixture.js +31 -7
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
- package/dist/__test-utils__/turn-input-fixture.d.ts +1 -1
- package/dist/__test-utils__/turn-input-fixture.js +1 -1
- package/dist/__test-utils__/turn-input-fixture.js.map +1 -1
- package/dist/activities/call-agent.js +2 -2
- package/dist/activities/call-agent.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +45 -3
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +0 -9
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +2 -41
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +7 -5
- package/dist/activities/execute-cursor/adapter.js +7 -5
- package/dist/activities/execute-cursor/adapter.js.map +1 -1
- package/dist/activities/execute-cursor/approval-policy.d.ts +5 -2
- package/dist/activities/execute-cursor/approval-policy.js +5 -2
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +16 -8
- package/dist/activities/execute-cursor/approval-state.js +6 -3
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/cas-observations.d.ts +14 -2
- package/dist/activities/execute-cursor/cas-observations.js +19 -2
- package/dist/activities/execute-cursor/cas-observations.js.map +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +8 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js +21 -4
- package/dist/activities/execute-cursor/cursor-capabilities.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +12 -20
- package/dist/activities/execute-cursor/message-translator.js +19 -32
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +48 -58
- package/dist/activities/execute-cursor/prompt-builder.js +76 -95
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/turn-boundary.d.ts +27 -55
- package/dist/activities/execute-cursor/turn-boundary.js +30 -90
- package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
- package/dist/activities/execute-cursor/turn-settle.d.ts +11 -7
- package/dist/activities/execute-cursor/turn-settle.js +37 -49
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-setup.d.ts +16 -24
- package/dist/activities/execute-cursor/turn-setup.js +29 -59
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.d.ts +3 -8
- package/dist/activities/execute-cursor/turn-stream.js +9 -22
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.js +5 -1
- package/dist/activities/execute-cursor/turn.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +93 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +348 -0
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +170 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +225 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.d.ts +24 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +41 -0
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +54 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +72 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -0
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +187 -23
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +238 -27
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
- package/dist/activities/execute-deep-agent/adapter.d.ts +41 -0
- package/dist/activities/execute-deep-agent/adapter.js +78 -0
- package/dist/activities/execute-deep-agent/adapter.js.map +1 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.d.ts +8 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js +9 -0
- package/dist/activities/execute-deep-agent/cas-capture-observer.js.map +1 -1
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +31 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +40 -0
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js.map +1 -0
- package/dist/activities/execute-deep-agent/execution-state.d.ts +4 -11
- package/dist/activities/execute-deep-agent/execution-state.js +4 -12
- package/dist/activities/execute-deep-agent/execution-state.js.map +1 -1
- package/dist/activities/execute-deep-agent/hitl.d.ts +49 -47
- package/dist/activities/execute-deep-agent/hitl.js +77 -103
- package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +51 -23
- package/dist/activities/execute-deep-agent/prompt-builder.js +115 -76
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +18 -32
- package/dist/activities/execute-deep-agent/status-builder-shared.js +10 -65
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +10 -8
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +12 -14
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +36 -13
- package/dist/activities/execute-deep-agent/subagent-tracker.js +76 -39
- package/dist/activities/execute-deep-agent/subagent-tracker.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +25 -28
- package/dist/activities/execute-deep-agent/subagent-transformer.js +29 -82
- package/dist/activities/execute-deep-agent/subagent-transformer.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-wiring.d.ts +3 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js +2 -2
- package/dist/activities/execute-deep-agent/subagent-wiring.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-settle.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn-settle.js +146 -0
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +212 -0
- package/dist/activities/execute-deep-agent/turn-setup.js +430 -0
- package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +97 -0
- package/dist/activities/execute-deep-agent/turn-stream.js +242 -0
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn.d.ts +42 -0
- package/dist/activities/execute-deep-agent/turn.js +116 -0
- package/dist/activities/execute-deep-agent/turn.js.map +1 -0
- package/dist/activities/execute-deep-agent/v3-event-recorder.d.ts +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js +6 -5
- package/dist/activities/execute-deep-agent/v3-event-recorder.js.map +1 -1
- package/dist/activities/execute-deep-agent/v3-events.d.ts +1 -1
- package/dist/activities/execute-deep-agent/v3-events.js +1 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +60 -17
- package/dist/activities/execute-deep-agent/v3-status-builder.js +72 -57
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
- package/dist/harness/approval-decisions.d.ts +61 -0
- package/dist/harness/approval-decisions.js +102 -0
- package/dist/harness/approval-decisions.js.map +1 -0
- package/dist/harness/capabilities.d.ts +16 -5
- package/dist/harness/capabilities.js +9 -0
- package/dist/harness/capabilities.js.map +1 -1
- package/dist/harness/capture.d.ts +144 -0
- package/dist/harness/capture.js +219 -0
- package/dist/harness/capture.js.map +1 -0
- package/dist/harness/persist-chokepoint.d.ts +19 -4
- package/dist/harness/persist-chokepoint.js +17 -4
- package/dist/harness/persist-chokepoint.js.map +1 -1
- package/dist/harness/run-turn.js +115 -29
- package/dist/harness/run-turn.js.map +1 -1
- package/dist/harness/terminal-table.d.ts +40 -11
- package/dist/harness/terminal-table.js +58 -19
- package/dist/harness/terminal-table.js.map +1 -1
- package/dist/harness/turn-context.d.ts +141 -76
- package/dist/harness/turn-context.js +194 -99
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/harness/types.d.ts +65 -12
- package/dist/harness/types.js +8 -2
- package/dist/harness/types.js.map +1 -1
- package/dist/harness-adapters.d.ts +12 -8
- package/dist/harness-adapters.js +17 -9
- package/dist/harness-adapters.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +1 -1
- package/dist/middleware/approval-gate.js +1 -1
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +39 -0
- package/dist/middleware/{cost-cap.js → cost-advisory.js} +37 -55
- package/dist/middleware/cost-advisory.js.map +1 -0
- package/dist/middleware/index.d.ts +23 -12
- package/dist/middleware/index.js +26 -18
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/types.d.ts +3 -2
- package/dist/runner-manager.js +1 -5
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.js +1 -5
- package/dist/runner.js.map +1 -1
- package/dist/shared/attachment-resolver.d.ts +41 -18
- package/dist/shared/attachment-resolver.js +178 -46
- package/dist/shared/attachment-resolver.js.map +1 -1
- package/dist/shared/attachment-zip.d.ts +85 -0
- package/dist/shared/attachment-zip.js +185 -0
- package/dist/shared/attachment-zip.js.map +1 -0
- package/dist/shared/connect-backfill.js +5 -4
- package/dist/shared/connect-backfill.js.map +1 -1
- package/dist/shared/cost-guard.d.ts +3 -3
- package/dist/shared/cost-guard.js +3 -3
- package/dist/shared/execution-status-writer.d.ts +5 -5
- package/dist/shared/execution-status-writer.js +5 -5
- package/dist/shared/extract-structured-output.d.ts +8 -7
- package/dist/shared/extract-structured-output.js +8 -7
- package/dist/shared/extract-structured-output.js.map +1 -1
- package/dist/shared/filereview/cas-progress.d.ts +1 -18
- package/dist/shared/filereview/cas-progress.js +4 -0
- package/dist/shared/filereview/cas-progress.js.map +1 -1
- package/dist/shared/filereview/cas-touched.d.ts +56 -0
- package/dist/shared/filereview/cas-touched.js +63 -0
- package/dist/shared/filereview/cas-touched.js.map +1 -0
- package/dist/shared/filereview/index.d.ts +2 -1
- package/dist/shared/filereview/index.js +2 -1
- package/dist/shared/filereview/index.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +4 -5
- package/dist/shared/mcp-resolver.js +4 -5
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/persist-decision.d.ts +3 -4
- package/dist/shared/persist-decision.js +3 -4
- package/dist/shared/persist-decision.js.map +1 -1
- package/dist/shared/plan-mode-permissions.d.ts +2 -2
- package/dist/shared/plan-mode-permissions.js +2 -2
- package/dist/shared/plan-mode-prompt.d.ts +1 -1
- package/dist/shared/plan-mode-prompt.js +1 -1
- package/dist/shared/prompt-sections.d.ts +163 -0
- package/dist/shared/prompt-sections.js +164 -0
- package/dist/shared/prompt-sections.js.map +1 -0
- package/dist/shared/skill-resolver.d.ts +4 -2
- package/dist/shared/skill-resolver.js +4 -2
- package/dist/shared/skill-resolver.js.map +1 -1
- package/dist/shared/tool-rounds.d.ts +32 -0
- package/dist/shared/tool-rounds.js +43 -0
- package/dist/shared/tool-rounds.js.map +1 -1
- package/dist/shared/tool-row.d.ts +34 -0
- package/dist/shared/tool-row.js +52 -0
- package/dist/shared/tool-row.js.map +1 -1
- package/dist/shared/workspace/session-provision.d.ts +3 -3
- package/dist/shared/workspace/session-provision.js +3 -3
- package/dist/shared/workspace/stigmer-link.d.ts +3 -3
- package/dist/shared/workspace/stigmer-link.js +3 -3
- package/dist/shared/workspace/writeback-coordinator.d.ts +15 -22
- package/dist/shared/workspace/writeback-coordinator.js +16 -53
- package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.js +1 -1
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +1 -0
- package/src/__test-utils__/execution-record-fixture.ts +18 -2
- package/src/__test-utils__/file-review-projection.ts +156 -0
- package/src/__test-utils__/git-workspace-fixture.ts +58 -0
- package/src/__test-utils__/harness-boot-order-child.ts +7 -2
- package/src/__test-utils__/harness-contract/contract.ts +33 -20
- package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +328 -10
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +38 -6
- package/src/__test-utils__/harness-contract/types.ts +27 -3
- package/src/__test-utils__/hermetic-activity.ts +52 -14
- package/src/__test-utils__/model-registry-fixture.ts +32 -7
- package/src/__test-utils__/module-specifiers.ts +24 -0
- package/src/__test-utils__/turn-input-fixture.ts +2 -2
- package/src/__tests__/harness-boot-order.test.ts +9 -2
- package/src/activities/call-agent.ts +2 -2
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +47 -3
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +2 -48
- package/src/activities/execute-cursor/__tests__/approval-decisions-agree.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +6 -1
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +52 -27
- package/src/activities/execute-cursor/__tests__/cas-observations.test.ts +25 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.everything.prompt.md +166 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.enhanced.plan-mode.prompt.md +186 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.recovery.prompt.md +191 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.hitl.reinvocation.prompt.md +13 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.prefixed.prompt.md +32 -0
- package/src/activities/execute-cursor/__tests__/goldens/prompt.resumed.raw.prompt.md +1 -0
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-error-at-create.status.json +4 -0
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +24 -4
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +6 -5
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +9 -0
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +11 -8
- package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +229 -0
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +2 -2
- package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +78 -234
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +1 -26
- package/src/activities/execute-cursor/adapter.ts +7 -5
- package/src/activities/execute-cursor/approval-policy.ts +5 -2
- package/src/activities/execute-cursor/approval-state.ts +16 -8
- package/src/activities/execute-cursor/cas-observations.ts +20 -2
- package/src/activities/execute-cursor/cursor-capabilities.ts +24 -5
- package/src/activities/execute-cursor/message-translator.ts +29 -41
- package/src/activities/execute-cursor/prompt-builder.ts +99 -157
- package/src/activities/execute-cursor/turn-boundary.ts +34 -140
- package/src/activities/execute-cursor/turn-settle.ts +37 -51
- package/src/activities/execute-cursor/turn-setup.ts +30 -70
- package/src/activities/execute-cursor/turn-stream.ts +8 -31
- package/src/activities/execute-cursor/turn.ts +5 -1
- package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +391 -0
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +313 -0
- package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +48 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +85 -0
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +383 -36
- package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +76 -0
- package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +47 -0
- package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +80 -0
- package/src/activities/execute-deep-agent/__tests__/cas-capture-backend.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -2
- package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -3
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +172 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +167 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.minimal.prompt.md +36 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +178 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +158 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +210 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +74 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +104 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +78 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +138 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +154 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +116 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +69 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +67 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/plain-turn.status.json +47 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +68 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +280 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +77 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +18 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +99 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +109 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +76 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.text-fallback.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tier2.status.json +51 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/structured-output.tool-strategy.status.json +56 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +90 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +70 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +71 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +144 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +184 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +203 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +170 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +175 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +206 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +142 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +126 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +139 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +122 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +236 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +161 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +157 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +152 -0
- package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +50 -122
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +8 -6
- package/src/activities/execute-deep-agent/__tests__/plan-mode-path-normalization.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +35 -35
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +247 -0
- package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +329 -0
- package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +1 -20
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +78 -0
- package/src/activities/execute-deep-agent/__tests__/subagent-gitignored-capture.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/subagent-plan-mode-permissions.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/subagent-tracker.test.ts +57 -31
- package/src/activities/execute-deep-agent/__tests__/subagent-transformer.test.ts +19 -79
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +15 -15
- package/src/activities/execute-deep-agent/__tests__/summarization-verification.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +391 -0
- package/src/activities/execute-deep-agent/__tests__/v3-status-builder.test.ts +343 -38
- package/src/activities/execute-deep-agent/__tests__/vision-input.test.ts +5 -5
- package/src/activities/execute-deep-agent/adapter.ts +94 -0
- package/src/activities/execute-deep-agent/cas-capture-observer.ts +11 -0
- package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +43 -0
- package/src/activities/execute-deep-agent/execution-state.ts +4 -13
- package/src/activities/execute-deep-agent/hitl.ts +100 -123
- package/src/activities/execute-deep-agent/prompt-builder.ts +141 -115
- package/src/activities/execute-deep-agent/status-builder-shared.ts +21 -84
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +13 -19
- package/src/activities/execute-deep-agent/subagent-tracker.ts +77 -42
- package/src/activities/execute-deep-agent/subagent-transformer.ts +46 -105
- package/src/activities/execute-deep-agent/subagent-wiring.ts +5 -4
- package/src/activities/execute-deep-agent/turn-settle.ts +164 -0
- package/src/activities/execute-deep-agent/turn-setup.ts +541 -0
- package/src/activities/execute-deep-agent/turn-stream.ts +313 -0
- package/src/activities/execute-deep-agent/turn.ts +131 -0
- package/src/activities/execute-deep-agent/v3-event-recorder.ts +6 -5
- package/src/activities/execute-deep-agent/v3-events.ts +1 -1
- package/src/activities/execute-deep-agent/v3-status-builder.ts +84 -63
- package/src/harness/__tests__/approval-decisions.test.ts +116 -0
- package/src/harness/__tests__/capture.test.ts +268 -0
- package/src/harness/__tests__/mount-skills.test.ts +169 -0
- package/src/harness/__tests__/persist-chokepoint.test.ts +38 -2
- package/src/harness/__tests__/run-turn-deterministic.test.ts +94 -0
- package/src/harness/__tests__/run-turn.test.ts +39 -23
- package/src/harness/__tests__/turn-attachments-vision.test.ts +80 -0
- package/src/harness/__tests__/turn-context.test.ts +73 -26
- package/src/harness/approval-decisions.ts +104 -0
- package/src/harness/capabilities.ts +16 -5
- package/src/harness/capture.ts +301 -0
- package/src/harness/persist-chokepoint.ts +24 -4
- package/src/harness/run-turn.ts +120 -29
- package/src/harness/terminal-table.ts +61 -20
- package/src/harness/turn-context.ts +208 -111
- package/src/harness/types.ts +66 -12
- package/src/harness-adapters.ts +17 -9
- package/src/middleware/__tests__/approval-gate.test.ts +1 -1
- package/src/middleware/__tests__/cost-advisory.test.ts +113 -0
- package/src/middleware/approval-gate.ts +2 -2
- package/src/middleware/{cost-cap.ts → cost-advisory.ts} +40 -70
- package/src/middleware/index.ts +29 -29
- package/src/middleware/types.ts +3 -2
- package/src/runner-manager.ts +0 -8
- package/src/runner.ts +0 -8
- package/src/shared/__tests__/attachment-naming.test.ts +6 -19
- package/src/shared/__tests__/attachment-resolver.test.ts +158 -8
- package/src/shared/__tests__/attachment-zip.test.ts +236 -0
- package/src/shared/__tests__/bedrock-adapter.test.ts +1 -1
- package/src/shared/__tests__/blueprint-resolver.test.ts +43 -0
- package/src/shared/__tests__/cost-guard.test.ts +3 -3
- package/src/shared/__tests__/prompt-sections.test.ts +167 -0
- package/src/shared/__tests__/secret-leak-scan.test.ts +2 -2
- package/src/{activities/execute-deep-agent → shared}/__tests__/stamp-flowed-rows.test.ts +33 -10
- package/src/shared/__tests__/vertex-adapter.test.ts +1 -1
- package/src/shared/attachment-resolver.ts +218 -55
- package/src/shared/attachment-zip.ts +281 -0
- package/src/shared/connect-backfill.ts +9 -11
- package/src/shared/cost-guard.ts +3 -3
- package/src/shared/execution-status-writer.ts +5 -5
- package/src/shared/extract-structured-output.ts +8 -7
- package/src/shared/filereview/__tests__/capture.test.ts +86 -4
- package/src/shared/filereview/__tests__/cas-progress.test.ts +2 -1
- package/src/shared/filereview/cas-progress.ts +5 -19
- package/src/shared/filereview/cas-touched.ts +89 -0
- package/src/shared/filereview/index.ts +4 -2
- package/src/shared/mcp-resolver.ts +4 -5
- package/src/shared/persist-decision.ts +3 -4
- package/src/shared/plan-mode-permissions.ts +2 -2
- package/src/shared/plan-mode-prompt.ts +1 -1
- package/src/shared/prompt-sections.ts +256 -0
- package/src/shared/skill-resolver.ts +4 -2
- package/src/shared/tool-rounds.ts +48 -0
- package/src/shared/tool-row.ts +61 -0
- package/src/shared/workspace/__tests__/stigmer-link.test.ts +7 -22
- package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +20 -61
- package/src/shared/workspace/session-provision.ts +3 -3
- package/src/shared/workspace/stigmer-link.ts +3 -3
- package/src/shared/workspace/writeback-coordinator.ts +16 -64
- package/src/tools/index.ts +1 -1
- package/dist/activities/execute-cursor/capture-flow.d.ts +0 -142
- package/dist/activities/execute-cursor/capture-flow.js +0 -285
- package/dist/activities/execute-cursor/capture-flow.js.map +0 -1
- package/dist/activities/execute-cursor/command-provenance.d.ts +0 -48
- package/dist/activities/execute-cursor/command-provenance.js +0 -38
- package/dist/activities/execute-cursor/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/attachment-injector.d.ts +0 -134
- package/dist/activities/execute-deep-agent/attachment-injector.js +0 -386
- package/dist/activities/execute-deep-agent/attachment-injector.js.map +0 -1
- package/dist/activities/execute-deep-agent/command-provenance.d.ts +0 -61
- package/dist/activities/execute-deep-agent/command-provenance.js +0 -72
- package/dist/activities/execute-deep-agent/command-provenance.js.map +0 -1
- package/dist/activities/execute-deep-agent/environment.d.ts +0 -24
- package/dist/activities/execute-deep-agent/environment.js +0 -58
- package/dist/activities/execute-deep-agent/environment.js.map +0 -1
- package/dist/activities/execute-deep-agent/event-recorder.d.ts +0 -21
- package/dist/activities/execute-deep-agent/event-recorder.js +0 -67
- package/dist/activities/execute-deep-agent/event-recorder.js.map +0 -1
- package/dist/activities/execute-deep-agent/index.d.ts +0 -15
- package/dist/activities/execute-deep-agent/index.js +0 -918
- package/dist/activities/execute-deep-agent/index.js.map +0 -1
- package/dist/activities/execute-deep-agent/mcp-gate.d.ts +0 -28
- package/dist/activities/execute-deep-agent/mcp-gate.js +0 -22
- package/dist/activities/execute-deep-agent/mcp-gate.js.map +0 -1
- package/dist/activities/execute-deep-agent/post-stream.d.ts +0 -23
- package/dist/activities/execute-deep-agent/post-stream.js +0 -71
- package/dist/activities/execute-deep-agent/post-stream.js.map +0 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +0 -136
- package/dist/activities/execute-deep-agent/setup.js +0 -767
- package/dist/activities/execute-deep-agent/setup.js.map +0 -1
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.d.ts +0 -36
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js +0 -56
- package/dist/activities/execute-deep-agent/stamp-flowed-rows.js.map +0 -1
- package/dist/activities/execute-deep-agent/status-builder.d.ts +0 -93
- package/dist/activities/execute-deep-agent/status-builder.js +0 -365
- package/dist/activities/execute-deep-agent/status-builder.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-terminal.d.ts +0 -21
- package/dist/activities/execute-deep-agent/streaming-terminal.js +0 -80
- package/dist/activities/execute-deep-agent/streaming-terminal.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming-v3.d.ts +0 -13
- package/dist/activities/execute-deep-agent/streaming-v3.js +0 -174
- package/dist/activities/execute-deep-agent/streaming-v3.js.map +0 -1
- package/dist/activities/execute-deep-agent/streaming.d.ts +0 -81
- package/dist/activities/execute-deep-agent/streaming.js +0 -160
- package/dist/activities/execute-deep-agent/streaming.js.map +0 -1
- package/dist/middleware/cost-cap.d.ts +0 -22
- package/dist/middleware/cost-cap.js.map +0 -1
- package/dist/middleware/graceful-stop.d.ts +0 -17
- package/dist/middleware/graceful-stop.js +0 -63
- package/dist/middleware/graceful-stop.js.map +0 -1
- package/dist/shared/skill-writer.d.ts +0 -75
- package/dist/shared/skill-writer.js +0 -207
- package/dist/shared/skill-writer.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/capture-flow.test.ts +0 -1032
- package/src/activities/execute-cursor/__tests__/command-provenance.test.ts +0 -240
- package/src/activities/execute-cursor/__tests__/progress-substrate.test.ts +0 -169
- package/src/activities/execute-cursor/capture-flow.ts +0 -379
- package/src/activities/execute-cursor/command-provenance.ts +0 -73
- package/src/activities/execute-deep-agent/__tests__/attachment-injector.test.ts +0 -1161
- package/src/activities/execute-deep-agent/__tests__/command-provenance.test.ts +0 -252
- package/src/activities/execute-deep-agent/__tests__/environment.test.ts +0 -108
- package/src/activities/execute-deep-agent/__tests__/event-recorder.test.ts +0 -150
- package/src/activities/execute-deep-agent/__tests__/hitl-integration.test.ts +0 -226
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +0 -318
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +0 -351
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +0 -293
- package/src/activities/execute-deep-agent/__tests__/index.test.ts +0 -99
- package/src/activities/execute-deep-agent/__tests__/mcp-gate.test.ts +0 -44
- package/src/activities/execute-deep-agent/__tests__/post-stream.test.ts +0 -112
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +0 -358
- package/src/activities/execute-deep-agent/__tests__/status-builder.test.ts +0 -1933
- package/src/activities/execute-deep-agent/__tests__/streaming-terminal.test.ts +0 -40
- package/src/activities/execute-deep-agent/__tests__/streaming-v3.test.ts +0 -597
- package/src/activities/execute-deep-agent/__tests__/streaming.test.ts +0 -508
- package/src/activities/execute-deep-agent/attachment-injector.ts +0 -627
- package/src/activities/execute-deep-agent/command-provenance.ts +0 -102
- package/src/activities/execute-deep-agent/environment.ts +0 -76
- package/src/activities/execute-deep-agent/event-recorder.ts +0 -95
- package/src/activities/execute-deep-agent/index.ts +0 -1072
- package/src/activities/execute-deep-agent/mcp-gate.ts +0 -37
- package/src/activities/execute-deep-agent/post-stream.ts +0 -109
- package/src/activities/execute-deep-agent/setup.ts +0 -1081
- package/src/activities/execute-deep-agent/stamp-flowed-rows.ts +0 -64
- package/src/activities/execute-deep-agent/status-builder.ts +0 -481
- package/src/activities/execute-deep-agent/streaming-terminal.ts +0 -106
- package/src/activities/execute-deep-agent/streaming-v3.ts +0 -277
- package/src/activities/execute-deep-agent/streaming.ts +0 -313
- package/src/middleware/__tests__/cost-cap.test.ts +0 -192
- package/src/middleware/__tests__/graceful-stop.test.ts +0 -105
- package/src/middleware/graceful-stop.ts +0 -86
- package/src/shared/__tests__/skill-writer.test.ts +0 -372
- package/src/shared/skill-writer.ts +0 -266
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
2
|
import { create } from "@bufbuild/protobuf";
|
|
3
3
|
import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
4
|
-
import { ExecutionPhase, MessageType, ToolCallStatus, ToolKind, TodoStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
4
|
+
import { ApprovalAction, ExecutionPhase, MessageType, ToolCallStatus, ToolKind, TodoStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
5
|
+
import { AgentMessageSchema, ToolCallSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
6
|
+
import { ExecutionArtifactSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/artifact_pb";
|
|
7
|
+
import { WorkspaceWriteBackSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/writeback_pb";
|
|
5
8
|
import { V3StatusBuilder } from "../v3-status-builder.js";
|
|
6
9
|
import { normalize } from "../v3-protocol-normalizer.js";
|
|
7
|
-
import type { ApprovalPolicyProvider } from "../status-builder.js";
|
|
10
|
+
import type { ApprovalPolicyProvider } from "../status-builder-shared.js";
|
|
11
|
+
import type { MergedToolPolicy } from "../../../shared/approval-policy.js";
|
|
8
12
|
import {
|
|
9
13
|
resetSeq,
|
|
10
14
|
makeMessageStart,
|
|
@@ -20,8 +24,38 @@ import {
|
|
|
20
24
|
} from "../__test-utils__/v3-event-fixtures.js";
|
|
21
25
|
import type { V3ProtocolEvent } from "../v3-event-recorder.js";
|
|
22
26
|
|
|
27
|
+
/**
|
|
28
|
+
* What the builder REPORTED through `onUsage`, summed by the test the way an
|
|
29
|
+
* accountant would (the builder itself sums nothing and writes no
|
|
30
|
+
* `streamingUsage`; the runtime does, priced, through the sink).
|
|
31
|
+
*/
|
|
32
|
+
interface ReportedUsage {
|
|
33
|
+
inputTokens: number;
|
|
34
|
+
outputTokens: number;
|
|
35
|
+
cacheReadTokens: number;
|
|
36
|
+
cacheWriteTokens: number;
|
|
37
|
+
turnCount: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const reportedByBuilder = new WeakMap<V3StatusBuilder, ReportedUsage>();
|
|
41
|
+
|
|
23
42
|
function makeBuilder(): V3StatusBuilder {
|
|
24
|
-
|
|
43
|
+
const reported: ReportedUsage = { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, turnCount: 0 };
|
|
44
|
+
const sb = new V3StatusBuilder("exec-test", create(AgentExecutionStatusSchema, {}), {
|
|
45
|
+
onUsage: (usage) => {
|
|
46
|
+
reported.inputTokens += usage.input_tokens ?? 0;
|
|
47
|
+
reported.outputTokens += usage.output_tokens ?? 0;
|
|
48
|
+
reported.cacheReadTokens += usage.input_token_details?.cache_read ?? 0;
|
|
49
|
+
reported.cacheWriteTokens += usage.input_token_details?.cache_creation ?? 0;
|
|
50
|
+
reported.turnCount += 1;
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
reportedByBuilder.set(sb, reported);
|
|
54
|
+
return sb;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function reportedUsage(sb: V3StatusBuilder): ReportedUsage {
|
|
58
|
+
return reportedByBuilder.get(sb)!;
|
|
25
59
|
}
|
|
26
60
|
|
|
27
61
|
function feedAll(sb: V3StatusBuilder, events: V3ProtocolEvent[]): void {
|
|
@@ -39,14 +73,11 @@ describe("V3StatusBuilder", () => {
|
|
|
39
73
|
// ── Initialization ───────────────────────────────────────────────
|
|
40
74
|
|
|
41
75
|
describe("initialization", () => {
|
|
42
|
-
it("
|
|
76
|
+
it("writes neither phase nor startedAt (the turn runtime owns both; S3 M2a, Q-M2a-7)", () => {
|
|
43
77
|
const sb = makeBuilder();
|
|
44
|
-
expect(sb.currentStatus.phase).toBe(ExecutionPhase.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
it("sets startedAt on construction", () => {
|
|
48
|
-
const sb = makeBuilder();
|
|
49
|
-
expect(sb.currentStatus.startedAt).toBeTruthy();
|
|
78
|
+
expect(sb.currentStatus.phase).toBe(ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED);
|
|
79
|
+
expect(sb.currentStatus.startedAt).toBe("");
|
|
80
|
+
expect(sb.awaitingApproval).toBe(false);
|
|
50
81
|
});
|
|
51
82
|
|
|
52
83
|
it("starts with forceNextUpdate = false", () => {
|
|
@@ -95,13 +126,11 @@ describe("V3StatusBuilder", () => {
|
|
|
95
126
|
expect(status.messages[1].content).toBe("Here is more detail.");
|
|
96
127
|
expect(status.messages[1].isStreaming).toBe(false);
|
|
97
128
|
|
|
98
|
-
const usage =
|
|
99
|
-
expect(usage.inputTokens).toBe(
|
|
100
|
-
expect(usage.outputTokens).toBe(
|
|
129
|
+
const usage = reportedUsage(sb);
|
|
130
|
+
expect(usage.inputTokens).toBe(130);
|
|
131
|
+
expect(usage.outputTokens).toBe(20);
|
|
101
132
|
expect(usage.turnCount).toBe(2);
|
|
102
|
-
expect(
|
|
103
|
-
|
|
104
|
-
expect(status.phase).toBe(ExecutionPhase.EXECUTION_IN_PROGRESS);
|
|
133
|
+
expect(status.streamingUsage, "the runtime owns streamingUsage; the builder reports").toBeUndefined();
|
|
105
134
|
});
|
|
106
135
|
});
|
|
107
136
|
|
|
@@ -144,12 +173,11 @@ describe("V3StatusBuilder", () => {
|
|
|
144
173
|
expect(status.messages[2].content).toBe("Let me elaborate.");
|
|
145
174
|
expect(status.messages[2].isStreaming).toBe(false);
|
|
146
175
|
|
|
147
|
-
const usage =
|
|
148
|
-
expect(usage.inputTokens).toBe(
|
|
149
|
-
expect(usage.outputTokens).toBe(
|
|
150
|
-
expect(usage.cacheReadTokens).toBe(
|
|
176
|
+
const usage = reportedUsage(sb);
|
|
177
|
+
expect(usage.inputTokens).toBe(500);
|
|
178
|
+
expect(usage.outputTokens).toBe(120);
|
|
179
|
+
expect(usage.cacheReadTokens).toBe(50);
|
|
151
180
|
expect(usage.turnCount).toBe(2);
|
|
152
|
-
expect(usage.totalTokens).toBe(670n);
|
|
153
181
|
});
|
|
154
182
|
});
|
|
155
183
|
|
|
@@ -197,9 +225,9 @@ describe("V3StatusBuilder", () => {
|
|
|
197
225
|
expect(secondMsg.content).toBe("The file contains a main function that logs 'hello'.");
|
|
198
226
|
expect(secondMsg.toolCalls).toHaveLength(0);
|
|
199
227
|
|
|
200
|
-
const usage =
|
|
201
|
-
expect(usage.inputTokens).toBe(
|
|
202
|
-
expect(usage.outputTokens).toBe(
|
|
228
|
+
const usage = reportedUsage(sb);
|
|
229
|
+
expect(usage.inputTokens).toBe(300);
|
|
230
|
+
expect(usage.outputTokens).toBe(35);
|
|
203
231
|
expect(usage.turnCount).toBe(2);
|
|
204
232
|
});
|
|
205
233
|
});
|
|
@@ -293,7 +321,8 @@ describe("V3StatusBuilder", () => {
|
|
|
293
321
|
]);
|
|
294
322
|
|
|
295
323
|
const status = sb.currentStatus;
|
|
296
|
-
expect(
|
|
324
|
+
expect(sb.awaitingApproval, "a fact for the caller, never a phase write").toBe(true);
|
|
325
|
+
expect(status.phase).toBe(ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED);
|
|
297
326
|
|
|
298
327
|
const tc = status.messages[0].toolCalls[0];
|
|
299
328
|
expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
|
|
@@ -338,14 +367,12 @@ describe("V3StatusBuilder", () => {
|
|
|
338
367
|
}),
|
|
339
368
|
]);
|
|
340
369
|
|
|
341
|
-
const usage = sb
|
|
342
|
-
expect(usage.inputTokens).toBe(
|
|
343
|
-
expect(usage.outputTokens).toBe(
|
|
344
|
-
expect(usage.cacheWriteTokens).toBe(
|
|
345
|
-
expect(usage.cacheReadTokens).toBe(
|
|
370
|
+
const usage = reportedUsage(sb);
|
|
371
|
+
expect(usage.inputTokens).toBe(600);
|
|
372
|
+
expect(usage.outputTokens).toBe(60);
|
|
373
|
+
expect(usage.cacheWriteTokens).toBe(80);
|
|
374
|
+
expect(usage.cacheReadTokens).toBe(150);
|
|
346
375
|
expect(usage.turnCount).toBe(3);
|
|
347
|
-
expect(usage.totalTokens).toBe(890n);
|
|
348
|
-
expect(usage.observedAt).toBeTruthy();
|
|
349
376
|
});
|
|
350
377
|
});
|
|
351
378
|
|
|
@@ -406,9 +433,9 @@ describe("V3StatusBuilder", () => {
|
|
|
406
433
|
expect(status.messages[3].type).toBe(MessageType.MESSAGE_AI);
|
|
407
434
|
expect(status.messages[3].content).toBe("The research is complete.");
|
|
408
435
|
|
|
409
|
-
const usage =
|
|
410
|
-
expect(usage.inputTokens).toBe(
|
|
411
|
-
expect(usage.outputTokens).toBe(
|
|
436
|
+
const usage = reportedUsage(sb);
|
|
437
|
+
expect(usage.inputTokens).toBe(650);
|
|
438
|
+
expect(usage.outputTokens).toBe(50);
|
|
412
439
|
expect(usage.turnCount).toBe(3);
|
|
413
440
|
});
|
|
414
441
|
});
|
|
@@ -442,9 +469,9 @@ describe("V3StatusBuilder", () => {
|
|
|
442
469
|
}),
|
|
443
470
|
]);
|
|
444
471
|
|
|
445
|
-
const usage = sb
|
|
446
|
-
expect(usage.inputTokens).toBe(
|
|
447
|
-
expect(usage.outputTokens).toBe(
|
|
472
|
+
const usage = reportedUsage(sb);
|
|
473
|
+
expect(usage.inputTokens).toBe(50);
|
|
474
|
+
expect(usage.outputTokens).toBe(10);
|
|
448
475
|
expect(usage.turnCount).toBe(1);
|
|
449
476
|
});
|
|
450
477
|
|
|
@@ -586,6 +613,26 @@ describe("V3StatusBuilder", () => {
|
|
|
586
613
|
expect(todos["todo-0"].status).toBe(TodoStatus.TODO_COMPLETED);
|
|
587
614
|
});
|
|
588
615
|
|
|
616
|
+
it("reports a sub-agent's usage through the same hook as the parent's (S3 M2b, Q-M2b-1)", () => {
|
|
617
|
+
const sb = makeBuilder();
|
|
618
|
+
const subNs = ["tools:task-1", "model_request:sub-run"];
|
|
619
|
+
feedAll(sb, [
|
|
620
|
+
...[makeMessageStart("parent-1"), makeTextDelta("parent-1", "Delegating."), makeMessageFinish("parent-1", { usage: { input_tokens: 1_000, output_tokens: 10 } })],
|
|
621
|
+
makeToolStarted("task-1", "task", { subagent_type: "worker", description: "delegate" }),
|
|
622
|
+
makeMessageStart("sub-run", { namespace: subNs }),
|
|
623
|
+
makeTextDelta("sub-run", "Working on it.", { namespace: subNs }),
|
|
624
|
+
makeMessageFinish("sub-run", { namespace: subNs, usage: { input_tokens: 600, output_tokens: 12 } }),
|
|
625
|
+
]);
|
|
626
|
+
|
|
627
|
+
const usage = reportedUsage(sb);
|
|
628
|
+
expect(usage.inputTokens, "the parent's 1,000 and the sub-agent's 600").toBe(1_600);
|
|
629
|
+
expect(usage.outputTokens).toBe(22);
|
|
630
|
+
expect(usage.turnCount).toBe(2);
|
|
631
|
+
// The transcript still routes the sub-agent's message to its own row, never the parent's.
|
|
632
|
+
expect(sb.currentStatus.messages.map((m) => m.content)).toEqual(["Delegating."]);
|
|
633
|
+
expect(sb.currentStatus.subAgentExecutions).toHaveLength(1);
|
|
634
|
+
});
|
|
635
|
+
|
|
589
636
|
it("does not project a sub-agent's write_todos into parent status.todos", () => {
|
|
590
637
|
const sb = makeBuilder();
|
|
591
638
|
const subNs = ["tools:task-1", "tools:sub-todo"];
|
|
@@ -608,4 +655,262 @@ describe("V3StatusBuilder", () => {
|
|
|
608
655
|
expect(Object.keys(sb.currentStatus.todos)).toHaveLength(0);
|
|
609
656
|
});
|
|
610
657
|
});
|
|
658
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
659
|
+
// Carried from the v2 StatusBuilder's suite when that builder retired
|
|
660
|
+
// with the v2 stream (S3 M2b, Q-S3-1 / Q-M2b-5): every rule below is the
|
|
661
|
+
// builder's own — how a policy decides a row's status, what the row
|
|
662
|
+
// carries, how a seeded row is resolved, how artifacts and write-backs
|
|
663
|
+
// are upserted — and had no v3 twin. The sanitizer's own rules
|
|
664
|
+
// (redaction, truncation) are `shared/__tests__/args-preview.test.ts`'s.
|
|
665
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
666
|
+
|
|
667
|
+
function providerWith(overrides: Partial<ApprovalPolicyProvider> = {}): ApprovalPolicyProvider {
|
|
668
|
+
return { policies: new Map(), toolServerMap: new Map(), globalBypass: false, ...overrides };
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
function policyFor(serverSlug: string, toolName: string, message = "Approve?"): [string, MergedToolPolicy] {
|
|
672
|
+
return [
|
|
673
|
+
`${serverSlug}/${toolName}`,
|
|
674
|
+
{ toolName, mcpServerSlug: serverSlug, requiresApproval: true, approvalMessage: message, source: "classifier_default" },
|
|
675
|
+
];
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/** A text turn, then one tool start, on a builder with the given provider. */
|
|
679
|
+
function firstToolCallUnder(provider: ApprovalPolicyProvider, toolName: string, input: Record<string, unknown> = {}) {
|
|
680
|
+
const sb = makeBuilder();
|
|
681
|
+
sb.setApprovalProvider(provider);
|
|
682
|
+
feedAll(sb, [
|
|
683
|
+
makeMessageStart("run-1"),
|
|
684
|
+
makeTextDelta("run-1", "Working."),
|
|
685
|
+
makeMessageFinish("run-1", { usage: { input_tokens: 10, output_tokens: 5 } }),
|
|
686
|
+
makeToolStarted("toolu_1", toolName, input),
|
|
687
|
+
]);
|
|
688
|
+
return { sb, tc: sb.currentStatus.messages[0].toolCalls[0] };
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
describe("approval provider: what decides a row's status", () => {
|
|
692
|
+
it("a policy that requires approval leaves the row WAITING_APPROVAL with its message and server", () => {
|
|
693
|
+
const [key, policy] = policyFor("github", "create_issue");
|
|
694
|
+
const { sb, tc } = firstToolCallUnder(
|
|
695
|
+
providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["create_issue", "github"]]) }),
|
|
696
|
+
"create_issue",
|
|
697
|
+
{ title: "Bug fix" },
|
|
698
|
+
);
|
|
699
|
+
expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
|
|
700
|
+
expect(tc.requiresApproval).toBe(true);
|
|
701
|
+
expect(tc.approvalMessage).toBe("Approve?");
|
|
702
|
+
expect(tc.mcpServerSlug).toBe("github");
|
|
703
|
+
expect(tc.approvalRequestedAt, "stamped when approval is required").toContain("T");
|
|
704
|
+
expect(sb.awaitingApproval).toBe(true);
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
it("the global bypass (spec.auto_approve_all) runs a gated tool without approval", () => {
|
|
708
|
+
const [key, policy] = policyFor("github", "delete_repo");
|
|
709
|
+
const { sb, tc } = firstToolCallUnder(
|
|
710
|
+
providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["delete_repo", "github"]]), globalBypass: true }),
|
|
711
|
+
"delete_repo",
|
|
712
|
+
);
|
|
713
|
+
expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
|
|
714
|
+
expect(tc.requiresApproval).toBe(false);
|
|
715
|
+
expect(sb.awaitingApproval).toBe(false);
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
it("the global bypass still attributes the row to its MCP server", () => {
|
|
719
|
+
const { tc } = firstToolCallUnder(
|
|
720
|
+
providerWith({ toolServerMap: new Map([["echo", "test-mcp-server"]]), globalBypass: true }),
|
|
721
|
+
"echo",
|
|
722
|
+
{ input: "hello" },
|
|
723
|
+
);
|
|
724
|
+
expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
|
|
725
|
+
expect(tc.mcpServerSlug).toBe("test-mcp-server");
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
it("a tool with no policy runs, attributed to its server", () => {
|
|
729
|
+
const { tc } = firstToolCallUnder(providerWith({ toolServerMap: new Map([["read", "filesystem"]]) }), "read");
|
|
730
|
+
expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
|
|
731
|
+
expect(tc.mcpServerSlug).toBe("filesystem");
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
it("a policy whose tool is not in the server map does not gate (the policy key needs the server)", () => {
|
|
735
|
+
const [key, policy] = policyFor("github", "create_pr");
|
|
736
|
+
const { tc } = firstToolCallUnder(providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map() }), "create_pr");
|
|
737
|
+
expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_RUNNING);
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it("resolves {{args.field}} placeholders in the approval message", () => {
|
|
741
|
+
const [key, policy] = policyFor("github", "create_issue", "Create issue '{{args.title}}' in {{args.repo}}?");
|
|
742
|
+
const { tc } = firstToolCallUnder(
|
|
743
|
+
providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["create_issue", "github"]]) }),
|
|
744
|
+
"create_issue",
|
|
745
|
+
{ title: "Fix crash", repo: "stigmer/stigmer" },
|
|
746
|
+
);
|
|
747
|
+
expect(tc.approvalMessage).toBe("Create issue 'Fix crash' in stigmer/stigmer?");
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
describe("args preview: when the builder writes one", () => {
|
|
752
|
+
it("a gated row carries a sanitized preview; an ungated row carries none", () => {
|
|
753
|
+
const [key, policy] = policyFor("db", "connect");
|
|
754
|
+
const gated = firstToolCallUnder(
|
|
755
|
+
providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["connect", "db"]]) }),
|
|
756
|
+
"connect",
|
|
757
|
+
{ host: "localhost", password: "super-secret" },
|
|
758
|
+
);
|
|
759
|
+
const preview = JSON.parse(gated.tc.argsPreview) as Record<string, string>;
|
|
760
|
+
expect(preview.host).toBe("localhost");
|
|
761
|
+
expect(preview.password, "the shared sanitizer redacts secret keys").toBe("[REDACTED]");
|
|
762
|
+
|
|
763
|
+
const ungated = firstToolCallUnder(providerWith(), "read", { path: "/foo" });
|
|
764
|
+
expect(ungated.tc.argsPreview).toBe("");
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
it("an unserializable input leaves the preview empty instead of failing the row", () => {
|
|
768
|
+
const [key, policy] = policyFor("api", "call");
|
|
769
|
+
const circular: Record<string, unknown> = {};
|
|
770
|
+
circular.self = circular;
|
|
771
|
+
const { tc } = firstToolCallUnder(
|
|
772
|
+
providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["call", "api"]]) }),
|
|
773
|
+
"call",
|
|
774
|
+
circular,
|
|
775
|
+
);
|
|
776
|
+
expect(tc.status).toBe(ToolCallStatus.TOOL_CALL_WAITING_APPROVAL);
|
|
777
|
+
expect(tc.argsPreview).toBe("");
|
|
778
|
+
});
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
describe("tool rows without a preceding text turn, and interleaving", () => {
|
|
782
|
+
it("a tool start with no prior text creates the AI message that carries it", () => {
|
|
783
|
+
const sb = makeBuilder();
|
|
784
|
+
feedAll(sb, [makeToolStarted("orphan", "read", {})]);
|
|
785
|
+
expect(sb.currentStatus.messages).toHaveLength(1);
|
|
786
|
+
expect(sb.currentStatus.messages[0].toolCalls[0].name).toBe("read");
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
it("interleaved start/finish pairs settle each row independently", () => {
|
|
790
|
+
const sb = makeBuilder();
|
|
791
|
+
feedAll(sb, [
|
|
792
|
+
makeMessageStart("run-1"),
|
|
793
|
+
makeTextDelta("run-1", "working"),
|
|
794
|
+
makeMessageFinish("run-1", { usage: { input_tokens: 1, output_tokens: 1 } }),
|
|
795
|
+
makeToolStarted("toolu_a", "read", {}),
|
|
796
|
+
makeToolFinished("toolu_a", "data 1"),
|
|
797
|
+
makeToolStarted("toolu_b", "write", {}),
|
|
798
|
+
makeToolFinished("toolu_b", "done"),
|
|
799
|
+
]);
|
|
800
|
+
const rows = sb.currentStatus.messages.flatMap((m) => m.toolCalls);
|
|
801
|
+
expect(rows.map((r) => r.status)).toEqual([ToolCallStatus.TOOL_CALL_COMPLETED, ToolCallStatus.TOOL_CALL_COMPLETED]);
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
describe("a handler that throws", () => {
|
|
806
|
+
it("is logged with the execution, the event kind and its seq, and never escapes processEvent", () => {
|
|
807
|
+
const sb = makeBuilder();
|
|
808
|
+
const errors: string[] = [];
|
|
809
|
+
const original = console.error;
|
|
810
|
+
console.error = (msg: unknown) => { errors.push(String(msg)); };
|
|
811
|
+
try {
|
|
812
|
+
const poisoned = normalize(makeToolFinished("toolu_x", "ok"))[0]!;
|
|
813
|
+
// A getter that throws where the handler reads the output.
|
|
814
|
+
const event = { ...poisoned, get output(): unknown { throw new Error("property access failed"); } };
|
|
815
|
+
expect(() => sb.processEvent(event as typeof poisoned)).not.toThrow();
|
|
816
|
+
} finally {
|
|
817
|
+
console.error = original;
|
|
818
|
+
}
|
|
819
|
+
expect(errors).toHaveLength(1);
|
|
820
|
+
expect(errors[0]).toContain("exec-test");
|
|
821
|
+
expect(errors[0]).toContain("kind=tool_finished");
|
|
822
|
+
expect(errors[0]).toMatch(/seq=\d+/);
|
|
823
|
+
});
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
describe("resume reconciliation (a seeded WAITING row on a durable checkpoint)", () => {
|
|
827
|
+
const GATED_ID = "toolu_seeded_01";
|
|
828
|
+
|
|
829
|
+
it("resolves the seeded gated row in place — no duplicate, history kept, no re-gate", () => {
|
|
830
|
+
const status = create(AgentExecutionStatusSchema, {
|
|
831
|
+
phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
|
|
832
|
+
messages: [
|
|
833
|
+
create(AgentMessageSchema, {
|
|
834
|
+
type: MessageType.MESSAGE_AI,
|
|
835
|
+
content: "I'll call the gated tool.",
|
|
836
|
+
toolCalls: [
|
|
837
|
+
create(ToolCallSchema, {
|
|
838
|
+
id: GATED_ID,
|
|
839
|
+
name: "dangerous_tool",
|
|
840
|
+
status: ToolCallStatus.TOOL_CALL_WAITING_APPROVAL,
|
|
841
|
+
requiresApproval: true,
|
|
842
|
+
approvalAction: ApprovalAction.APPROVE,
|
|
843
|
+
mcpServerSlug: "my-server",
|
|
844
|
+
}),
|
|
845
|
+
],
|
|
846
|
+
}),
|
|
847
|
+
],
|
|
848
|
+
});
|
|
849
|
+
const sb = new V3StatusBuilder("exec-resume", status);
|
|
850
|
+
const [key, policy] = policyFor("my-server", "dangerous_tool", "Execute dangerous_tool");
|
|
851
|
+
sb.setApprovalProvider(providerWith({ policies: new Map([[key, policy]]), toolServerMap: new Map([["dangerous_tool", "my-server"]]) }));
|
|
852
|
+
|
|
853
|
+
// The durable checkpoint re-emits the SAME tool_call_id now that approval is granted.
|
|
854
|
+
feedAll(sb, [
|
|
855
|
+
makeToolStarted(GATED_ID, "dangerous_tool", { target: "prod" }),
|
|
856
|
+
makeToolFinished(GATED_ID, "tool executed ok"),
|
|
857
|
+
makeMessageStart("llm-after"),
|
|
858
|
+
makeTextDelta("llm-after", "All done."),
|
|
859
|
+
makeMessageFinish("llm-after", { usage: { input_tokens: 1, output_tokens: 1 } }),
|
|
860
|
+
]);
|
|
861
|
+
|
|
862
|
+
const gated = sb.currentStatus.messages.flatMap((m) => m.toolCalls).filter((tc) => tc.id === GATED_ID);
|
|
863
|
+
expect(gated).toHaveLength(1);
|
|
864
|
+
expect(gated[0].status).toBe(ToolCallStatus.TOOL_CALL_COMPLETED);
|
|
865
|
+
expect(gated[0].result).toContain("tool executed ok");
|
|
866
|
+
expect(gated[0].args, "the resumed start fills the args the seed lacked").toEqual({ target: "prod" });
|
|
867
|
+
const allText = sb.currentStatus.messages.map((m) => m.content).join("\n");
|
|
868
|
+
expect(allText).toContain("I'll call the gated tool.");
|
|
869
|
+
expect(allText).toContain("All done.");
|
|
870
|
+
expect(sb.awaitingApproval, "a resumed tool never re-gates").toBe(false);
|
|
871
|
+
});
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
describe("artifacts and write-backs (the ExecutionStatusWriter face)", () => {
|
|
875
|
+
const artifact = (sandboxPath: string, contentHash: string) =>
|
|
876
|
+
create(ExecutionArtifactSchema, { sandboxPath, contentHash, storageKey: `k/${contentHash}` });
|
|
877
|
+
|
|
878
|
+
it("appends a new artifact and forces the next persist", () => {
|
|
879
|
+
const sb = makeBuilder();
|
|
880
|
+
sb.addArtifact(artifact("out/a.txt", "h1"));
|
|
881
|
+
expect(sb.currentStatus.artifacts).toHaveLength(1);
|
|
882
|
+
expect(sb.forceNextUpdate).toBe(true);
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
it("deduplicates by sandboxPath: the same contentHash is a no-op that does not force a persist", () => {
|
|
886
|
+
const sb = makeBuilder();
|
|
887
|
+
sb.addArtifact(artifact("out/a.txt", "h1"));
|
|
888
|
+
sb.clearForceFlag();
|
|
889
|
+
sb.addArtifact(artifact("out/a.txt", "h1"));
|
|
890
|
+
expect(sb.currentStatus.artifacts).toHaveLength(1);
|
|
891
|
+
expect(sb.forceNextUpdate).toBe(false);
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
it("replaces the artifact in place when its contentHash changes", () => {
|
|
895
|
+
const sb = makeBuilder();
|
|
896
|
+
sb.addArtifact(artifact("out/a.txt", "h1"));
|
|
897
|
+
sb.clearForceFlag();
|
|
898
|
+
sb.addArtifact(artifact("out/a.txt", "h2"));
|
|
899
|
+
expect(sb.currentStatus.artifacts).toHaveLength(1);
|
|
900
|
+
expect(sb.currentStatus.artifacts[0].contentHash).toBe("h2");
|
|
901
|
+
expect(sb.forceNextUpdate).toBe(true);
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
it("upserts write-backs by workspaceEntryName, tracking entries independently", () => {
|
|
905
|
+
const sb = makeBuilder();
|
|
906
|
+
sb.addWriteBack(create(WorkspaceWriteBackSchema, { workspaceEntryName: "repo-a", branchName: "stigmer/s1" }));
|
|
907
|
+
sb.addWriteBack(create(WorkspaceWriteBackSchema, { workspaceEntryName: "repo-b", branchName: "stigmer/s1" }));
|
|
908
|
+
sb.clearForceFlag();
|
|
909
|
+
sb.addWriteBack(create(WorkspaceWriteBackSchema, { workspaceEntryName: "repo-a", branchName: "stigmer/s1", pullRequestUrl: "https://example/pr/1" }));
|
|
910
|
+
const backs = sb.currentStatus.workspaceWriteBacks;
|
|
911
|
+
expect(backs.map((b) => b.workspaceEntryName)).toEqual(["repo-a", "repo-b"]);
|
|
912
|
+
expect(backs[0].pullRequestUrl).toBe("https://example/pr/1");
|
|
913
|
+
expect(sb.forceNextUpdate).toBe(true);
|
|
914
|
+
});
|
|
915
|
+
});
|
|
611
916
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Proves the T04 vision input path end-to-end through the REAL framework
|
|
3
|
-
* stack: the exact `{ role: "user", content: [...] }` shape that setup.ts
|
|
3
|
+
* stack: the exact `{ role: "user", content: [...] }` shape that turn-setup.ts
|
|
4
4
|
* builds is driven through `createDeepAgent` (the production graph factory,
|
|
5
5
|
* default middleware included) and the test asserts what the chat model's
|
|
6
6
|
* `_generate` actually received.
|
|
@@ -60,9 +60,9 @@ class CapturingModel extends ScriptedModel {
|
|
|
60
60
|
return next as unknown as this;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
override async _generate(messages: BaseMessage[]): Promise<ChatResult> {
|
|
63
|
+
override async _generate(messages: BaseMessage[], options: this["ParsedCallOptions"]): Promise<ChatResult> {
|
|
64
64
|
this.captured.push(messages);
|
|
65
|
-
return super._generate(messages);
|
|
65
|
+
return super._generate(messages, options);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -92,7 +92,7 @@ describe("deep-agent vision input through the real graph", () => {
|
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
* `content` is exactly what setup.ts puts on the user message: a plain
|
|
95
|
+
* `content` is exactly what turn-setup.ts puts on the user message: a plain
|
|
96
96
|
* string, or the content-block array built by toLangChainImageBlocks plus
|
|
97
97
|
* the composed text block.
|
|
98
98
|
*/
|
|
@@ -111,7 +111,7 @@ describe("deep-agent vision input through the real graph", () => {
|
|
|
111
111
|
backend,
|
|
112
112
|
} as Parameters<typeof createDeepAgent>[0]);
|
|
113
113
|
|
|
114
|
-
// The EXACT input shape setup.ts constructs (plain role/content dict, not
|
|
114
|
+
// The EXACT input shape turn-setup.ts constructs (plain role/content dict, not
|
|
115
115
|
// a HumanMessage instance — the reducer does the coercion in production).
|
|
116
116
|
await agent.invoke(
|
|
117
117
|
{ messages: [{ role: "user", content }] },
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The native deep-agent harness as a `HarnessAdapter` — the worker- and
|
|
3
|
+
* session-lifetime half of its LangGraph slice, behind the turn runtime's
|
|
4
|
+
* contract (`harness/types.ts`). One engine turn is `turn.ts`'s
|
|
5
|
+
* `runDeepAgentTurn`; this module boots and delegates.
|
|
6
|
+
*
|
|
7
|
+
* What this adapter owns: the deepagents harness profiles (worker lifetime,
|
|
8
|
+
* registered once before the first `createDeepAgent`), and one engine turn
|
|
9
|
+
* (`runTurn`, through `turn.ts`). Everything else about a turn is the
|
|
10
|
+
* runtime's (`harness/run-turn.ts`).
|
|
11
|
+
*
|
|
12
|
+
* THIS MODULE'S STATIC GRAPH IS SDK-FREE, ON PURPOSE. The composition roots
|
|
13
|
+
* import the harness table (`src/harness-adapters.ts`) BEFORE they boot it,
|
|
14
|
+
* and that table's static graph must stay connect- and SDK-free (the Cursor
|
|
15
|
+
* adapter's boot patches `node:http2` before anything dials the control
|
|
16
|
+
* plane). So `deepagents` and `@langchain/*` — this harness's whole engine —
|
|
17
|
+
* are loaded with a dynamic import INSIDE `boot`, after the profiles are
|
|
18
|
+
* registered; a worker that does not serve this harness never pays for
|
|
19
|
+
* LangChain. `__tests__/adapter-graph-is-sdk-free.test.ts` pins it.
|
|
20
|
+
*
|
|
21
|
+
* Nothing is parked per session, and the header says so where the contract
|
|
22
|
+
* asks: the sqlite saver is opened and closed per turn and the MCP
|
|
23
|
+
* subprocesses are connected and closed per turn (`turn.ts`), so
|
|
24
|
+
* `shutdown` and `releaseSession` resolve as no-ops.
|
|
25
|
+
*
|
|
26
|
+
* What this adapter never does: throw out of `runTurn` (an engine failure is
|
|
27
|
+
* `failed` on the `internal` surface; the recursion limit is
|
|
28
|
+
* `tool_call_limit`; a `CancelledFailure` never exists here), branch on why
|
|
29
|
+
* `stopSignal` aborted, write a phase or a terminal copy, bind a state id
|
|
30
|
+
* (the thread id is the runtime's, `deterministic`), or import
|
|
31
|
+
* `@temporalio/*` (`__tests__/adapter-is-temporal-free.test.ts`).
|
|
32
|
+
*
|
|
33
|
+
* Extracted from `index.ts` `createDeepAgentActivities` at S3 M2a on the
|
|
34
|
+
* Cursor adapter's layout (`execute-cursor/adapter.ts`).
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import type { Config } from "../../config.js";
|
|
38
|
+
import type { HarnessAdapter, TurnInput, TurnOutcome, TurnSink } from "../../harness/types.js";
|
|
39
|
+
import { DEEP_AGENT_CAPABILITIES } from "./deep-agent-capabilities.js";
|
|
40
|
+
import type { DeepAgentAdapterConfig } from "./turn-setup.js";
|
|
41
|
+
|
|
42
|
+
/** The config slice this adapter reads per turn, taken at `boot`; a whole `Config` satisfies it. */
|
|
43
|
+
export function resolveDeepAgentConfig(config: Config): DeepAgentAdapterConfig {
|
|
44
|
+
return {
|
|
45
|
+
checkpointerType: config.checkpointerType,
|
|
46
|
+
checkpointerProxyEndpoint: config.checkpointerProxyEndpoint,
|
|
47
|
+
stigmerToken: config.stigmerToken,
|
|
48
|
+
proxyEndpoint: config.proxyEndpoint,
|
|
49
|
+
mode: config.mode,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** What `boot` leaves behind for the turns: the config slice and the engine turn, loaded after the profiles. */
|
|
54
|
+
interface BootedDeepAgentHarness {
|
|
55
|
+
readonly config: DeepAgentAdapterConfig;
|
|
56
|
+
readonly runDeepAgentTurn: typeof import("./turn.js").runDeepAgentTurn;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function createDeepAgentAdapter(): HarnessAdapter {
|
|
60
|
+
let booted: BootedDeepAgentHarness | undefined;
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
name: "deep-agent",
|
|
64
|
+
capabilities: DEEP_AGENT_CAPABILITIES,
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Register the harness profiles (deepagents would otherwise auto-inject
|
|
68
|
+
* an ungated `general-purpose` sub-agent into every graph), then load
|
|
69
|
+
* the engine slice. Idempotent: a re-boot re-reads the slice; the
|
|
70
|
+
* registration is once-guarded.
|
|
71
|
+
*/
|
|
72
|
+
async boot(bootConfig: Config): Promise<void> {
|
|
73
|
+
// `deepagents-profiles.ts` imports the SDK to register against it, so
|
|
74
|
+
// it too is loaded here and not at the top of this module.
|
|
75
|
+
const { registerStigmerDeepagentsProfiles } = await import("./deepagents-profiles.js");
|
|
76
|
+
registerStigmerDeepagentsProfiles();
|
|
77
|
+
const { runDeepAgentTurn } = await import("./turn.js");
|
|
78
|
+
booted = { config: resolveDeepAgentConfig(bootConfig), runDeepAgentTurn };
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
/** Nothing is held across turns (see the header). */
|
|
82
|
+
async shutdown(): Promise<void> {},
|
|
83
|
+
|
|
84
|
+
/** Nothing is parked per session (see the header); an unknown id is a no-op by construction. */
|
|
85
|
+
async releaseSession(_sessionId: string): Promise<void> {},
|
|
86
|
+
|
|
87
|
+
async runTurn(input: TurnInput, sink: TurnSink): Promise<TurnOutcome> {
|
|
88
|
+
if (booted === undefined) {
|
|
89
|
+
throw new Error("deep-agent adapter: runTurn before boot (the registry boots every adapter before the worker polls)");
|
|
90
|
+
}
|
|
91
|
+
return booted.runDeepAgentTurn(input, sink, booted.config);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
import { readFile } from "node:fs/promises";
|
|
41
41
|
import { resolveWorkspacePath } from "../../shared/file-change.js";
|
|
42
|
+
import type { CasTouchedSnapshot } from "../../shared/filereview/cas-touched.js";
|
|
42
43
|
|
|
43
44
|
/**
|
|
44
45
|
* Pre-turn bytes of each first-touched gitignored path, keyed by workspace-root-
|
|
@@ -75,6 +76,16 @@ export class CasCaptureObserver {
|
|
|
75
76
|
return this.blocked;
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
/**
|
|
80
|
+
* An atomic copy of what has been observed so far — the shape the progress
|
|
81
|
+
* slice and the turn-boundary capture read (`shared/filereview/cas-touched.ts`).
|
|
82
|
+
* Copied synchronously, so a sub-agent's concurrent `recordBefore` landing
|
|
83
|
+
* mid-capture cannot mutate a snapshot a reader is walking.
|
|
84
|
+
*/
|
|
85
|
+
snapshot(): CasTouchedSnapshot {
|
|
86
|
+
return { before: new Map(this.before), blockedSecretPaths: new Set(this.blocked) };
|
|
87
|
+
}
|
|
88
|
+
|
|
78
89
|
/**
|
|
79
90
|
* Record the pre-turn bytes of `rawPath` when it is a first-touched gitignored
|
|
80
91
|
* path. First-touch-wins across ALL backends sharing this observer: the slot is
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The native deep-agent harness's capability flags — the facts about the
|
|
3
|
+
* LangGraph engine the turn runtime branches on, declared once
|
|
4
|
+
* (`harness/capabilities.ts` has the matrix and the meaning of each flag).
|
|
5
|
+
*
|
|
6
|
+
* - `interrupt`: the approval gate (`middleware/approval-gate.ts`) calls
|
|
7
|
+
* LangGraph's `interrupt()` at a gated tool; the graph checkpoints and
|
|
8
|
+
* stops, and the adapter resumes it with a `Command(resume)` carrying
|
|
9
|
+
* the decisions (`hitl.ts`). No engine re-run, no exact-apply.
|
|
10
|
+
* - `deterministic`: the thread id is the runtime's, minted from the
|
|
11
|
+
* session before the first turn (`ensure-thread.ts`), so the adapter
|
|
12
|
+
* never binds a state id and the runtime's reinvocation fact is the
|
|
13
|
+
* persisted transcript.
|
|
14
|
+
* - A system prompt: instructions, skills, input files and standing context
|
|
15
|
+
* ride `createDeepAgent`'s `systemPrompt` (`prompt-builder.ts`).
|
|
16
|
+
* - Sub-agents as compiled sub-graphs (`subagent-transformer.ts`), each
|
|
17
|
+
* with its own mounted skills from the runtime (`TurnSkills.bySubAgent`).
|
|
18
|
+
* - Tool restriction by tool list: an MCP server's `enabled_tools` is
|
|
19
|
+
* honoured at connect time, so the engine never sees a disabled tool.
|
|
20
|
+
* - PNG, JPEG, WebP and GIF inline (`shared/attachment-vision.ts`).
|
|
21
|
+
* - File review under the `deep-agent` harness id with nothing excluded:
|
|
22
|
+
* this harness writes no transient file into the repo (the `.stigmer`
|
|
23
|
+
* link is the runtime's, created before its baseline pin and git-excluded
|
|
24
|
+
* at provision). The capture is the runtime's (`harness/capture.ts`, S3
|
|
25
|
+
* M4); this harness binds its `CasCaptureObserver`'s snapshot as the
|
|
26
|
+
* runtime's CAS observations (`turn.ts`).
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import type { HarnessCapabilities } from "../../harness/capabilities.js";
|
|
30
|
+
import { DEEP_AGENT_VISION_PROFILE } from "../../shared/attachment-vision.js";
|
|
31
|
+
|
|
32
|
+
/** The harness id stamped on the deep-agent's file-review ledger events. */
|
|
33
|
+
export const DEEP_AGENT_HARNESS_ID = "deep-agent";
|
|
34
|
+
|
|
35
|
+
export const DEEP_AGENT_CAPABILITIES: HarnessCapabilities = {
|
|
36
|
+
pausePrimitive: "interrupt",
|
|
37
|
+
stateIdSource: "deterministic",
|
|
38
|
+
systemPrompt: true,
|
|
39
|
+
subAgents: true,
|
|
40
|
+
toolRestriction: true,
|
|
41
|
+
visionProfile: DEEP_AGENT_VISION_PROFILE,
|
|
42
|
+
fileReview: { harnessId: DEEP_AGENT_HARNESS_ID, excludePaths: [] },
|
|
43
|
+
};
|