@stigmer/runner 3.15.3-dev.20260914121148 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/approval-contract/types.d.ts +1 -1
- package/dist/__test-utils__/hermetic-activity.d.ts +61 -7
- package/dist/__test-utils__/hermetic-activity.js +100 -9
- package/dist/__test-utils__/hermetic-activity.js.map +1 -1
- package/dist/__test-utils__/model-registry-fixture.d.ts +22 -3
- package/dist/__test-utils__/model-registry-fixture.js +22 -7
- package/dist/__test-utils__/model-registry-fixture.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.d.ts +2 -2
- package/dist/activities/execute-cursor/__test-utils__/contract-subject.js +2 -2
- package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +61 -0
- package/dist/activities/execute-cursor/__test-utils__/fold.js +94 -0
- package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -0
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js +1 -1
- package/dist/activities/execute-cursor/__test-utils__/gateway-substrate.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.d.ts +47 -12
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +41 -10
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.d.ts +15 -6
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js +17 -4
- package/dist/activities/execute-cursor/__test-utils__/scripted-agent.js.map +1 -1
- package/dist/activities/execute-cursor/adapter.d.ts +4 -4
- package/dist/activities/execute-cursor/adapter.js +4 -4
- package/dist/activities/execute-cursor/approval-policy.d.ts +10 -10
- package/dist/activities/execute-cursor/approval-policy.js +12 -23
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +35 -1
- package/dist/activities/execute-cursor/approval-state.js +65 -0
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/{message-translator.d.ts → boundary-rows.d.ts} +45 -341
- package/dist/activities/execute-cursor/boundary-rows.js +1018 -0
- package/dist/activities/execute-cursor/boundary-rows.js.map +1 -0
- package/dist/activities/execute-cursor/cursor-capabilities.d.ts +1 -1
- package/dist/activities/execute-cursor/cursor-capabilities.js +1 -1
- package/dist/activities/execute-cursor/cursor-event-recorder.d.ts +33 -14
- package/dist/activities/execute-cursor/cursor-event-recorder.js +43 -21
- package/dist/activities/execute-cursor/cursor-event-recorder.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +3 -3
- package/dist/activities/execute-cursor/prompt-builder.js +4 -4
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/service-tier.js +1 -2
- package/dist/activities/execute-cursor/service-tier.js.map +1 -1
- package/dist/activities/execute-cursor/sub-agent-steps.d.ts +79 -0
- package/dist/activities/execute-cursor/sub-agent-steps.js +180 -0
- package/dist/activities/execute-cursor/sub-agent-steps.js.map +1 -0
- package/dist/activities/execute-cursor/tool-result.d.ts +49 -0
- package/dist/activities/execute-cursor/tool-result.js +130 -0
- package/dist/activities/execute-cursor/tool-result.js.map +1 -0
- package/dist/activities/execute-cursor/translator.d.ts +178 -0
- package/dist/activities/execute-cursor/translator.js +485 -0
- package/dist/activities/execute-cursor/translator.js.map +1 -0
- package/dist/activities/execute-cursor/turn-boundary.d.ts +15 -5
- package/dist/activities/execute-cursor/turn-boundary.js +10 -14
- 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 +47 -34
- package/dist/activities/execute-cursor/turn-settle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-setup.d.ts +2 -2
- package/dist/activities/execute-cursor/turn-setup.js +5 -5
- package/dist/activities/execute-cursor/turn-setup.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.d.ts +23 -14
- package/dist/activities/execute-cursor/turn-stream.js +41 -28
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-cursor/turn.d.ts +4 -4
- package/dist/activities/execute-cursor/turn.js +5 -5
- package/dist/activities/execute-cursor/usage-pricing.d.ts +2 -2
- package/dist/activities/execute-cursor/usage-pricing.js +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.d.ts +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/contract-subject.js +2 -2
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +16 -11
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -10
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hitl-script.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.d.ts +2 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js +2 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model-module.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.d.ts +12 -3
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js +18 -4
- package/dist/activities/execute-deep-agent/__test-utils__/scripted-model.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.d.ts +10 -1
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js +24 -11
- package/dist/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.js.map +1 -1
- package/dist/activities/execute-deep-agent/adapter.d.ts +1 -1
- package/dist/activities/execute-deep-agent/adapter.js +1 -1
- package/dist/activities/execute-deep-agent/approval-file-change.d.ts +19 -19
- package/dist/activities/execute-deep-agent/approval-file-change.js +16 -15
- package/dist/activities/execute-deep-agent/approval-file-change.js.map +1 -1
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.d.ts +2 -2
- package/dist/activities/execute-deep-agent/deep-agent-capabilities.js +2 -2
- package/dist/activities/execute-deep-agent/hitl.d.ts +2 -2
- package/dist/activities/execute-deep-agent/hitl.js +2 -2
- package/dist/activities/execute-deep-agent/inline-publisher.d.ts +13 -3
- package/dist/activities/execute-deep-agent/inline-publisher.js +3 -3
- package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +3 -3
- package/dist/activities/execute-deep-agent/prompt-builder.js +6 -7
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +16 -8
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +20 -33
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/subagent-transformer.d.ts +3 -3
- package/dist/activities/execute-deep-agent/subagent-transformer.js +1 -1
- package/dist/activities/execute-deep-agent/translator.d.ts +134 -0
- package/dist/activities/execute-deep-agent/translator.js +418 -0
- package/dist/activities/execute-deep-agent/translator.js.map +1 -0
- package/dist/activities/execute-deep-agent/turn-settle.d.ts +13 -7
- package/dist/activities/execute-deep-agent/turn-settle.js +34 -45
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +8 -8
- package/dist/activities/execute-deep-agent/turn-setup.js +7 -7
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +13 -10
- package/dist/activities/execute-deep-agent/turn-stream.js +44 -41
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn.d.ts +3 -3
- package/dist/activities/execute-deep-agent/turn.js +3 -3
- package/dist/activities/generate-session-subject.d.ts +25 -4
- package/dist/activities/generate-session-subject.js +17 -7
- package/dist/activities/generate-session-subject.js.map +1 -1
- package/dist/client/stigmer-client.d.ts +17 -6
- package/dist/client/stigmer-client.js +47 -14
- package/dist/client/stigmer-client.js.map +1 -1
- package/dist/config.d.ts +6 -3
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/harness/approval-decisions.d.ts +1 -1
- package/dist/harness/approval-decisions.js +1 -1
- package/dist/harness/capabilities.d.ts +21 -11
- package/dist/harness/capabilities.js +2 -2
- package/dist/harness/capture.d.ts +4 -4
- package/dist/harness/capture.js +4 -4
- package/dist/harness/persist-chokepoint.d.ts +3 -3
- package/dist/harness/persist-chokepoint.js +3 -3
- package/dist/harness/registry.d.ts +2 -2
- package/dist/harness/registry.js +2 -2
- package/dist/harness/run-turn.d.ts +6 -4
- package/dist/harness/run-turn.js +31 -9
- package/dist/harness/run-turn.js.map +1 -1
- package/dist/harness/stop-controller.d.ts +1 -1
- package/dist/harness/stop-controller.js +1 -1
- package/dist/harness/terminal-table.d.ts +7 -7
- package/dist/harness/terminal-table.js +7 -7
- package/dist/harness/transcript/builder.d.ts +182 -0
- package/dist/harness/transcript/builder.js +693 -0
- package/dist/harness/transcript/builder.js.map +1 -0
- package/dist/harness/transcript/events.d.ts +218 -0
- package/dist/harness/transcript/events.js +50 -0
- package/dist/harness/transcript/events.js.map +1 -0
- package/dist/harness/transcript/state.d.ts +110 -0
- package/dist/harness/transcript/state.js +148 -0
- package/dist/harness/transcript/state.js.map +1 -0
- package/dist/harness/turn-context.d.ts +54 -38
- package/dist/harness/turn-context.js +42 -43
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/harness/types.d.ts +63 -22
- package/dist/harness/types.js +12 -11
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage-accumulator.d.ts +2 -2
- package/dist/harness/usage-accumulator.js +2 -2
- package/dist/harness-adapters.d.ts +5 -4
- package/dist/harness-adapters.js +5 -4
- package/dist/harness-adapters.js.map +1 -1
- package/dist/interceptors/run-credential-activity.d.ts +28 -0
- package/dist/interceptors/run-credential-activity.js +56 -0
- package/dist/interceptors/run-credential-activity.js.map +1 -0
- package/dist/middleware/approval-gate.d.ts +6 -0
- package/dist/middleware/approval-gate.js +7 -57
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +3 -3
- package/dist/middleware/cost-advisory.js +3 -3
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/runner-manager.js +10 -4
- package/dist/runner-manager.js.map +1 -1
- package/dist/shared/activity-input.d.ts +9 -0
- package/dist/shared/activity-input.js +17 -0
- package/dist/shared/activity-input.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +53 -0
- package/dist/shared/approval-policy.js +76 -0
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/args-preview.d.ts +45 -22
- package/dist/shared/args-preview.js +51 -41
- package/dist/shared/args-preview.js.map +1 -1
- package/dist/shared/attachment-resolver.d.ts +4 -4
- package/dist/shared/attachment-resolver.js +4 -4
- package/dist/shared/attachment-zip.d.ts +2 -2
- package/dist/shared/attachment-zip.js +2 -2
- package/dist/shared/channel-attachment.d.ts +8 -5
- package/dist/shared/channel-attachment.js +10 -6
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/shared/cost-guard.d.ts +2 -2
- package/dist/shared/cost-guard.js +2 -2
- package/dist/shared/exact-apply.d.ts +1 -1
- package/dist/shared/exact-apply.js +1 -1
- package/dist/shared/execution-context.d.ts +2 -2
- package/dist/shared/execution-context.js +2 -2
- package/dist/shared/extract-structured-output.d.ts +2 -2
- package/dist/shared/extract-structured-output.js +2 -2
- package/dist/shared/filereview/cas-touched.d.ts +2 -2
- package/dist/shared/filereview/cas-touched.js +2 -2
- package/dist/shared/filereview/progress.d.ts +13 -0
- package/dist/shared/filereview/progress.js +13 -0
- package/dist/shared/filereview/progress.js.map +1 -1
- package/dist/shared/heartbeat.d.ts +1 -1
- package/dist/shared/heartbeat.js +1 -1
- package/dist/shared/llm-backend.d.ts +0 -4
- package/dist/shared/llm-backend.js +0 -4
- package/dist/shared/llm-backend.js.map +1 -1
- package/dist/shared/memory-attachment.d.ts +16 -9
- package/dist/shared/memory-attachment.js +18 -10
- package/dist/shared/memory-attachment.js.map +1 -1
- package/dist/shared/model-error.d.ts +1 -2
- package/dist/shared/model-error.js +1 -2
- package/dist/shared/model-error.js.map +1 -1
- package/dist/shared/persist-decision.d.ts +18 -24
- package/dist/shared/persist-decision.js +19 -11
- package/dist/shared/persist-decision.js.map +1 -1
- package/dist/shared/prompt-sections.d.ts +4 -4
- package/dist/shared/prompt-sections.js +4 -4
- package/dist/shared/run-credential-store.d.ts +32 -0
- package/dist/shared/run-credential-store.js +39 -0
- package/dist/shared/run-credential-store.js.map +1 -0
- package/dist/shared/run-credential.d.ts +61 -0
- package/dist/shared/run-credential.js +68 -0
- package/dist/shared/run-credential.js.map +1 -0
- package/dist/shared/skill-resolver.d.ts +3 -3
- package/dist/shared/skill-resolver.js +3 -3
- package/dist/shared/status-offload.d.ts +1 -1
- package/dist/shared/status-offload.js +2 -2
- package/dist/shared/status-offload.js.map +1 -1
- package/dist/shared/streaming-scheduler.d.ts +2 -7
- package/dist/shared/streaming-scheduler.js +6 -14
- package/dist/shared/streaming-scheduler.js.map +1 -1
- package/dist/shared/subagent-rows.d.ts +2 -2
- package/dist/shared/subagent-rows.js +2 -2
- package/dist/shared/synthesized-attachment.d.ts +30 -3
- package/dist/shared/synthesized-attachment.js +26 -0
- package/dist/shared/synthesized-attachment.js.map +1 -1
- package/dist/shared/todos.d.ts +3 -3
- package/dist/shared/todos.js +3 -3
- package/dist/shared/tool-row.d.ts +19 -1
- package/dist/shared/tool-row.js +36 -2
- package/dist/shared/tool-row.js.map +1 -1
- package/dist/shared/worker-shutdown.d.ts +1 -1
- package/dist/shared/worker-shutdown.js +1 -1
- package/dist/shared/workspace/session-provision.d.ts +1 -1
- package/dist/shared/workspace/session-provision.js +1 -1
- package/dist/shared/workspace/sources/empty.d.ts +1 -1
- package/dist/shared/workspace/sources/empty.js +1 -2
- package/dist/shared/workspace/sources/empty.js.map +1 -1
- package/dist/shared/workspace/sources/git.js +4 -4
- package/dist/shared/workspace/sources/git.js.map +1 -1
- package/dist/shared/workspace/sources/local-path.js +6 -6
- package/dist/shared/workspace/sources/local-path.js.map +1 -1
- package/dist/shared/workspace/stigmer-link.d.ts +1 -1
- package/dist/shared/workspace/stigmer-link.js +1 -1
- package/dist/shared/workspace/types.d.ts +2 -5
- package/dist/shared/workspace/types.js +0 -6
- package/dist/shared/workspace/types.js.map +1 -1
- package/dist/shared/workspace/writeback-coordinator.d.ts +17 -4
- package/dist/shared/workspace/writeback-coordinator.js +7 -9
- package/dist/shared/workspace/writeback-coordinator.js.map +1 -1
- package/dist/worker.js +10 -3
- package/dist/worker.js.map +1 -1
- package/dist/workflow-source.d.ts +10 -0
- package/dist/workflow-source.js +12 -0
- package/dist/workflow-source.js.map +1 -1
- package/dist/workflows/execute-from-execution.d.ts +15 -0
- package/dist/workflows/execute-from-execution.js +11 -0
- package/dist/workflows/execute-from-execution.js.map +1 -1
- package/dist/workflows/index.d.ts +5 -3
- package/dist/workflows/index.js +5 -3
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/interceptors/run-credential.d.ts +34 -0
- package/dist/workflows/interceptors/run-credential.js +71 -0
- package/dist/workflows/interceptors/run-credential.js.map +1 -0
- package/package.json +4 -4
- package/src/__test-utils__/__tests__/execution-record-barrier.test.ts +70 -0
- package/src/__test-utils__/__tests__/harness-contract-self-check.test.ts +35 -1
- package/src/__test-utils__/approval-contract/contract.ts +1 -1
- package/src/__test-utils__/approval-contract/types.ts +1 -1
- package/src/__test-utils__/harness-boot-order-child.ts +1 -1
- package/src/__test-utils__/harness-contract/contract.ts +8 -8
- package/src/__test-utils__/harness-contract/recording-sink.ts +11 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +52 -16
- package/src/__test-utils__/harness-contract/scripted-adapter.ts +47 -43
- package/src/__test-utils__/hermetic-activity.ts +113 -9
- package/src/__test-utils__/model-registry-fixture.ts +31 -7
- package/src/__test-utils__/module-specifiers.ts +32 -3
- package/src/__tests__/harness-boot-order.test.ts +1 -1
- package/src/__tests__/harness-contract.test.ts +1 -1
- package/src/__tests__/run-credential-e2e.test.ts +233 -0
- package/src/__tests__/run-credential-registration.test.ts +80 -0
- package/src/__tests__/runner-manager.test.ts +1 -1
- package/src/activities/__tests__/generate-session-subject-wire.test.ts +119 -0
- package/src/activities/execute-cursor/__test-utils__/__tests__/scripted-double.test.ts +1 -1
- package/src/activities/execute-cursor/__test-utils__/contract-subject.ts +2 -2
- package/src/activities/execute-cursor/__test-utils__/fold.ts +116 -0
- package/src/activities/execute-cursor/__test-utils__/gateway-substrate.ts +1 -1
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +67 -17
- package/src/activities/execute-cursor/__test-utils__/scripted-agent.ts +19 -5
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/approval-state.test.ts +14 -21
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/coarse-fingerprint.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/cursor-event-recorder.test.ts +142 -0
- package/src/activities/execute-cursor/__tests__/cursor-fetch-interceptor-bypass.test.ts +19 -8
- package/src/activities/execute-cursor/__tests__/cursor-sdk-auth-smoke.test.ts +10 -8
- package/src/activities/execute-cursor/__tests__/cursor-transcript-live.test.ts +298 -0
- package/src/activities/execute-cursor/__tests__/deny-gate-exact-apply.test.ts +4 -2
- package/src/activities/execute-cursor/__tests__/fetch-interceptor.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/deny-and-retry.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/mcp-tool-call.status.json +71 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sdk-task-note.status.json +73 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +78 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +72 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +72 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/sub-agent-delegation.status.json +109 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/thinking-turn.status.json +78 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/todo-write.status.json +119 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-error.status.json +68 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/tool-only-step.status.json +67 -0
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/harness-contract.test.ts +7 -7
- package/src/activities/execute-cursor/__tests__/hermetic/mcp-tool-call.test.ts +146 -0
- package/src/activities/execute-cursor/__tests__/hermetic/pause-vs-shutdown.test.ts +5 -5
- package/src/activities/execute-cursor/__tests__/hermetic/plain-turn.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/hermetic/run-wait-arms.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/hermetic/sdk-task-note.test.ts +122 -0
- package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +276 -0
- package/src/activities/execute-cursor/__tests__/hermetic/stream-self-stop-arms.test.ts +8 -8
- package/src/activities/execute-cursor/__tests__/hermetic/sub-agent-delegation.test.ts +196 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thinking-turn.test.ts +145 -0
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/todo-write.test.ts +165 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-call.test.ts +3 -3
- package/src/activities/execute-cursor/__tests__/hermetic/tool-error.test.ts +138 -0
- package/src/activities/execute-cursor/__tests__/hermetic/tool-only-step.test.ts +130 -0
- package/src/activities/execute-cursor/__tests__/hermetic/unattributed-hook-block.test.ts +13 -1
- package/src/activities/execute-cursor/__tests__/hermetic/workspace-lock-timeout.test.ts +2 -2
- package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +43 -60
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +23 -28
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +2 -1
- package/src/activities/execute-cursor/__tests__/http2-interceptor.test.ts +1 -1
- package/src/activities/execute-cursor/__tests__/prompt-goldens.test.ts +5 -5
- package/src/activities/execute-cursor/__tests__/same-identity-reproposal.test.ts +11 -13
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +8 -11
- package/src/activities/execute-cursor/__tests__/tool-result-image.test.ts +8 -22
- package/src/activities/execute-cursor/__tests__/translator.test.ts +594 -0
- package/src/activities/execute-cursor/__tests__/turn-boundary.test.ts +8 -5
- package/src/activities/execute-cursor/__tests__/turn-stream.test.ts +87 -63
- package/src/activities/execute-cursor/adapter.ts +4 -4
- package/src/activities/execute-cursor/approval-policy.ts +12 -24
- package/src/activities/execute-cursor/approval-state.ts +66 -1
- package/src/activities/execute-cursor/boundary-rows.ts +1132 -0
- package/src/activities/execute-cursor/cursor-capabilities.ts +1 -1
- package/src/activities/execute-cursor/cursor-event-recorder.ts +57 -28
- package/src/activities/execute-cursor/fetch-interceptor.ts +1 -1
- package/src/activities/execute-cursor/http2-interceptor.ts +1 -1
- package/src/activities/execute-cursor/prompt-builder.ts +6 -6
- package/src/activities/execute-cursor/service-tier.ts +1 -2
- package/src/activities/execute-cursor/sub-agent-steps.ts +188 -0
- package/src/activities/execute-cursor/tool-result.ts +128 -0
- package/src/activities/execute-cursor/translator.ts +541 -0
- package/src/activities/execute-cursor/turn-boundary.ts +21 -14
- package/src/activities/execute-cursor/turn-settle.ts +46 -34
- package/src/activities/execute-cursor/turn-setup.ts +5 -5
- package/src/activities/execute-cursor/turn-stream.ts +49 -46
- package/src/activities/execute-cursor/turn.ts +5 -5
- package/src/activities/execute-cursor/usage-pricing.ts +2 -2
- package/src/activities/execute-deep-agent/__test-utils__/contract-subject.ts +2 -2
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +23 -11
- package/src/activities/execute-deep-agent/__test-utils__/hitl-script.ts +1 -1
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model-module.ts +2 -3
- package/src/activities/execute-deep-agent/__test-utils__/scripted-model.ts +25 -4
- package/src/activities/execute-deep-agent/__test-utils__/v3-event-fixtures.ts +25 -11
- package/src/activities/execute-deep-agent/__tests__/adapter-graph-is-sdk-free.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/adapter-is-temporal-free.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/approval-file-change.test.ts +6 -17
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +25 -8
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn1.status.json +2 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve-all-lease.turn2.status.json +4 -14
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/approve.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +4 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/gate.turn1.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +2 -9
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +2 -9
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.after-tool.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/pause.loop.mid-tool.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/platform-stop.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +109 -76
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/reject.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn2.status.json +2 -10
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sequential-gates.turn3.status.json +2 -10
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/skip.turn2.status.json +1 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/sub-agent-delegation.status.json +3 -6
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/tool-call.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/worker-shutdown.status.json +1 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/write-todos.status.json +92 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/harness-contract.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-approve-all-lease.test.ts +9 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-round-trips.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/hitl-sequential-gates.test.ts +3 -3
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +7 -6
- package/src/activities/execute-deep-agent/__tests__/hermetic/pause-vs-shutdown.test.ts +10 -11
- package/src/activities/execute-deep-agent/__tests__/hermetic/plain-turn.test.ts +4 -4
- package/src/activities/execute-deep-agent/__tests__/hermetic/platform-stop.test.ts +9 -8
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +21 -13
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +2 -2
- package/src/activities/execute-deep-agent/__tests__/hermetic/structured-output.test.ts +7 -7
- package/src/activities/execute-deep-agent/__tests__/hermetic/sub-agent-delegation.test.ts +28 -12
- package/src/activities/execute-deep-agent/__tests__/hermetic/tool-call.test.ts +21 -21
- package/src/activities/execute-deep-agent/__tests__/hermetic/workspace-lock-timeout.test.ts +5 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/write-todos.test.ts +160 -0
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +35 -30
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +3 -4
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +12 -10
- package/src/activities/execute-deep-agent/__tests__/scripted-model.test.ts +13 -3
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +26 -18
- package/src/activities/execute-deep-agent/__tests__/subagent-wiring.test.ts +1 -1
- package/src/activities/execute-deep-agent/__tests__/{subagent-tracker.test.ts → translator-subagents.test.ts} +76 -57
- package/src/activities/execute-deep-agent/__tests__/{v3-status-builder.test.ts → translator-through-builder.test.ts} +213 -299
- package/src/activities/execute-deep-agent/__tests__/translator.test.ts +505 -0
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +11 -29
- package/src/activities/execute-deep-agent/adapter.ts +1 -1
- package/src/activities/execute-deep-agent/approval-file-change.ts +20 -22
- package/src/activities/execute-deep-agent/deep-agent-capabilities.ts +2 -2
- package/src/activities/execute-deep-agent/hitl.ts +2 -2
- package/src/activities/execute-deep-agent/inline-publisher.ts +16 -5
- package/src/activities/execute-deep-agent/prompt-builder.ts +6 -7
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +22 -31
- package/src/activities/execute-deep-agent/subagent-transformer.ts +3 -3
- package/src/activities/execute-deep-agent/translator.ts +463 -0
- package/src/activities/execute-deep-agent/turn-settle.ts +35 -43
- package/src/activities/execute-deep-agent/turn-setup.ts +8 -8
- package/src/activities/execute-deep-agent/turn-stream.ts +53 -51
- package/src/activities/execute-deep-agent/turn.ts +3 -3
- package/src/activities/generate-session-subject.ts +29 -4
- package/src/client/__tests__/stigmer-client.test.ts +92 -0
- package/src/client/stigmer-client.ts +48 -14
- package/src/config.ts +6 -3
- package/src/harness/README.md +335 -0
- package/src/harness/__tests__/approval-decisions.test.ts +2 -2
- package/src/harness/__tests__/capture.test.ts +3 -3
- package/src/harness/__tests__/import-direction.test.ts +3 -2
- package/src/harness/__tests__/mount-skills.test.ts +4 -1
- package/src/harness/__tests__/readme-index.test.ts +339 -0
- package/src/harness/__tests__/run-turn.test.ts +131 -6
- package/src/harness/__tests__/transcript-is-engine-free.test.ts +83 -0
- package/src/harness/__tests__/transcript-writers.test.ts +191 -0
- package/src/harness/__tests__/turn-attachments-vision.test.ts +5 -2
- package/src/harness/__tests__/turn-context.test.ts +5 -5
- package/src/harness/approval-decisions.ts +1 -1
- package/src/harness/capabilities.ts +21 -11
- package/src/harness/capture.ts +4 -4
- package/src/harness/persist-chokepoint.ts +3 -3
- package/src/harness/registry.ts +2 -2
- package/src/harness/run-turn.ts +33 -9
- package/src/harness/stop-controller.ts +1 -1
- package/src/harness/terminal-table.ts +7 -7
- package/src/harness/transcript/__tests__/builder.test.ts +975 -0
- package/src/harness/transcript/__tests__/state.test.ts +143 -0
- package/src/harness/transcript/builder.ts +755 -0
- package/src/harness/transcript/events.ts +262 -0
- package/src/harness/transcript/state.ts +167 -0
- package/src/harness/turn-context.ts +61 -46
- package/src/harness/types.ts +64 -22
- package/src/harness/usage-accumulator.ts +2 -2
- package/src/harness-adapters.ts +5 -4
- package/src/interceptors/__tests__/run-credential-activity.test.ts +133 -0
- package/src/interceptors/run-credential-activity.ts +67 -0
- package/src/middleware/__tests__/cost-advisory.test.ts +2 -2
- package/src/middleware/approval-gate.ts +7 -74
- package/src/middleware/cost-advisory.ts +3 -3
- package/src/middleware/index.ts +1 -1
- package/src/runner-manager.ts +14 -4
- package/src/shared/__tests__/approval-policy.test.ts +45 -0
- package/src/shared/__tests__/args-preview.test.ts +40 -20
- package/src/shared/__tests__/attachment-naming.test.ts +1 -1
- package/src/shared/__tests__/attachment-resolver.test.ts +5 -5
- package/src/shared/__tests__/attachment-zip.test.ts +1 -1
- package/src/shared/__tests__/blueprint-resolver.test.ts +1 -1
- package/src/shared/__tests__/channel-attachment.test.ts +12 -0
- package/src/shared/__tests__/cost-guard.test.ts +1 -1
- package/src/shared/__tests__/exact-apply.test.ts +2 -1
- package/src/shared/__tests__/memory-attachment.test.ts +17 -0
- package/src/shared/__tests__/persist-decision.test.ts +19 -33
- package/src/shared/__tests__/prompt-sections.test.ts +1 -1
- package/src/shared/__tests__/run-credential.test.ts +111 -0
- package/src/shared/__tests__/stamp-flowed-rows.test.ts +1 -1
- package/src/shared/__tests__/status-offload.test.ts +1 -1
- package/src/shared/__tests__/streaming-scheduler.test.ts +8 -9
- package/src/shared/__tests__/todos.test.ts +1 -1
- package/src/shared/__tests__/tool-row.test.ts +1 -1
- package/src/shared/activity-input.ts +21 -0
- package/src/shared/approval-policy.ts +95 -0
- package/src/shared/args-preview.ts +51 -42
- package/src/shared/attachment-resolver.ts +4 -4
- package/src/shared/attachment-zip.ts +2 -2
- package/src/shared/channel-attachment.ts +14 -6
- package/src/shared/cost-guard.ts +2 -2
- package/src/shared/exact-apply.ts +1 -1
- package/src/shared/execution-context.ts +2 -2
- package/src/shared/extract-structured-output.ts +2 -2
- package/src/shared/filereview/__tests__/capture.test.ts +9 -5
- package/src/shared/filereview/__tests__/git-substrate.test.ts +4 -1
- package/src/shared/filereview/__tests__/proxy-reconcile.test.ts +3 -3
- package/src/shared/filereview/cas-touched.ts +2 -2
- package/src/shared/filereview/progress.ts +13 -0
- package/src/shared/heartbeat.ts +1 -1
- package/src/shared/llm-backend.ts +0 -4
- package/src/shared/memory-attachment.ts +22 -10
- package/src/shared/model-error.ts +1 -2
- package/src/shared/persist-decision.ts +19 -28
- package/src/shared/prompt-sections.ts +4 -4
- package/src/shared/run-credential-store.ts +45 -0
- package/src/shared/run-credential.ts +70 -0
- package/src/shared/skill-resolver.ts +3 -3
- package/src/shared/status-offload.ts +2 -2
- package/src/shared/streaming-scheduler.ts +8 -13
- package/src/shared/subagent-rows.ts +2 -2
- package/src/shared/synthesized-attachment.ts +38 -3
- package/src/shared/todos.ts +3 -3
- package/src/shared/tool-row.ts +38 -2
- package/src/shared/worker-shutdown.ts +1 -1
- package/src/shared/workspace/__tests__/git-source.test.ts +3 -3
- package/src/shared/workspace/__tests__/provisioner.test.ts +5 -5
- package/src/shared/workspace/__tests__/session-provision.test.ts +2 -2
- package/src/shared/workspace/__tests__/writeback-coordinator.integration.test.ts +8 -9
- package/src/shared/workspace/__tests__/writeback-coordinator.test.ts +25 -25
- package/src/shared/workspace/provisioner.ts +1 -1
- package/src/shared/workspace/session-provision.ts +1 -1
- package/src/shared/workspace/sources/empty.ts +2 -2
- package/src/shared/workspace/sources/git.ts +3 -4
- package/src/shared/workspace/sources/local-path.ts +5 -6
- package/src/shared/workspace/stigmer-link.ts +1 -1
- package/src/shared/workspace/types.ts +2 -5
- package/src/shared/workspace/writeback-coordinator.ts +23 -12
- package/src/worker.ts +15 -3
- package/src/workflow-source.ts +15 -0
- package/src/workflows/__tests__/run-credential-interceptor.test.ts +178 -0
- package/src/workflows/execute-from-execution.ts +17 -0
- package/src/workflows/index.ts +5 -3
- package/src/workflows/interceptors/run-credential.ts +101 -0
- package/dist/activities/execute-cursor/delta-enricher.d.ts +0 -87
- package/dist/activities/execute-cursor/delta-enricher.js +0 -265
- package/dist/activities/execute-cursor/delta-enricher.js.map +0 -1
- package/dist/activities/execute-cursor/message-translator.js +0 -2040
- package/dist/activities/execute-cursor/message-translator.js.map +0 -1
- package/dist/activities/execute-cursor/todo-tracker.d.ts +0 -40
- package/dist/activities/execute-cursor/todo-tracker.js +0 -80
- package/dist/activities/execute-cursor/todo-tracker.js.map +0 -1
- package/dist/activities/execute-deep-agent/execution-state.d.ts +0 -54
- package/dist/activities/execute-deep-agent/execution-state.js +0 -68
- package/dist/activities/execute-deep-agent/execution-state.js.map +0 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +0 -65
- package/dist/activities/execute-deep-agent/status-builder-shared.js +0 -90
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +0 -1
- package/dist/activities/execute-deep-agent/subagent-tracker.d.ts +0 -113
- package/dist/activities/execute-deep-agent/subagent-tracker.js +0 -400
- package/dist/activities/execute-deep-agent/subagent-tracker.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-events.d.ts +0 -102
- package/dist/activities/execute-deep-agent/v3-events.js +0 -35
- package/dist/activities/execute-deep-agent/v3-events.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.d.ts +0 -15
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js +0 -235
- package/dist/activities/execute-deep-agent/v3-protocol-normalizer.js.map +0 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.d.ts +0 -111
- package/dist/activities/execute-deep-agent/v3-status-builder.js +0 -457
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +0 -1
- package/dist/shared/execution-status-writer.d.ts +0 -31
- package/dist/shared/execution-status-writer.js +0 -43
- package/dist/shared/execution-status-writer.js.map +0 -1
- package/src/activities/execute-cursor/__tests__/delta-enricher.test.ts +0 -310
- package/src/activities/execute-cursor/__tests__/message-translator.test.ts +0 -1033
- package/src/activities/execute-cursor/__tests__/todo-tracker.test.ts +0 -498
- package/src/activities/execute-cursor/delta-enricher.ts +0 -307
- package/src/activities/execute-cursor/message-translator.ts +0 -2319
- package/src/activities/execute-cursor/todo-tracker.ts +0 -91
- package/src/activities/execute-deep-agent/__tests__/execution-state-extended.test.ts +0 -148
- package/src/activities/execute-deep-agent/__tests__/execution-state.test.ts +0 -154
- package/src/activities/execute-deep-agent/__tests__/status-builder-shared.test.ts +0 -47
- package/src/activities/execute-deep-agent/__tests__/v3-protocol-normalizer.test.ts +0 -324
- package/src/activities/execute-deep-agent/execution-state.ts +0 -78
- package/src/activities/execute-deep-agent/status-builder-shared.ts +0 -142
- package/src/activities/execute-deep-agent/subagent-tracker.ts +0 -479
- package/src/activities/execute-deep-agent/v3-events.ts +0 -153
- package/src/activities/execute-deep-agent/v3-protocol-normalizer.ts +0 -264
- package/src/activities/execute-deep-agent/v3-status-builder.ts +0 -565
- package/src/shared/execution-status-writer.ts +0 -56
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hermetic golden: the agent's TO-DO LIST on the native harness — the model
|
|
3
|
+
* proposes deepagents' built-in `write_todos`, the tools node runs it for
|
|
4
|
+
* real, and the builder projects the list into `status.todos`.
|
|
5
|
+
*
|
|
6
|
+
* Invariant pinned: `TranscriptBuilder.handleToolStarted` classifies
|
|
7
|
+
* the row `ToolKind.TODO` by name; `handleToolFinished` projects `tc.args.todos`
|
|
8
|
+
* into `status.todos` through the shared `applyTodoUpdate` as a FULL REPLACE
|
|
9
|
+
* (deepagents' schema has no `merge`), keyed `todo-<i>`, and KEEPS the row in
|
|
10
|
+
* the transcript — the clients filter `ToolKind.TODO` from the thread. As an
|
|
11
|
+
* ungated built-in it carries `argsPreview` like every row since #1097
|
|
12
|
+
* (until then native stamped a preview on gated rows only).
|
|
13
|
+
*
|
|
14
|
+
* What the golden shows:
|
|
15
|
+
* - The row sits on the AI message whose text proposed it, "Planning the two
|
|
16
|
+
* steps." (since #1097; until then on an empty message between the two
|
|
17
|
+
* texts — see `tool-call.test.ts`'s header).
|
|
18
|
+
* - The row's `result` is the tool's confirmation text, "Updated todo list
|
|
19
|
+
* to [...]" (since #1097). deepagents' `write_todos` returns a
|
|
20
|
+
* LangGraph `Command` (`{ lg_name: "Command", update: { todos, messages:
|
|
21
|
+
* [ToolMessage] } }`); until then the native extractor unwrapped a
|
|
22
|
+
* LangChain `ToolMessage` envelope but not a `Command`, so the row carried
|
|
23
|
+
* the whole serialized Command — the todos array a second time and the
|
|
24
|
+
* text nested inside it (pinned as found when this net opened,
|
|
25
|
+
* regenerated in #1097 with that one hunk).
|
|
26
|
+
*
|
|
27
|
+
* The #1097 moves, as landed (2026-09-14): the
|
|
28
|
+
* row joined `messages[0]` ("Planning the two steps.") and the empty message
|
|
29
|
+
* went; the row gained `argsPreview`, the elided preview of
|
|
30
|
+
* its `args`. `todos` is byte-identical (the builder keeps native's
|
|
31
|
+
* full-replace: `write_todos` never sends `merge`). Any other hunk is a pause.
|
|
32
|
+
*
|
|
33
|
+
* Why this net exists: none of the twenty-three earlier native goldens
|
|
34
|
+
* carried a todo, and #1097 moved the projection from the native builder
|
|
35
|
+
* into the canonical one.
|
|
36
|
+
*
|
|
37
|
+
* Regenerate ONLY after a deliberate behavior change:
|
|
38
|
+
* npx vitest run src/activities/execute-deep-agent/__tests__/hermetic -u
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
|
42
|
+
import { toJson } from "@bufbuild/protobuf";
|
|
43
|
+
import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
44
|
+
import {
|
|
45
|
+
ExecutionPhase,
|
|
46
|
+
MessageType,
|
|
47
|
+
TodoStatus,
|
|
48
|
+
ToolCallStatus,
|
|
49
|
+
ToolKind,
|
|
50
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
51
|
+
|
|
52
|
+
vi.mock("../../../../shared/model-client.js", async () =>
|
|
53
|
+
(await import("../../__test-utils__/scripted-model-module.js")).scriptedModelClientModule(),
|
|
54
|
+
);
|
|
55
|
+
vi.mock("../../../../client/stigmer-client.js", async () =>
|
|
56
|
+
(await import("../../../../__test-utils__/hermetic-activity.js")).hermeticStigmerClientModule(),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
import {
|
|
60
|
+
ScriptedClock,
|
|
61
|
+
createHermeticEnvironment,
|
|
62
|
+
type HermeticEnvironment,
|
|
63
|
+
} from "../../../../__test-utils__/hermetic-activity.js";
|
|
64
|
+
import { stubRegistryFetch } from "../../../../__test-utils__/model-registry-fixture.js";
|
|
65
|
+
import {
|
|
66
|
+
beginDeepAgentScenario,
|
|
67
|
+
deepAgentExecutionRecord,
|
|
68
|
+
runDeepAgentTurn,
|
|
69
|
+
} from "../../__test-utils__/hermetic-deep-agent.js";
|
|
70
|
+
|
|
71
|
+
const CALL_ID = "call-hermetic-todos-0001";
|
|
72
|
+
const USER_MESSAGE = "Plan the two steps.";
|
|
73
|
+
const TEXT_PLAN = "Planning the two steps.";
|
|
74
|
+
/** deepagents' `write_todos` schema: `{ content, status }` per item, three statuses, no id, no merge. */
|
|
75
|
+
const TODOS = [
|
|
76
|
+
{ content: "Read the fixture", status: "pending" },
|
|
77
|
+
{ content: "Summarise it", status: "in_progress" },
|
|
78
|
+
];
|
|
79
|
+
const TEXT_CLOSING = "The plan is written.";
|
|
80
|
+
|
|
81
|
+
describe("ExecuteDeepAgent hermetic — write_todos", () => {
|
|
82
|
+
let env: HermeticEnvironment;
|
|
83
|
+
let registry: ReturnType<typeof stubRegistryFetch>;
|
|
84
|
+
const clock = new ScriptedClock();
|
|
85
|
+
|
|
86
|
+
beforeAll(() => {
|
|
87
|
+
env = createHermeticEnvironment();
|
|
88
|
+
registry = stubRegistryFetch();
|
|
89
|
+
clock.install();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
afterAll(() => {
|
|
93
|
+
clock.uninstall();
|
|
94
|
+
registry.restore();
|
|
95
|
+
env.dispose();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("projects the completed write into status.todos, keeps the row, and completes", async () => {
|
|
99
|
+
// ── Arrange ──────────────────────────────────────────────────────────────
|
|
100
|
+
const record = deepAgentExecutionRecord({ message: USER_MESSAGE });
|
|
101
|
+
const scenario = beginDeepAgentScenario({
|
|
102
|
+
env,
|
|
103
|
+
clock,
|
|
104
|
+
record,
|
|
105
|
+
script: () => ({
|
|
106
|
+
turns: [
|
|
107
|
+
{
|
|
108
|
+
text: TEXT_PLAN,
|
|
109
|
+
toolCalls: [{ id: CALL_ID, name: "write_todos", args: { todos: TODOS } }],
|
|
110
|
+
usage: { inputTokens: 1_400, outputTokens: 70 },
|
|
111
|
+
},
|
|
112
|
+
{ text: TEXT_CLOSING, usage: { inputTokens: 1_600, outputTokens: 20 } },
|
|
113
|
+
],
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// ── Act ──────────────────────────────────────────────────────────────────
|
|
118
|
+
const invocation = await runDeepAgentTurn(scenario);
|
|
119
|
+
|
|
120
|
+
// ── Assert: outcome ──────────────────────────────────────────────────────
|
|
121
|
+
expect(invocation.outcome.kind).toBe("returned");
|
|
122
|
+
expect((invocation.outcome as { value: Record<string, unknown> }).value.phase).toBe("EXECUTION_COMPLETED");
|
|
123
|
+
expect(record.persistedPhases.at(-1)).toBe(ExecutionPhase.EXECUTION_COMPLETED);
|
|
124
|
+
|
|
125
|
+
// ── Assert: the row stays in the transcript, classified TODO ─────────────
|
|
126
|
+
const rows = record.toolCalls();
|
|
127
|
+
expect(rows).toHaveLength(1);
|
|
128
|
+
const row = rows[0];
|
|
129
|
+
expect(row.id).toBe(CALL_ID);
|
|
130
|
+
expect(row.name).toBe("write_todos");
|
|
131
|
+
expect(row.toolKind).toBe(ToolKind.TODO);
|
|
132
|
+
expect(row.status).toBe(ToolCallStatus.TOOL_CALL_COMPLETED);
|
|
133
|
+
expect(row.args).toEqual({ todos: TODOS });
|
|
134
|
+
expect(JSON.parse(row.argsPreview), "every row carries its elided preview").toEqual({ todos: TODOS });
|
|
135
|
+
expect(row.requiresApproval).toBe(false);
|
|
136
|
+
// Since #1097: the ToolMessage's content, never the serialized Command.
|
|
137
|
+
expect(row.result.startsWith("Updated todo list to"), "the tool's own confirmation text is what the row carries").toBe(true);
|
|
138
|
+
expect(row.result).not.toContain("lg_name");
|
|
139
|
+
|
|
140
|
+
// ── Assert: the transcript — the row beside the text that proposed it ──
|
|
141
|
+
const final = record.lastFullStatus!;
|
|
142
|
+
const ai = final.messages.filter((m) => m.type === MessageType.MESSAGE_AI);
|
|
143
|
+
expect(ai.map((m) => [m.content, m.toolCalls.map((tc) => tc.id)])).toEqual([
|
|
144
|
+
[TEXT_PLAN, [CALL_ID]],
|
|
145
|
+
[TEXT_CLOSING, []],
|
|
146
|
+
]);
|
|
147
|
+
|
|
148
|
+
// ── Assert: the projection, by key (byte-identical across the swap) ─────
|
|
149
|
+
expect(Object.keys(final.todos).sort()).toEqual(["todo-0", "todo-1"]);
|
|
150
|
+
expect([final.todos["todo-0"].content, final.todos["todo-0"].status]).toEqual(["Read the fixture", TodoStatus.TODO_PENDING]);
|
|
151
|
+
expect([final.todos["todo-1"].content, final.todos["todo-1"].status]).toEqual(["Summarise it", TodoStatus.TODO_IN_PROGRESS]);
|
|
152
|
+
|
|
153
|
+
// ── Assert: hermeticity ──────────────────────────────────────────────────
|
|
154
|
+
expect(registry.urls.every((u) => u.includes("/model-registry"))).toBe(true);
|
|
155
|
+
|
|
156
|
+
// ── Assert: the golden ───────────────────────────────────────────────────
|
|
157
|
+
const json = JSON.stringify(toJson(AgentExecutionStatusSchema, final), null, 2) + "\n";
|
|
158
|
+
await expect(json).toMatchFileSnapshot("./goldens/write-todos.status.json");
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -4,19 +4,21 @@ import { writeFile, mkdir } from "node:fs/promises";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { create } from "@bufbuild/protobuf";
|
|
7
|
-
import { AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
7
|
+
import { type AgentExecutionStatus, AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
8
8
|
import { ExecutionArtifactKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
9
9
|
import { InlinePublisher } from "../inline-publisher.js";
|
|
10
|
-
import {
|
|
10
|
+
import { TranscriptBuilder } from "../../../harness/transcript/builder.js";
|
|
11
11
|
import { LocalWorkspaceBackend } from "../../../shared/workspace/local-backend.js";
|
|
12
12
|
import type { ArtifactStorage } from "../../../shared/artifact-storage.js";
|
|
13
13
|
import { makeInMemoryArtifactStorage } from "../../../__test-utils__/fake-artifact-storage.js";
|
|
14
14
|
import type { WorkspaceBackend } from "../../../shared/workspace/types.js";
|
|
15
15
|
|
|
16
|
-
// The publisher
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
// The publisher registers artifacts on the transcript builder (`addArtifact`);
|
|
17
|
+
// the one builder since #1096.
|
|
18
|
+
/** A builder and the status it builds into: the test writes through `sb` and reads `status`, as production reads `TurnSink.status`. */
|
|
19
|
+
function makeStatusBuilder(): { sb: TranscriptBuilder; status: AgentExecutionStatus } {
|
|
20
|
+
const status = create(AgentExecutionStatusSchema, {});
|
|
21
|
+
return { sb: new TranscriptBuilder("exec-test", status), status };
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
function mockWorkspaceBackend(files: Record<string, string>): WorkspaceBackend {
|
|
@@ -55,19 +57,20 @@ function sha256(content: string): string {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
describe("InlinePublisher", () => {
|
|
58
|
-
let sb:
|
|
60
|
+
let sb: TranscriptBuilder;
|
|
61
|
+
let status: AgentExecutionStatus;
|
|
59
62
|
let storage: ReturnType<typeof mockArtifactStorage>;
|
|
60
63
|
let backend: WorkspaceBackend;
|
|
61
64
|
let publisher: InlinePublisher;
|
|
62
65
|
|
|
63
66
|
beforeEach(() => {
|
|
64
|
-
sb = makeStatusBuilder();
|
|
67
|
+
({ sb, status } = makeStatusBuilder());
|
|
65
68
|
storage = mockArtifactStorage();
|
|
66
69
|
backend = mockWorkspaceBackend({ "src/main.ts": "console.log('hello');" });
|
|
67
70
|
publisher = new InlinePublisher({
|
|
68
71
|
workspaceBackend: backend,
|
|
69
72
|
artifactStorage: storage,
|
|
70
|
-
|
|
73
|
+
artifacts: sb,
|
|
71
74
|
executionId: "exec-123",
|
|
72
75
|
});
|
|
73
76
|
});
|
|
@@ -76,9 +79,9 @@ describe("InlinePublisher", () => {
|
|
|
76
79
|
await publisher.publish("src/main.ts");
|
|
77
80
|
|
|
78
81
|
expect(storage.uploadedKeys).toEqual(["artifacts/exec-123/main.ts"]);
|
|
79
|
-
expect(
|
|
82
|
+
expect(status.artifacts).toHaveLength(1);
|
|
80
83
|
|
|
81
|
-
const artifact =
|
|
84
|
+
const artifact = status.artifacts[0];
|
|
82
85
|
expect(artifact.name).toBe("main.ts");
|
|
83
86
|
expect(artifact.sandboxPath).toBe("src/main.ts");
|
|
84
87
|
expect(artifact.kind).toBe(ExecutionArtifactKind.FILE);
|
|
@@ -90,8 +93,8 @@ describe("InlinePublisher", () => {
|
|
|
90
93
|
it("strips leading slashes from paths", async () => {
|
|
91
94
|
await publisher.publish("/src/main.ts");
|
|
92
95
|
|
|
93
|
-
expect(
|
|
94
|
-
expect(
|
|
96
|
+
expect(status.artifacts).toHaveLength(1);
|
|
97
|
+
expect(status.artifacts[0].sandboxPath).toBe("src/main.ts");
|
|
95
98
|
});
|
|
96
99
|
|
|
97
100
|
it("deduplicates by path + content hash", async () => {
|
|
@@ -99,7 +102,7 @@ describe("InlinePublisher", () => {
|
|
|
99
102
|
await publisher.publish("src/main.ts");
|
|
100
103
|
|
|
101
104
|
expect(storage.uploadedKeys).toHaveLength(1);
|
|
102
|
-
expect(
|
|
105
|
+
expect(status.artifacts).toHaveLength(1);
|
|
103
106
|
});
|
|
104
107
|
|
|
105
108
|
it("re-publishes when content changes", async () => {
|
|
@@ -109,8 +112,8 @@ describe("InlinePublisher", () => {
|
|
|
109
112
|
await publisher.publish("src/main.ts");
|
|
110
113
|
|
|
111
114
|
expect(storage.uploadedKeys).toHaveLength(2);
|
|
112
|
-
expect(
|
|
113
|
-
expect(
|
|
115
|
+
expect(status.artifacts).toHaveLength(1);
|
|
116
|
+
expect(status.artifacts[0].contentHash).toBe(sha256("updated content"));
|
|
114
117
|
});
|
|
115
118
|
|
|
116
119
|
it("exposes published paths for dedup by auto-publish", async () => {
|
|
@@ -128,13 +131,13 @@ describe("InlinePublisher", () => {
|
|
|
128
131
|
const pub = new InlinePublisher({
|
|
129
132
|
workspaceBackend: failBackend,
|
|
130
133
|
artifactStorage: storage,
|
|
131
|
-
|
|
134
|
+
artifacts: sb,
|
|
132
135
|
executionId: "exec-err",
|
|
133
136
|
});
|
|
134
137
|
|
|
135
138
|
await pub.publish("nonexistent.txt");
|
|
136
139
|
|
|
137
|
-
expect(
|
|
140
|
+
expect(status.artifacts).toHaveLength(0);
|
|
138
141
|
expect(warnSpy).toHaveBeenCalledWith(
|
|
139
142
|
expect.stringContaining("[InlinePublisher]"),
|
|
140
143
|
);
|
|
@@ -149,7 +152,7 @@ describe("InlinePublisher", () => {
|
|
|
149
152
|
|
|
150
153
|
await publisher.publish("src/main.ts");
|
|
151
154
|
|
|
152
|
-
expect(
|
|
155
|
+
expect(status.artifacts).toHaveLength(0);
|
|
153
156
|
expect(warnSpy).toHaveBeenCalled();
|
|
154
157
|
warnSpy.mockRestore();
|
|
155
158
|
});
|
|
@@ -160,7 +163,7 @@ describe("InlinePublisher", () => {
|
|
|
160
163
|
const expected = createHash("sha256")
|
|
161
164
|
.update(Buffer.from("console.log('hello');", "utf-8"))
|
|
162
165
|
.digest("hex");
|
|
163
|
-
expect(
|
|
166
|
+
expect(status.artifacts[0].contentHash).toBe(expected);
|
|
164
167
|
});
|
|
165
168
|
|
|
166
169
|
it("never publishes a secret-like file to artifact storage (design doc 12, D4)", async () => {
|
|
@@ -172,14 +175,14 @@ describe("InlinePublisher", () => {
|
|
|
172
175
|
const pub = new InlinePublisher({
|
|
173
176
|
workspaceBackend: secretBackend,
|
|
174
177
|
artifactStorage: storage,
|
|
175
|
-
|
|
178
|
+
artifacts: sb,
|
|
176
179
|
executionId: "exec-secret",
|
|
177
180
|
});
|
|
178
181
|
|
|
179
182
|
await pub.publish(".env");
|
|
180
183
|
|
|
181
184
|
expect(storage.uploadedKeys).toHaveLength(0);
|
|
182
|
-
expect(
|
|
185
|
+
expect(status.artifacts).toHaveLength(0);
|
|
183
186
|
expect(readSpy).not.toHaveBeenCalled(); // withheld before the file is even read
|
|
184
187
|
expect(pub.publishedPaths.size).toBe(0);
|
|
185
188
|
});
|
|
@@ -189,7 +192,7 @@ describe("InlinePublisher", () => {
|
|
|
189
192
|
const pub = new InlinePublisher({
|
|
190
193
|
workspaceBackend: jsonBackend,
|
|
191
194
|
artifactStorage: storage,
|
|
192
|
-
|
|
195
|
+
artifacts: sb,
|
|
193
196
|
executionId: "exec-ct",
|
|
194
197
|
});
|
|
195
198
|
|
|
@@ -209,21 +212,22 @@ describe("InlinePublisher with LocalWorkspaceBackend (disk-backed)", () => {
|
|
|
209
212
|
await mkdir(join(dir, "src"), { recursive: true });
|
|
210
213
|
await writeFile(join(dir, "src/app.ts"), "export const x = 42;", "utf-8");
|
|
211
214
|
|
|
212
|
-
const
|
|
215
|
+
const status = create(AgentExecutionStatusSchema, {});
|
|
216
|
+
const sb = new TranscriptBuilder("exec-disk", status);
|
|
213
217
|
const storage = mockArtifactStorage();
|
|
214
218
|
const backend = new LocalWorkspaceBackend(dir);
|
|
215
219
|
|
|
216
220
|
const publisher = new InlinePublisher({
|
|
217
221
|
workspaceBackend: backend,
|
|
218
222
|
artifactStorage: storage,
|
|
219
|
-
|
|
223
|
+
artifacts: sb,
|
|
220
224
|
executionId: "exec-disk",
|
|
221
225
|
});
|
|
222
226
|
|
|
223
227
|
await publisher.publish("src/app.ts");
|
|
224
228
|
|
|
225
|
-
expect(
|
|
226
|
-
const artifact =
|
|
229
|
+
expect(status.artifacts).toHaveLength(1);
|
|
230
|
+
const artifact = status.artifacts[0];
|
|
227
231
|
expect(artifact.name).toBe("app.ts");
|
|
228
232
|
expect(artifact.sandboxPath).toBe("src/app.ts");
|
|
229
233
|
expect(artifact.kind).toBe(ExecutionArtifactKind.FILE);
|
|
@@ -237,20 +241,21 @@ describe("InlinePublisher with LocalWorkspaceBackend (disk-backed)", () => {
|
|
|
237
241
|
const dir = join(tmpdir(), `stigmer-publisher-test-${Date.now()}`);
|
|
238
242
|
await mkdir(dir, { recursive: true });
|
|
239
243
|
|
|
240
|
-
const
|
|
244
|
+
const status = create(AgentExecutionStatusSchema, {});
|
|
245
|
+
const sb = new TranscriptBuilder("exec-miss", status);
|
|
241
246
|
const storage = mockArtifactStorage();
|
|
242
247
|
const backend = new LocalWorkspaceBackend(dir);
|
|
243
248
|
|
|
244
249
|
const publisher = new InlinePublisher({
|
|
245
250
|
workspaceBackend: backend,
|
|
246
251
|
artifactStorage: storage,
|
|
247
|
-
|
|
252
|
+
artifacts: sb,
|
|
248
253
|
executionId: "exec-miss",
|
|
249
254
|
});
|
|
250
255
|
|
|
251
256
|
await publisher.publish("nonexistent.ts");
|
|
252
257
|
|
|
253
|
-
expect(
|
|
258
|
+
expect(status.artifacts).toHaveLength(0);
|
|
254
259
|
expect(storage.uploadedKeys).toHaveLength(0);
|
|
255
260
|
expect(warnSpy).toHaveBeenCalledWith(
|
|
256
261
|
expect.stringContaining("[InlinePublisher]"),
|
|
@@ -2,13 +2,12 @@ import { describe, it, expect } from "vitest";
|
|
|
2
2
|
import { InteractionMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
3
3
|
import { buildEnhancedSystemPrompt, composeUserMessage } from "../prompt-builder.js";
|
|
4
4
|
import { PLAN_MODE_DIRECTIVE } from "../../../shared/plan-mode-prompt.js";
|
|
5
|
-
import { SourceType } from "../../../shared/workspace/types.js";
|
|
6
5
|
import type { ProvisionResult } from "../../../shared/workspace/types.js";
|
|
7
6
|
|
|
8
7
|
function makeProvisionResult(overrides: Partial<ProvisionResult> = {}): ProvisionResult {
|
|
9
8
|
return {
|
|
10
9
|
rootDir: "/workspace/project",
|
|
11
|
-
sourceType:
|
|
10
|
+
sourceType: "local_path",
|
|
12
11
|
consumedKeys: [],
|
|
13
12
|
workspaceDescription: "User project directory at /workspace/project",
|
|
14
13
|
entryName: "project",
|
|
@@ -266,7 +265,7 @@ describe("buildEnhancedSystemPrompt", () => {
|
|
|
266
265
|
instructions: "Test",
|
|
267
266
|
provisionResults: [
|
|
268
267
|
makeProvisionResult({
|
|
269
|
-
sourceType:
|
|
268
|
+
sourceType: "git_repo",
|
|
270
269
|
entryName: "my-repo",
|
|
271
270
|
rootDir: "/workspace/my-repo",
|
|
272
271
|
gitMetadata: {
|
|
@@ -277,7 +276,7 @@ describe("buildEnhancedSystemPrompt", () => {
|
|
|
277
276
|
},
|
|
278
277
|
}),
|
|
279
278
|
makeProvisionResult({
|
|
280
|
-
sourceType:
|
|
279
|
+
sourceType: "empty",
|
|
281
280
|
entryName: "scratch",
|
|
282
281
|
rootDir: "/workspace/scratch",
|
|
283
282
|
}),
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* The native system prompt, whole, as goldens.
|
|
3
3
|
*
|
|
4
4
|
* Every other prompt test in this directory asserts with `toContain`; the
|
|
5
|
-
* hermetic goldens are status JSON and never see a prompt. So until
|
|
5
|
+
* hermetic goldens are status JSON and never see a prompt. So until #1096 no
|
|
6
6
|
* test pinned a rendered prompt byte for byte, and the relevance-filtered
|
|
7
7
|
* `## Skills` section (eight or more skills, `turn-setup.ts`
|
|
8
8
|
* `renderRootSkillsSection`) had no test at all. These goldens are the
|
|
9
9
|
* photograph taken BEFORE the shared prompt glue moved into
|
|
10
|
-
* `shared/prompt-sections.ts` (
|
|
11
|
-
* byte-identical — the same discipline
|
|
10
|
+
* `shared/prompt-sections.ts` (#1096), so the move could be proven
|
|
11
|
+
* byte-identical — the same discipline the hermetic net applied to the
|
|
12
|
+
* activity's status.
|
|
12
13
|
*
|
|
13
14
|
* Why bytes matter here beyond taste: `ScriptedModel` tells its scripted
|
|
14
15
|
* roles apart by the system prompt's text (`__test-utils__/scripted-model.ts`
|
|
@@ -25,9 +26,10 @@
|
|
|
25
26
|
*
|
|
26
27
|
* The goldens are taken through `turn-setup.ts` `composeSystemPrompt`, the
|
|
27
28
|
* production mapping from the runtime's resolved record to the builder's
|
|
28
|
-
* input, so they pin the mapping too, not a copy of it. (
|
|
29
|
-
* prompt through a field-for-field copy of the mapping as
|
|
30
|
-
* in `buildEngine`;
|
|
29
|
+
* input, so they pin the mapping too, not a copy of it. (The first cut
|
|
30
|
+
* photographed the prompt through a field-for-field copy of the mapping as
|
|
31
|
+
* it then sat inline in `buildEngine`; the next extracted it and re-took the
|
|
32
|
+
* goldens through the
|
|
31
33
|
* extraction — byte-identical, which is the proof the extraction is one.)
|
|
32
34
|
*
|
|
33
35
|
* A golden moves only under a ruling quoted in this header; never a quiet
|
|
@@ -49,7 +51,7 @@ import type { TurnInput } from "../../../harness/types.js";
|
|
|
49
51
|
import type { ResolvedAttachment } from "../../../shared/attachment-resolver.js";
|
|
50
52
|
import type { SkillMetadata } from "../../../shared/skill-resolver.js";
|
|
51
53
|
import type { RecalledMemoriesContent } from "../../../shared/recalled-memories.js";
|
|
52
|
-
import {
|
|
54
|
+
import type { ProvisionResult } from "../../../shared/workspace/types.js";
|
|
53
55
|
import { buildEnhancedSystemPrompt } from "../prompt-builder.js";
|
|
54
56
|
import { composeSystemPrompt } from "../turn-setup.js";
|
|
55
57
|
|
|
@@ -81,7 +83,7 @@ const THREE_SKILLS: readonly SkillMetadata[] = NINE_SKILLS.slice(0, 3);
|
|
|
81
83
|
const PROVISION_RESULTS: readonly ProvisionResult[] = [
|
|
82
84
|
{
|
|
83
85
|
rootDir: "/ws/app",
|
|
84
|
-
sourceType:
|
|
86
|
+
sourceType: "git_repo",
|
|
85
87
|
consumedKeys: [],
|
|
86
88
|
workspaceDescription: "The payments service, cloned from git.",
|
|
87
89
|
entryName: "app",
|
|
@@ -90,7 +92,7 @@ const PROVISION_RESULTS: readonly ProvisionResult[] = [
|
|
|
90
92
|
},
|
|
91
93
|
{
|
|
92
94
|
rootDir: "/ws/docs",
|
|
93
|
-
sourceType:
|
|
95
|
+
sourceType: "local_path",
|
|
94
96
|
consumedKeys: [],
|
|
95
97
|
workspaceDescription: "The docs folder on the user's machine.",
|
|
96
98
|
entryName: "docs",
|
|
@@ -209,7 +211,7 @@ async function systemPromptOf(input: TurnInput): Promise<string> {
|
|
|
209
211
|
// Goldens
|
|
210
212
|
// ---------------------------------------------------------------------------
|
|
211
213
|
|
|
212
|
-
describe("native system prompt goldens
|
|
214
|
+
describe("native system prompt goldens", () => {
|
|
213
215
|
it("everything at once, nine skills so the relevance filter fires", async () => {
|
|
214
216
|
const prompt = await systemPromptOf(everythingInput({ skills: NINE_SKILLS }));
|
|
215
217
|
await expect(prompt).toMatchFileSnapshot("./goldens/system-prompt.everything.prompt.md");
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* deepagents graph aborted mid-hang through the run's own signal, the
|
|
26
26
|
* parked model unparks, the stream rejects with the abort, and the
|
|
27
27
|
* process sees no orphaned rejection — the posture the contract kit's
|
|
28
|
-
* hang arms and the runtime's stall watchdog rely on (
|
|
28
|
+
* hang arms and the runtime's stall watchdog rely on (#1096
|
|
29
29
|
* measured one orphan for a forced mid-step abort of a WEDGED engine;
|
|
30
30
|
* an engine that honours its signal leaves none, and this arm is where
|
|
31
31
|
* that fact is pinned).
|
|
@@ -102,12 +102,22 @@ describe("ScriptedModel — turns are indexed by the transcript, not by a counte
|
|
|
102
102
|
expect(replayed.tool_calls?.[0]?.id).toBe("call_b");
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
-
it("reports the role
|
|
105
|
+
it("reports the role, the round and the calls it answers to onTurn before rendering", async () => {
|
|
106
106
|
const seen: ScriptedTurnInfo[] = [];
|
|
107
107
|
const model = new ScriptedModel(() => script, [], { onTurn: (info) => void seen.push(info) });
|
|
108
108
|
const bound = model.bindTools([{ name: "probe" }]);
|
|
109
109
|
await bound.invoke(transcriptWithRounds(2));
|
|
110
|
-
|
|
110
|
+
// The prior calls are the LAST AI message's — the results this turn
|
|
111
|
+
// answers — read from the transcript, not the script.
|
|
112
|
+
expect(seen).toEqual([{ boundToolNames: ["probe"], round: 2, priorToolCallIds: ["call_1"] }]);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("reports no prior calls on a first turn or after a text-only turn", async () => {
|
|
116
|
+
const seen: ScriptedTurnInfo[] = [];
|
|
117
|
+
const model = new ScriptedModel(() => script, [], { onTurn: (info) => void seen.push(info) });
|
|
118
|
+
await model.invoke(transcriptWithRounds(0));
|
|
119
|
+
await model.invoke([...transcriptWithRounds(1), new AIMessage("a text-only turn"), new HumanMessage("more")]);
|
|
120
|
+
expect(seen.map((s) => s.priorToolCallIds)).toEqual([[], []]);
|
|
111
121
|
});
|
|
112
122
|
|
|
113
123
|
it("throws a diagnosing error when the script runs out", async () => {
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `StreamingSideEffects`:
|
|
3
|
-
* `
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* `StreamingSideEffects`: a `tool_started` carries the tool INPUT and a
|
|
3
|
+
* `tool_finished` its completion, so the trigger correlates the two by
|
|
4
|
+
* `callId` and publishes a file-modifying tool's target path once the call
|
|
5
|
+
* has finished. Driven the way the loop drives it (since #1097): raw v3 events
|
|
6
|
+
* through the translator, the canonical events into the trigger.
|
|
6
7
|
*
|
|
7
8
|
* Carried from the legacy v3 loop's suite (`streaming-v3.test.ts`, retired
|
|
8
|
-
* with the loop
|
|
9
|
+
* with the loop in #1096) — the trigger itself never had a test of its own.
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
import { describe, it, expect, vi } from "vitest";
|
|
12
13
|
|
|
13
14
|
import { StreamingSideEffects } from "../streaming-side-effects.js";
|
|
15
|
+
import { DeepAgentTranslator } from "../translator.js";
|
|
14
16
|
import type { InlinePublisher } from "../inline-publisher.js";
|
|
17
|
+
import type { V3ProtocolEvent } from "../v3-event-recorder.js";
|
|
15
18
|
import { makeToolFinished, makeToolStarted, resetSeq } from "../__test-utils__/v3-event-fixtures.js";
|
|
16
19
|
|
|
20
|
+
/** What the loop does per raw event: translate, then hand every canonical event to the trigger. */
|
|
21
|
+
function feed(effects: StreamingSideEffects, raw: V3ProtocolEvent): void {
|
|
22
|
+
for (const event of new DeepAgentTranslator(null).translate(raw)) effects.onEvent(event);
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
function publisherDouble(): { publisher: InlinePublisher; publish: ReturnType<typeof vi.fn> } {
|
|
18
26
|
const publish = vi.fn(async (_path: string) => undefined);
|
|
19
27
|
// The trigger reads exactly one member of the publisher.
|
|
@@ -26,10 +34,10 @@ describe("StreamingSideEffects", () => {
|
|
|
26
34
|
const { publisher, publish } = publisherDouble();
|
|
27
35
|
const effects = new StreamingSideEffects({ inlinePublisher: publisher });
|
|
28
36
|
|
|
29
|
-
effects
|
|
37
|
+
feed(effects, makeToolStarted("toolu_1", "write_file", { file_path: "/ws/index.ts", content: "x" }));
|
|
30
38
|
expect(publish, "not before the call finishes").not.toHaveBeenCalled();
|
|
31
39
|
|
|
32
|
-
effects
|
|
40
|
+
feed(effects, makeToolFinished("toolu_1", "written"));
|
|
33
41
|
expect(publish).toHaveBeenCalledWith("/ws/index.ts");
|
|
34
42
|
expect(effects.pendingPublishPromises).toHaveLength(1);
|
|
35
43
|
});
|
|
@@ -39,8 +47,8 @@ describe("StreamingSideEffects", () => {
|
|
|
39
47
|
const { publisher, publish } = publisherDouble();
|
|
40
48
|
const effects = new StreamingSideEffects({ inlinePublisher: publisher });
|
|
41
49
|
|
|
42
|
-
effects
|
|
43
|
-
effects
|
|
50
|
+
feed(effects, makeToolStarted("toolu_2", "read_file", { path: "/ws/index.ts" }));
|
|
51
|
+
feed(effects, makeToolFinished("toolu_2", "contents"));
|
|
44
52
|
expect(publish).not.toHaveBeenCalled();
|
|
45
53
|
expect(effects.pendingPublishPromises).toHaveLength(0);
|
|
46
54
|
});
|
|
@@ -50,10 +58,10 @@ describe("StreamingSideEffects", () => {
|
|
|
50
58
|
const { publisher, publish } = publisherDouble();
|
|
51
59
|
const effects = new StreamingSideEffects({ inlinePublisher: publisher });
|
|
52
60
|
|
|
53
|
-
effects
|
|
54
|
-
effects
|
|
55
|
-
effects
|
|
56
|
-
effects
|
|
61
|
+
feed(effects, makeToolStarted("toolu_3", "edit", { filePath: "/ws/a.ts" }));
|
|
62
|
+
feed(effects, makeToolFinished("toolu_3", "ok"));
|
|
63
|
+
feed(effects, makeToolStarted("toolu_4", "write", JSON.stringify({ path: "/ws/b.ts" })));
|
|
64
|
+
feed(effects, makeToolFinished("toolu_4", "ok"));
|
|
57
65
|
expect(publish.mock.calls.map((c) => c[0])).toEqual(["/ws/a.ts", "/ws/b.ts"]);
|
|
58
66
|
});
|
|
59
67
|
|
|
@@ -62,17 +70,17 @@ describe("StreamingSideEffects", () => {
|
|
|
62
70
|
const { publisher, publish } = publisherDouble();
|
|
63
71
|
const effects = new StreamingSideEffects({ inlinePublisher: publisher });
|
|
64
72
|
|
|
65
|
-
effects
|
|
66
|
-
effects
|
|
67
|
-
effects
|
|
73
|
+
feed(effects, makeToolFinished("toolu_never_started", "ok"));
|
|
74
|
+
feed(effects, makeToolStarted("toolu_5", "write_file", { content: "no path" }));
|
|
75
|
+
feed(effects, makeToolFinished("toolu_5", "ok"));
|
|
68
76
|
expect(publish).not.toHaveBeenCalled();
|
|
69
77
|
});
|
|
70
78
|
|
|
71
79
|
it("does nothing at all without a publisher", () => {
|
|
72
80
|
resetSeq();
|
|
73
81
|
const effects = new StreamingSideEffects({});
|
|
74
|
-
effects
|
|
75
|
-
effects
|
|
82
|
+
feed(effects, makeToolStarted("toolu_6", "write_file", { path: "/ws/x" }));
|
|
83
|
+
feed(effects, makeToolFinished("toolu_6", "ok"));
|
|
76
84
|
expect(effects.pendingPublishPromises).toHaveLength(0);
|
|
77
85
|
});
|
|
78
86
|
});
|
|
@@ -46,7 +46,7 @@ describe("buildSubAgentMiddleware", () => {
|
|
|
46
46
|
|
|
47
47
|
const subView = stack[4];
|
|
48
48
|
expect(subView.afterModel).toBeDefined();
|
|
49
|
-
expect(subView.wrapToolCall, "the advisory never blocks a tool; the runtime enforces the cap
|
|
49
|
+
expect(subView.wrapToolCall, "the advisory never blocks a tool; the runtime enforces the cap").toBeUndefined();
|
|
50
50
|
expect(subView.beforeAgent).toBeUndefined();
|
|
51
51
|
});
|
|
52
52
|
|