@assemblyline-agents/runtime 1.0.0 → 3.0.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/LICENSE +1 -1
- package/dist/a2a-client.d.ts +22 -0
- package/dist/a2a-client.d.ts.map +1 -0
- package/dist/a2a-client.js +211 -0
- package/dist/a2a-client.js.map +1 -0
- package/dist/agent-capability-snapshot.d.ts +32 -0
- package/dist/agent-capability-snapshot.d.ts.map +1 -0
- package/dist/agent-capability-snapshot.js +77 -0
- package/dist/agent-capability-snapshot.js.map +1 -0
- package/dist/agent-event-handlers.d.ts +21 -0
- package/dist/agent-event-handlers.d.ts.map +1 -0
- package/dist/agent-event-handlers.js +64 -0
- package/dist/agent-event-handlers.js.map +1 -0
- package/dist/agent-hook-context.d.ts +8 -0
- package/dist/agent-hook-context.d.ts.map +1 -0
- package/dist/agent-hook-context.js +29 -0
- package/dist/agent-hook-context.js.map +1 -0
- package/dist/agent-hook-evaluation.d.ts +61 -0
- package/dist/agent-hook-evaluation.d.ts.map +1 -0
- package/dist/agent-hook-evaluation.js +197 -0
- package/dist/agent-hook-evaluation.js.map +1 -0
- package/dist/agent-hook-run-lifecycle.d.ts +44 -0
- package/dist/agent-hook-run-lifecycle.d.ts.map +1 -0
- package/dist/agent-hook-run-lifecycle.js +76 -0
- package/dist/agent-hook-run-lifecycle.js.map +1 -0
- package/dist/agent-state.d.ts +31 -0
- package/dist/agent-state.d.ts.map +1 -0
- package/dist/agent-state.js +80 -0
- package/dist/agent-state.js.map +1 -0
- package/dist/agent-surface.d.ts +32 -0
- package/dist/agent-surface.d.ts.map +1 -0
- package/dist/agent-surface.js +85 -0
- package/dist/agent-surface.js.map +1 -0
- package/dist/attachments.d.ts +5 -1
- package/dist/attachments.d.ts.map +1 -1
- package/dist/attachments.js +58 -32
- package/dist/attachments.js.map +1 -1
- package/dist/audience.d.ts +30 -0
- package/dist/audience.d.ts.map +1 -0
- package/dist/audience.js +68 -0
- package/dist/audience.js.map +1 -0
- package/dist/authored-hooks.d.ts +6 -0
- package/dist/authored-hooks.d.ts.map +1 -0
- package/dist/authored-hooks.js +17 -0
- package/dist/authored-hooks.js.map +1 -0
- package/dist/automation-event-match.d.ts +8 -0
- package/dist/automation-event-match.d.ts.map +1 -0
- package/dist/automation-event-match.js +25 -0
- package/dist/automation-event-match.js.map +1 -0
- package/dist/background-review-trigger.d.ts +9 -0
- package/dist/background-review-trigger.d.ts.map +1 -0
- package/dist/background-review-trigger.js +72 -0
- package/dist/background-review-trigger.js.map +1 -0
- package/dist/background-review-types.d.ts +60 -0
- package/dist/background-review-types.d.ts.map +1 -0
- package/dist/background-review-types.js +2 -0
- package/dist/background-review-types.js.map +1 -0
- package/dist/background-review-worker.d.ts +14 -0
- package/dist/background-review-worker.d.ts.map +1 -0
- package/dist/background-review-worker.js +61 -0
- package/dist/background-review-worker.js.map +1 -0
- package/dist/background-review.d.ts +5 -0
- package/dist/background-review.d.ts.map +1 -0
- package/dist/background-review.js +332 -0
- package/dist/background-review.js.map +1 -0
- package/dist/builtin-tool-executors.d.ts +50 -27
- package/dist/builtin-tool-executors.d.ts.map +1 -1
- package/dist/builtin-tool-executors.js +332 -124
- package/dist/builtin-tool-executors.js.map +1 -1
- package/dist/builtin-tools.d.ts +16 -9
- package/dist/builtin-tools.d.ts.map +1 -1
- package/dist/builtin-tools.js +308 -116
- package/dist/builtin-tools.js.map +1 -1
- package/dist/capability-catalog.d.ts +3 -2
- package/dist/capability-catalog.d.ts.map +1 -1
- package/dist/capability-catalog.js +12 -7
- package/dist/capability-catalog.js.map +1 -1
- package/dist/capability-inspection.d.ts +31 -0
- package/dist/capability-inspection.d.ts.map +1 -0
- package/dist/capability-inspection.js +58 -0
- package/dist/capability-inspection.js.map +1 -0
- package/dist/channel-http-util.d.ts.map +1 -1
- package/dist/channel-http-util.js +6 -5
- package/dist/channel-http-util.js.map +1 -1
- package/dist/channel-ingress.d.ts +16 -1
- package/dist/channel-ingress.d.ts.map +1 -1
- package/dist/channel-ingress.js +152 -14
- package/dist/channel-ingress.js.map +1 -1
- package/dist/channel.d.ts +73 -3
- package/dist/channel.d.ts.map +1 -1
- package/dist/checkpoints.d.ts +1 -1
- package/dist/checkpoints.d.ts.map +1 -1
- package/dist/checkpoints.js +6 -6
- package/dist/checkpoints.js.map +1 -1
- package/dist/child-process-env.d.ts +7 -0
- package/dist/child-process-env.d.ts.map +1 -0
- package/dist/child-process-env.js +41 -0
- package/dist/child-process-env.js.map +1 -0
- package/dist/computer-relay-protocol.d.ts.map +1 -1
- package/dist/computer-relay-protocol.js +4 -4
- package/dist/computer-relay-protocol.js.map +1 -1
- package/dist/concurrency.d.ts +1 -1
- package/dist/concurrency.js +1 -1
- package/dist/connection-auth-util.d.ts +1 -0
- package/dist/connection-auth-util.d.ts.map +1 -1
- package/dist/connection-auth-util.js +3 -1
- package/dist/connection-auth-util.js.map +1 -1
- package/dist/connection-clients.d.ts +11 -3
- package/dist/connection-clients.d.ts.map +1 -1
- package/dist/connection-clients.js +71 -8
- package/dist/connection-clients.js.map +1 -1
- package/dist/connection-event-store.d.ts +98 -0
- package/dist/connection-event-store.d.ts.map +1 -0
- package/dist/connection-event-store.js +162 -0
- package/dist/connection-event-store.js.map +1 -0
- package/dist/connection-events.d.ts +51 -0
- package/dist/connection-events.d.ts.map +1 -0
- package/dist/connection-events.js +343 -0
- package/dist/connection-events.js.map +1 -0
- package/dist/connection-stores.d.ts +6 -0
- package/dist/connection-stores.d.ts.map +1 -1
- package/dist/connection-stores.js +20 -1
- package/dist/connection-stores.js.map +1 -1
- package/dist/connection-util.d.ts +3 -2
- package/dist/connection-util.d.ts.map +1 -1
- package/dist/connection-util.js +18 -1
- package/dist/connection-util.js.map +1 -1
- package/dist/connections.d.ts +60 -5
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +390 -57
- package/dist/connections.js.map +1 -1
- package/dist/context-policy-util.d.ts.map +1 -1
- package/dist/context-policy-util.js +1 -3
- package/dist/context-policy-util.js.map +1 -1
- package/dist/conversation-context.d.ts +9 -4
- package/dist/conversation-context.d.ts.map +1 -1
- package/dist/conversation-context.js +65 -19
- package/dist/conversation-context.js.map +1 -1
- package/dist/conversation-transcript.d.ts +8 -5
- package/dist/conversation-transcript.d.ts.map +1 -1
- package/dist/conversation-transcript.js +24 -5
- package/dist/conversation-transcript.js.map +1 -1
- package/dist/conversation-turn-coalescing.d.ts +22 -0
- package/dist/conversation-turn-coalescing.d.ts.map +1 -0
- package/dist/conversation-turn-coalescing.js +121 -0
- package/dist/conversation-turn-coalescing.js.map +1 -0
- package/dist/conversation-turn-dispatch.d.ts +5 -2
- package/dist/conversation-turn-dispatch.d.ts.map +1 -1
- package/dist/conversation-turn-dispatch.js +59 -22
- package/dist/conversation-turn-dispatch.js.map +1 -1
- package/dist/default-outbound-route.d.ts +29 -0
- package/dist/default-outbound-route.d.ts.map +1 -0
- package/dist/default-outbound-route.js +105 -0
- package/dist/default-outbound-route.js.map +1 -0
- package/dist/delivery-artifacts.d.ts +2 -0
- package/dist/delivery-artifacts.d.ts.map +1 -0
- package/dist/delivery-artifacts.js +34 -0
- package/dist/delivery-artifacts.js.map +1 -0
- package/dist/delivery-files.d.ts +5 -0
- package/dist/delivery-files.d.ts.map +1 -0
- package/dist/delivery-files.js +33 -0
- package/dist/delivery-files.js.map +1 -0
- package/dist/delivery-queue.d.ts +21 -1
- package/dist/delivery-queue.d.ts.map +1 -1
- package/dist/delivery-queue.js +144 -1
- package/dist/delivery-queue.js.map +1 -1
- package/dist/delivery-send.d.ts +2 -2
- package/dist/delivery-send.d.ts.map +1 -1
- package/dist/delivery-send.js +256 -100
- package/dist/delivery-send.js.map +1 -1
- package/dist/durable-files.d.ts +37 -0
- package/dist/durable-files.d.ts.map +1 -0
- package/dist/durable-files.js +63 -0
- package/dist/durable-files.js.map +1 -0
- package/dist/harness-loop.d.ts +18 -9
- package/dist/harness-loop.d.ts.map +1 -1
- package/dist/harness-loop.js +245 -50
- package/dist/harness-loop.js.map +1 -1
- package/dist/heic-transcode-worker.d.ts +2 -0
- package/dist/heic-transcode-worker.d.ts.map +1 -0
- package/dist/heic-transcode-worker.js +59 -0
- package/dist/heic-transcode-worker.js.map +1 -0
- package/dist/heic-transcode.d.ts +18 -0
- package/dist/heic-transcode.d.ts.map +1 -0
- package/dist/heic-transcode.js +99 -0
- package/dist/heic-transcode.js.map +1 -0
- package/dist/human-input-routing.d.ts +22 -0
- package/dist/human-input-routing.d.ts.map +1 -0
- package/dist/human-input-routing.js +26 -0
- package/dist/human-input-routing.js.map +1 -0
- package/dist/in-memory-agent-state-store.d.ts +21 -0
- package/dist/in-memory-agent-state-store.d.ts.map +1 -0
- package/dist/in-memory-agent-state-store.js +97 -0
- package/dist/in-memory-agent-state-store.js.map +1 -0
- package/dist/in-memory-conversation-turn-store.d.ts +3 -1
- package/dist/in-memory-conversation-turn-store.d.ts.map +1 -1
- package/dist/in-memory-conversation-turn-store.js +41 -2
- package/dist/in-memory-conversation-turn-store.js.map +1 -1
- package/dist/in-memory-run-store.d.ts +8 -0
- package/dist/in-memory-run-store.d.ts.map +1 -1
- package/dist/in-memory-run-store.js +28 -5
- package/dist/in-memory-run-store.js.map +1 -1
- package/dist/in-memory-sandbox-session-store.d.ts +2 -1
- package/dist/in-memory-sandbox-session-store.d.ts.map +1 -1
- package/dist/in-memory-sandbox-session-store.js +65 -1
- package/dist/in-memory-sandbox-session-store.js.map +1 -1
- package/dist/in-memory-small-stores.d.ts +18 -1
- package/dist/in-memory-small-stores.d.ts.map +1 -1
- package/dist/in-memory-small-stores.js +107 -1
- package/dist/in-memory-small-stores.js.map +1 -1
- package/dist/in-memory-workspace-store.d.ts +40 -0
- package/dist/in-memory-workspace-store.d.ts.map +1 -0
- package/dist/in-memory-workspace-store.js +370 -0
- package/dist/in-memory-workspace-store.js.map +1 -0
- package/dist/index.d.ts +116 -45
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +637 -566
- package/dist/index.js.map +1 -1
- package/dist/json-util.d.ts +8 -0
- package/dist/json-util.d.ts.map +1 -1
- package/dist/json-util.js +8 -0
- package/dist/json-util.js.map +1 -1
- package/dist/learning-store.d.ts +111 -0
- package/dist/learning-store.d.ts.map +1 -0
- package/dist/learning-store.js +193 -0
- package/dist/learning-store.js.map +1 -0
- package/dist/local-sandbox.d.ts +3 -2
- package/dist/local-sandbox.d.ts.map +1 -1
- package/dist/local-sandbox.js +69 -25
- package/dist/local-sandbox.js.map +1 -1
- package/dist/mcp-client.d.ts.map +1 -1
- package/dist/mcp-client.js +3 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/media-processor.d.ts +42 -0
- package/dist/media-processor.d.ts.map +1 -0
- package/dist/media-processor.js +2 -0
- package/dist/media-processor.js.map +1 -0
- package/dist/model-media.d.ts +13 -1
- package/dist/model-media.d.ts.map +1 -1
- package/dist/model-media.js +81 -18
- package/dist/model-media.js.map +1 -1
- package/dist/model-visible-interrupts.d.ts +10 -0
- package/dist/model-visible-interrupts.d.ts.map +1 -0
- package/dist/model-visible-interrupts.js +41 -0
- package/dist/model-visible-interrupts.js.map +1 -0
- package/dist/operator-controls.d.ts.map +1 -1
- package/dist/operator-controls.js +16 -3
- package/dist/operator-controls.js.map +1 -1
- package/dist/outbound-http-policy.d.ts +7 -0
- package/dist/outbound-http-policy.d.ts.map +1 -0
- package/dist/outbound-http-policy.js +155 -0
- package/dist/outbound-http-policy.js.map +1 -0
- package/dist/principals.d.ts +18 -0
- package/dist/principals.d.ts.map +1 -0
- package/dist/principals.js +90 -0
- package/dist/principals.js.map +1 -0
- package/dist/public-api.d.ts +21 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +19 -0
- package/dist/public-api.js.map +1 -0
- package/dist/replay-resume.d.ts +15 -3
- package/dist/replay-resume.d.ts.map +1 -1
- package/dist/replay-resume.js +256 -24
- package/dist/replay-resume.js.map +1 -1
- package/dist/resource-projection-util.d.ts +1 -1
- package/dist/resource-projection-util.d.ts.map +1 -1
- package/dist/resource-projection-util.js +21 -10
- package/dist/resource-projection-util.js.map +1 -1
- package/dist/resource-projection.d.ts +8 -1
- package/dist/resource-projection.d.ts.map +1 -1
- package/dist/resource-projection.js +230 -26
- package/dist/resource-projection.js.map +1 -1
- package/dist/run-heartbeat.d.ts +12 -2
- package/dist/run-heartbeat.d.ts.map +1 -1
- package/dist/run-heartbeat.js +31 -4
- package/dist/run-heartbeat.js.map +1 -1
- package/dist/run-outcome.d.ts +9 -5
- package/dist/run-outcome.d.ts.map +1 -1
- package/dist/run-outcome.js +16 -5
- package/dist/run-outcome.js.map +1 -1
- package/dist/run-recovery.d.ts +31 -2
- package/dist/run-recovery.d.ts.map +1 -1
- package/dist/run-recovery.js +211 -32
- package/dist/run-recovery.js.map +1 -1
- package/dist/run-replay.d.ts +35 -0
- package/dist/run-replay.d.ts.map +1 -0
- package/dist/run-replay.js +193 -0
- package/dist/run-replay.js.map +1 -0
- package/dist/run-result.d.ts +4 -0
- package/dist/run-result.d.ts.map +1 -0
- package/dist/run-result.js +18 -0
- package/dist/run-result.js.map +1 -0
- package/dist/run-timeline-query.d.ts +38 -0
- package/dist/run-timeline-query.d.ts.map +1 -0
- package/dist/run-timeline-query.js +99 -0
- package/dist/run-timeline-query.js.map +1 -0
- package/dist/runs-query.d.ts.map +1 -1
- package/dist/runs-query.js +12 -4
- package/dist/runs-query.js.map +1 -1
- package/dist/runtime-bundle.d.ts.map +1 -1
- package/dist/runtime-bundle.js +2 -0
- package/dist/runtime-bundle.js.map +1 -1
- package/dist/runtime-learning.d.ts +88 -0
- package/dist/runtime-learning.d.ts.map +1 -0
- package/dist/runtime-learning.js +260 -0
- package/dist/runtime-learning.js.map +1 -0
- package/dist/runtime-types.d.ts +79 -10
- package/dist/runtime-types.d.ts.map +1 -1
- package/dist/sandbox-fs.d.ts +9 -5
- package/dist/sandbox-fs.d.ts.map +1 -1
- package/dist/sandbox-fs.js +50 -33
- package/dist/sandbox-fs.js.map +1 -1
- package/dist/sandbox-handle.d.ts +25 -0
- package/dist/sandbox-handle.d.ts.map +1 -0
- package/dist/sandbox-handle.js +120 -0
- package/dist/sandbox-handle.js.map +1 -0
- package/dist/sandbox-session-identity.d.ts +14 -0
- package/dist/sandbox-session-identity.d.ts.map +1 -0
- package/dist/sandbox-session-identity.js +33 -0
- package/dist/sandbox-session-identity.js.map +1 -0
- package/dist/sandbox-session-key.d.ts.map +1 -1
- package/dist/sandbox-session-key.js +14 -10
- package/dist/sandbox-session-key.js.map +1 -1
- package/dist/sandbox-session-lifecycle.d.ts +12 -0
- package/dist/sandbox-session-lifecycle.d.ts.map +1 -0
- package/dist/sandbox-session-lifecycle.js +261 -0
- package/dist/sandbox-session-lifecycle.js.map +1 -0
- package/dist/sandbox-snapshot-policy.js +3 -3
- package/dist/sandbox-snapshot-policy.js.map +1 -1
- package/dist/sandbox-state-sync.d.ts +22 -0
- package/dist/sandbox-state-sync.d.ts.map +1 -0
- package/dist/sandbox-state-sync.js +147 -0
- package/dist/sandbox-state-sync.js.map +1 -0
- package/dist/sandbox-sync-worker.d.ts +11 -2
- package/dist/sandbox-sync-worker.d.ts.map +1 -1
- package/dist/sandbox-sync-worker.js +143 -31
- package/dist/sandbox-sync-worker.js.map +1 -1
- package/dist/schedule-execution.d.ts.map +1 -1
- package/dist/schedule-execution.js +187 -57
- package/dist/schedule-execution.js.map +1 -1
- package/dist/sdk-api-client.d.ts +17 -0
- package/dist/sdk-api-client.d.ts.map +1 -0
- package/dist/sdk-api-client.js +55 -0
- package/dist/sdk-api-client.js.map +1 -0
- package/dist/security.js +2 -2
- package/dist/security.js.map +1 -1
- package/dist/self-improvement.d.ts +34 -6
- package/dist/self-improvement.d.ts.map +1 -1
- package/dist/self-improvement.js +140 -34
- package/dist/self-improvement.js.map +1 -1
- package/dist/skill-bundles.d.ts +55 -0
- package/dist/skill-bundles.d.ts.map +1 -0
- package/dist/skill-bundles.js +134 -0
- package/dist/skill-bundles.js.map +1 -0
- package/dist/source-loader.d.ts +8 -0
- package/dist/source-loader.d.ts.map +1 -1
- package/dist/source-loader.js +41 -10
- package/dist/source-loader.js.map +1 -1
- package/dist/state-store-helpers.d.ts +2 -0
- package/dist/state-store-helpers.d.ts.map +1 -1
- package/dist/state-store-helpers.js +11 -1
- package/dist/state-store-helpers.js.map +1 -1
- package/dist/state-stores.d.ts +2 -0
- package/dist/state-stores.d.ts.map +1 -1
- package/dist/state-stores.js +40 -7
- package/dist/state-stores.js.map +1 -1
- package/dist/state.d.ts +344 -5
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +44 -2
- package/dist/state.js.map +1 -1
- package/dist/storage.d.ts +59 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +183 -6
- package/dist/storage.js.map +1 -1
- package/dist/subagent-execution.d.ts +7 -6
- package/dist/subagent-execution.d.ts.map +1 -1
- package/dist/subagent-execution.js +58 -19
- package/dist/subagent-execution.js.map +1 -1
- package/dist/target-instructions.d.ts +14 -0
- package/dist/target-instructions.d.ts.map +1 -0
- package/dist/target-instructions.js +18 -0
- package/dist/target-instructions.js.map +1 -0
- package/dist/tool-apis.d.ts.map +1 -1
- package/dist/tool-apis.js +55 -10
- package/dist/tool-apis.js.map +1 -1
- package/dist/tool-execution.d.ts +26 -13
- package/dist/tool-execution.d.ts.map +1 -1
- package/dist/tool-execution.js +368 -239
- package/dist/tool-execution.js.map +1 -1
- package/dist/turn-media.d.ts +29 -0
- package/dist/turn-media.d.ts.map +1 -0
- package/dist/turn-media.js +233 -0
- package/dist/turn-media.js.map +1 -0
- package/dist/usage-reconciliation.d.ts +1 -1
- package/dist/usage-reconciliation.js +1 -1
- package/dist/workspace-id.d.ts +10 -0
- package/dist/workspace-id.d.ts.map +1 -0
- package/dist/workspace-id.js +55 -0
- package/dist/workspace-id.js.map +1 -0
- package/dist/workspace-manifest.d.ts +24 -0
- package/dist/workspace-manifest.d.ts.map +1 -0
- package/dist/workspace-manifest.js +111 -0
- package/dist/workspace-manifest.js.map +1 -0
- package/dist/workspace-operation-limiter.d.ts +16 -0
- package/dist/workspace-operation-limiter.d.ts.map +1 -0
- package/dist/workspace-operation-limiter.js +31 -0
- package/dist/workspace-operation-limiter.js.map +1 -0
- package/dist/workspace-operations.d.ts +145 -0
- package/dist/workspace-operations.d.ts.map +1 -0
- package/dist/workspace-operations.js +420 -0
- package/dist/workspace-operations.js.map +1 -0
- package/dist/workspace-runtime.d.ts +110 -0
- package/dist/workspace-runtime.d.ts.map +1 -0
- package/dist/workspace-runtime.js +240 -0
- package/dist/workspace-runtime.js.map +1 -0
- package/dist/workspace-search.d.ts +55 -0
- package/dist/workspace-search.d.ts.map +1 -0
- package/dist/workspace-search.js +262 -0
- package/dist/workspace-search.js.map +1 -0
- package/dist/workspace-service.d.ts +173 -0
- package/dist/workspace-service.d.ts.map +1 -0
- package/dist/workspace-service.js +619 -0
- package/dist/workspace-service.js.map +1 -0
- package/dist/workspace.d.ts +7 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +7 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +7 -4
- package/dist/agent-harness.d.ts +0 -108
- package/dist/agent-harness.d.ts.map +0 -1
- package/dist/agent-harness.js +0 -2
- package/dist/agent-harness.js.map +0 -1
- package/dist/attachments-legacy.d.ts +0 -17
- package/dist/attachments-legacy.d.ts.map +0 -1
- package/dist/attachments-legacy.js +0 -273
- package/dist/attachments-legacy.js.map +0 -1
- package/dist/code-mode.d.ts +0 -20
- package/dist/code-mode.d.ts.map +0 -1
- package/dist/code-mode.js +0 -658
- package/dist/code-mode.js.map +0 -1
- package/dist/hook-dispatch.d.ts +0 -19
- package/dist/hook-dispatch.d.ts.map +0 -1
- package/dist/hook-dispatch.js +0 -37
- package/dist/hook-dispatch.js.map +0 -1
- package/dist/pi-agent-harness.d.ts +0 -40
- package/dist/pi-agent-harness.d.ts.map +0 -1
- package/dist/pi-agent-harness.js +0 -222
- package/dist/pi-agent-harness.js.map +0 -1
- package/dist/pi-harness.d.ts +0 -42
- package/dist/pi-harness.d.ts.map +0 -1
- package/dist/pi-harness.js +0 -142
- package/dist/pi-harness.js.map +0 -1
- package/dist/run-resolver.d.ts +0 -35
- package/dist/run-resolver.d.ts.map +0 -1
- package/dist/run-resolver.js +0 -84
- package/dist/run-resolver.js.map +0 -1
- package/dist/usage-budget.d.ts +0 -29
- package/dist/usage-budget.d.ts.map +0 -1
- package/dist/usage-budget.js +0 -145
- package/dist/usage-budget.js.map +0 -1
package/dist/tool-execution.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { boundModelOutput, normalizeApprovalPolicy, sandboxFilesystemContractMetadata } from "@assemblyline-agents/core";
|
|
2
|
-
import {
|
|
3
|
-
import { createConnectionRegistryForRunImpl,
|
|
4
|
-
import { CONNECTION_SEARCH_TOOL_NAME, parseQualifiedName } from "./connections.js";
|
|
1
|
+
import { boundModelOutput, DELEGATE_TOOL_NAME, normalizeApprovalPolicy, sandboxFilesystemContractMetadata } from "@assemblyline-agents/core";
|
|
2
|
+
import { HISTORY_SEARCH_TOOL_NAME, FILES_MOUNT_TOOL_NAME, FILES_SEARCH_TOOL_NAME, LOAD_SKILL_TOOL_NAME, PAIR_TOOL_NAME, runtimeToolsForSurface, TOOL_SEARCH_TOOL_NAME, WORKSPACE_CHECKPOINT_CREATE_TOOL_NAME, WORKSPACE_CHECKPOINT_LIST_TOOL_NAME, WORKSPACE_CHECKPOINT_RESTORE_TOOL_NAME, WORKSPACE_FORK_TOOL_NAME, WORKSPACE_SEARCH_TOOL_NAME, WORKSPACE_STATUS_TOOL_NAME } from "./builtin-tools.js";
|
|
3
|
+
import { createConnectionRegistryForRunImpl, executeConnectionSearchTool, executeConnectionTool, executeHistorySearchTool, executeLoadSkillTool, executePairTool, executeToolSearchTool, failRuntimeHandledTool, recordRuntimeHandledToolStart } from "./builtin-tool-executors.js";
|
|
4
|
+
import { CONNECTION_SEARCH_TOOL_NAME, isConnectionConfigurationError, parseQualifiedName } from "./connections.js";
|
|
5
5
|
import { resolvePositiveIntegerEnv } from "./env-config.js";
|
|
6
6
|
import { harnessPauseOutcome } from "./harness-continuation.js";
|
|
7
7
|
import { evalRunOptionsForRun } from "./eval-run-options.js";
|
|
8
8
|
import { isJsonObject, previewString, redactedToolInput, safeJson } from "./json-util.js";
|
|
9
|
+
import { runUsesChannelReplyForHumanInput } from "./human-input-routing.js";
|
|
9
10
|
import { prepareToolModelOutput } from "./model-media.js";
|
|
10
|
-
import { failRun } from "./run-outcome.js";
|
|
11
11
|
import { sandboxWriteByteLength } from "./resource-projection-util.js";
|
|
12
12
|
import { stringValue, timestamp, toolRequiresSandbox } from "./runtime-util.js";
|
|
13
13
|
import { applyCoreToolPolicy, filterVisibleToolSet } from "./security.js";
|
|
@@ -16,10 +16,13 @@ export function visibleToolSetImpl(host, defaultToolNames, activeSkills) {
|
|
|
16
16
|
void activeSkills;
|
|
17
17
|
return filterVisibleToolSet(defaultToolNames, host.coreToolPolicy);
|
|
18
18
|
}
|
|
19
|
-
export async function modelToolsImpl(host, activeToolNames, connectionRegistry, discoveredConnectionTools = new Map()) {
|
|
19
|
+
export async function modelToolsImpl(host, run, activeToolNames, connectionRegistry, discoveredConnectionTools = new Map(), options = {}) {
|
|
20
20
|
const tools = [];
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const surface = host.surfaceForRun(run);
|
|
22
|
+
for (const tool of runtimeToolsForSurface(surface.tools)) {
|
|
23
|
+
const active = activeToolNames.has(tool.name);
|
|
24
|
+
const deferred = options.includeDeferred === true && tool.visibility === "deferred";
|
|
25
|
+
if (!active && !deferred)
|
|
23
26
|
continue;
|
|
24
27
|
const policyTool = applyCoreToolPolicy(tool, host.coreToolPolicy);
|
|
25
28
|
if (!policyTool)
|
|
@@ -30,17 +33,21 @@ export async function modelToolsImpl(host, activeToolNames, connectionRegistry,
|
|
|
30
33
|
description: definition.description ?? policyTool.description,
|
|
31
34
|
inputSchema: definition.inputSchema ?? policyTool.inputSchema
|
|
32
35
|
};
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
// the deferred-tool bridge can hit any of those through the tool it
|
|
36
|
-
// routes to.
|
|
37
|
-
if (policyTool.name === ASK_QUESTION_TOOL_NAME ||
|
|
38
|
-
policyTool.name === TOOL_CALL_TOOL_NAME ||
|
|
39
|
-
normalizeApprovalPolicy(policyTool.needsApproval).mode === "always") {
|
|
36
|
+
// Approval-gated tools park the run and therefore serialize their batch.
|
|
37
|
+
if (normalizeApprovalPolicy(policyTool.needsApproval).mode === "always") {
|
|
40
38
|
descriptor.execution = "sequential";
|
|
41
39
|
}
|
|
40
|
+
if (!active) {
|
|
41
|
+
descriptor.deferLoading = true;
|
|
42
|
+
options.exposedDeferredToolNames?.add(policyTool.name);
|
|
43
|
+
}
|
|
42
44
|
tools.push(descriptor);
|
|
43
45
|
}
|
|
46
|
+
// connection_search is not part of the built-in tool catalog, so it cannot
|
|
47
|
+
// be selected by authored setup() (capability validation rejects unknown
|
|
48
|
+
// names) and this branch stays dormant today. tool_search is the model's
|
|
49
|
+
// discovery surface for connection tools, and the core `pair` tool is the
|
|
50
|
+
// discovery-independent binding path.
|
|
44
51
|
if (connectionRegistry?.hasLiveConnections() && activeToolNames.has(CONNECTION_SEARCH_TOOL_NAME)) {
|
|
45
52
|
tools.push({
|
|
46
53
|
name: CONNECTION_SEARCH_TOOL_NAME,
|
|
@@ -66,30 +73,74 @@ export async function modelToolsImpl(host, activeToolNames, connectionRegistry,
|
|
|
66
73
|
}
|
|
67
74
|
});
|
|
68
75
|
}
|
|
76
|
+
if (options.includeDeferred && connectionRegistry?.hasLiveConnections()) {
|
|
77
|
+
const catalog = await connectionRegistry.search({ keywords: "", limit: Number.MAX_SAFE_INTEGER });
|
|
78
|
+
for (const result of catalog) {
|
|
79
|
+
if (!result.qualifiedName || !result.tool || !result.inputSchema)
|
|
80
|
+
continue;
|
|
81
|
+
const metadata = {
|
|
82
|
+
connection: result.connection,
|
|
83
|
+
name: result.tool,
|
|
84
|
+
qualifiedName: result.qualifiedName,
|
|
85
|
+
description: result.description,
|
|
86
|
+
inputSchema: result.inputSchema
|
|
87
|
+
};
|
|
88
|
+
if (result.outputSchema)
|
|
89
|
+
metadata.outputSchema = result.outputSchema;
|
|
90
|
+
discoveredConnectionTools.set(result.qualifiedName, metadata);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
69
93
|
for (const [qualifiedName, metadata] of discoveredConnectionTools) {
|
|
70
|
-
|
|
94
|
+
const active = activeToolNames.has(qualifiedName);
|
|
95
|
+
if (!active && !options.includeDeferred)
|
|
71
96
|
continue;
|
|
72
|
-
|
|
97
|
+
const descriptor = {
|
|
73
98
|
name: qualifiedName,
|
|
74
99
|
description: metadata.description,
|
|
75
100
|
inputSchema: metadata.inputSchema,
|
|
101
|
+
external: {
|
|
102
|
+
namespace: metadata.connection,
|
|
103
|
+
name: metadata.name
|
|
104
|
+
},
|
|
76
105
|
// Connection tools can pause for authorization at any call.
|
|
77
106
|
execution: "sequential"
|
|
78
|
-
}
|
|
107
|
+
};
|
|
108
|
+
if (!active) {
|
|
109
|
+
descriptor.deferLoading = true;
|
|
110
|
+
options.exposedDeferredToolNames?.add(qualifiedName);
|
|
111
|
+
}
|
|
112
|
+
tools.push(descriptor);
|
|
79
113
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
114
|
+
const selectedSubagentNames = new Set(Array.isArray(run.input.agentSubagents)
|
|
115
|
+
? run.input.agentSubagents.filter((name) => typeof name === "string")
|
|
116
|
+
: []);
|
|
117
|
+
const selectedSubagents = surface.subagents
|
|
118
|
+
.filter((subagent) => selectedSubagentNames.has(subagent.name))
|
|
119
|
+
.sort((left, right) => left.name.localeCompare(right.name));
|
|
120
|
+
if (activeToolNames.has(DELEGATE_TOOL_NAME) && selectedSubagents.length > 0) {
|
|
121
|
+
const directory = selectedSubagents
|
|
122
|
+
.map((subagent) => `${subagent.name}: ${subagent.description}`)
|
|
123
|
+
.join("\n");
|
|
83
124
|
tools.push({
|
|
84
|
-
name:
|
|
85
|
-
description:
|
|
125
|
+
name: DELEGATE_TOOL_NAME,
|
|
126
|
+
description: `Delegate one self-contained task to an enabled immediate child. The child has no parent transcript, so include needed context and usable file paths; review its result before replying. Available agents:\n${directory}`,
|
|
86
127
|
inputSchema: {
|
|
87
128
|
type: "object",
|
|
88
129
|
properties: {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
130
|
+
agent: {
|
|
131
|
+
type: "string",
|
|
132
|
+
enum: selectedSubagents.map((subagent) => subagent.name),
|
|
133
|
+
description: "Exact child-agent name from the available-agent directory."
|
|
134
|
+
},
|
|
135
|
+
task: { type: "string", description: "Self-contained objective and required context." },
|
|
136
|
+
expectedOutput: { type: "string", description: "Required result or artifact." },
|
|
137
|
+
constraints: {
|
|
138
|
+
type: "array",
|
|
139
|
+
items: { type: "string" },
|
|
140
|
+
description: "Limits, authority, and confidentiality requirements."
|
|
141
|
+
}
|
|
92
142
|
},
|
|
143
|
+
required: ["agent", "task"],
|
|
93
144
|
additionalProperties: true
|
|
94
145
|
}
|
|
95
146
|
});
|
|
@@ -97,127 +148,142 @@ export async function modelToolsImpl(host, activeToolNames, connectionRegistry,
|
|
|
97
148
|
return tools;
|
|
98
149
|
}
|
|
99
150
|
export async function harnessExecuteToolImpl(host, call, state) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return harnessResult(outcome.modelOutput, host.env);
|
|
109
|
-
}
|
|
110
|
-
if (name === TOOL_SEARCH_TOOL_NAME) {
|
|
111
|
-
const outcome = await executeToolSearchTool(host, state.run(), {
|
|
112
|
-
connectionRegistry: state.connectionRegistry,
|
|
113
|
-
discoveredConnectionTools: state.discoveredConnectionTools
|
|
114
|
-
}, params, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
115
|
-
state.setRun(outcome.run);
|
|
116
|
-
return harnessResult(outcome.modelOutput, host.env);
|
|
117
|
-
}
|
|
118
|
-
if (name === TOOL_DESCRIBE_TOOL_NAME) {
|
|
119
|
-
const outcome = await executeToolDescribeTool(host, state.run(), {
|
|
120
|
-
connectionRegistry: state.connectionRegistry,
|
|
121
|
-
discoveredConnectionTools: state.discoveredConnectionTools
|
|
122
|
-
}, params, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
123
|
-
state.setRun(outcome.run);
|
|
124
|
-
return harnessResult(outcome.modelOutput, host.env);
|
|
151
|
+
// Tool calls may already be queued in a provider response when the operator
|
|
152
|
+
// cancels. Re-read the durable run before every tool boundary so no new side
|
|
153
|
+
// effect starts after cancellation became visible to the operator.
|
|
154
|
+
const durableRun = await host.state.getRun(state.run().id);
|
|
155
|
+
if (durableRun?.status === "cancelled" || durableRun?.controlIntent === "cancel") {
|
|
156
|
+
if (durableRun)
|
|
157
|
+
state.setRun(durableRun);
|
|
158
|
+
return harnessResult({ cancelled: true }, host.env);
|
|
125
159
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
160
|
+
const { toolCallId, name, input: params } = call;
|
|
161
|
+
const boundaryIdempotencyKey = `tool:${state.run().id}:${name}:${toolCallId}`;
|
|
162
|
+
try {
|
|
163
|
+
if (!state.defaultToolNames.has(name) && !state.exposedDeferredToolNames.has(name)) {
|
|
164
|
+
await host.state.appendEvent(state.run().id, "tool.unavailable", {
|
|
165
|
+
toolName: name,
|
|
166
|
+
reason: "not_enabled_for_run"
|
|
167
|
+
});
|
|
168
|
+
throw new Error(`Tool ${name} is not enabled for this run.`);
|
|
169
|
+
}
|
|
170
|
+
if (state.exposedDeferredToolNames.has(name))
|
|
171
|
+
state.defaultToolNames.add(name);
|
|
172
|
+
if (name === LOAD_SKILL_TOOL_NAME) {
|
|
173
|
+
const outcome = await executeLoadSkillTool(host, state.run(), {
|
|
174
|
+
sandboxHandle: state.sandboxHandle,
|
|
175
|
+
allowedSkills: state.activeSkills
|
|
176
|
+
}, params, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
177
|
+
state.setRun(outcome.run);
|
|
178
|
+
return harnessResult(outcome.modelOutput, host.env);
|
|
179
|
+
}
|
|
180
|
+
if (name === TOOL_SEARCH_TOOL_NAME) {
|
|
181
|
+
const outcome = await executeToolSearchTool(host, state.run(), {
|
|
182
|
+
connectionRegistry: state.connectionRegistry,
|
|
183
|
+
discoveredConnectionTools: state.discoveredConnectionTools,
|
|
184
|
+
activeToolNames: state.defaultToolNames
|
|
185
|
+
}, params, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
186
|
+
state.setRun(outcome.run);
|
|
187
|
+
return harnessResult(outcome.modelOutput, host.env);
|
|
188
|
+
}
|
|
189
|
+
if (name === DELEGATE_TOOL_NAME) {
|
|
190
|
+
if (!isJsonObject(params))
|
|
191
|
+
throw new Error(`${DELEGATE_TOOL_NAME} requires an object input.`);
|
|
192
|
+
const subagentName = stringValue(params.agent);
|
|
193
|
+
if (!subagentName)
|
|
194
|
+
throw new Error(`${DELEGATE_TOOL_NAME} requires agent.`);
|
|
195
|
+
if (!stringValue(params.task))
|
|
196
|
+
throw new Error(`${DELEGATE_TOOL_NAME} requires a non-empty task.`);
|
|
197
|
+
const task = { ...params };
|
|
198
|
+
delete task.agent;
|
|
199
|
+
const timeline = await host.runSubagent(state.run().id, subagentName, task);
|
|
200
|
+
return harnessResult({
|
|
201
|
+
runId: timeline.run.id,
|
|
202
|
+
status: timeline.run.status,
|
|
203
|
+
events: timeline.events.map((event) => ({ type: event.type, data: event.data })).slice(-8)
|
|
204
|
+
}, host.env);
|
|
205
|
+
}
|
|
206
|
+
if (name === PAIR_TOOL_NAME) {
|
|
207
|
+
const outcome = await executePairTool(host, state.run(), state.connectionRegistry, params, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
208
|
+
state.setRun(outcome.run);
|
|
209
|
+
return harnessResult(outcome.modelOutput, host.env);
|
|
210
|
+
}
|
|
211
|
+
if (name === CONNECTION_SEARCH_TOOL_NAME) {
|
|
212
|
+
const outcome = await executeConnectionSearchTool(host, state.run(), state.connectionRegistry, params, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
213
|
+
state.setRun(outcome.run);
|
|
214
|
+
for (const result of outcome.results) {
|
|
215
|
+
if (result.qualifiedName && result.tool && result.inputSchema) {
|
|
216
|
+
const metadata = {
|
|
217
|
+
connection: result.connection,
|
|
218
|
+
name: result.tool,
|
|
219
|
+
qualifiedName: result.qualifiedName,
|
|
220
|
+
description: result.description,
|
|
221
|
+
inputSchema: result.inputSchema
|
|
222
|
+
};
|
|
223
|
+
if (result.outputSchema)
|
|
224
|
+
metadata.outputSchema = result.outputSchema;
|
|
225
|
+
state.discoveredConnectionTools.set(result.qualifiedName, metadata);
|
|
226
|
+
state.defaultToolNames.add(result.qualifiedName);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return harnessResult(outcome.results, host.env);
|
|
230
|
+
}
|
|
231
|
+
if (parseQualifiedName(name)) {
|
|
232
|
+
const outcome = await executeConnectionTool(host, state.run(), state.connectionRegistry, name, params, false, `tool:${state.run().id}:${name}:${toolCallId}`, "return");
|
|
233
|
+
state.setRun(outcome.run);
|
|
234
|
+
if (outcome.waitingForApproval || outcome.waitingForConnection) {
|
|
235
|
+
const waiting = { run: outcome.run };
|
|
236
|
+
if (outcome.waitingForApproval !== undefined)
|
|
237
|
+
waiting.waitingForApproval = outcome.waitingForApproval;
|
|
238
|
+
if (outcome.waitingForConnection !== undefined)
|
|
239
|
+
waiting.waitingForConnection = outcome.waitingForConnection;
|
|
240
|
+
waiting.toolCallId = toolCallId;
|
|
241
|
+
waiting.toolName = name;
|
|
242
|
+
if (outcome.authorizationSessionId)
|
|
243
|
+
waiting.authorizationSessionId = outcome.authorizationSessionId;
|
|
244
|
+
state.setPause(waiting);
|
|
245
|
+
return harnessPauseOutcome(waiting);
|
|
246
|
+
}
|
|
247
|
+
return harnessResult(outcome.modelOutput ?? {}, host.env);
|
|
248
|
+
}
|
|
249
|
+
const compiledTool = runtimeToolsForSurface(host.surfaceForRun(state.run()).tools).find((candidate) => candidate.name === name);
|
|
250
|
+
if (!compiledTool) {
|
|
251
|
+
await host.state.appendEvent(state.run().id, "tool.unavailable", { toolName: name });
|
|
252
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
253
|
+
}
|
|
254
|
+
const outcome = await executeToolImpl(host, state.run(), compiledTool, params, state.sandboxHandle, false, `tool:${state.run().id}:${compiledTool.name}:${toolCallId}`, call.signal);
|
|
132
255
|
state.setRun(outcome.run);
|
|
133
|
-
if (outcome.waitingForApproval || outcome.waitingForInput
|
|
256
|
+
if (outcome.waitingForApproval || outcome.waitingForInput) {
|
|
134
257
|
const waiting = { run: outcome.run };
|
|
135
258
|
if (outcome.waitingForApproval !== undefined)
|
|
136
259
|
waiting.waitingForApproval = outcome.waitingForApproval;
|
|
137
260
|
if (outcome.waitingForInput !== undefined)
|
|
138
261
|
waiting.waitingForInput = outcome.waitingForInput;
|
|
139
|
-
if (outcome.waitingForConnection !== undefined)
|
|
140
|
-
waiting.waitingForConnection = outcome.waitingForConnection;
|
|
141
262
|
if (outcome.toolCallId)
|
|
142
263
|
waiting.toolCallId = outcome.toolCallId;
|
|
143
264
|
if (outcome.toolName)
|
|
144
265
|
waiting.toolName = outcome.toolName;
|
|
145
|
-
if (outcome.authorizationSessionId)
|
|
146
|
-
waiting.authorizationSessionId = outcome.authorizationSessionId;
|
|
147
|
-
state.setPause(waiting);
|
|
148
|
-
return harnessPauseOutcome(waiting);
|
|
149
|
-
}
|
|
150
|
-
return harnessResult(outcome.modelOutput ?? {}, host.env);
|
|
151
|
-
}
|
|
152
|
-
if (name.startsWith("delegate_")) {
|
|
153
|
-
const subagentName = name.slice("delegate_".length);
|
|
154
|
-
const task = isJsonObject(params) ? params : { task: String(params ?? "") };
|
|
155
|
-
const timeline = await host.runSubagent(state.run().id, subagentName, task);
|
|
156
|
-
return harnessResult({
|
|
157
|
-
runId: timeline.run.id,
|
|
158
|
-
status: timeline.run.status,
|
|
159
|
-
events: timeline.events.map((event) => ({ type: event.type, data: event.data })).slice(-8)
|
|
160
|
-
}, host.env);
|
|
161
|
-
}
|
|
162
|
-
if (name === CONNECTION_SEARCH_TOOL_NAME) {
|
|
163
|
-
const outcome = await executeConnectionSearchTool(host, state.run(), state.connectionRegistry, params, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
164
|
-
state.setRun(outcome.run);
|
|
165
|
-
for (const result of outcome.results) {
|
|
166
|
-
if (result.qualifiedName && result.tool && result.inputSchema) {
|
|
167
|
-
const metadata = {
|
|
168
|
-
connection: result.connection,
|
|
169
|
-
name: result.tool,
|
|
170
|
-
qualifiedName: result.qualifiedName,
|
|
171
|
-
description: result.description,
|
|
172
|
-
inputSchema: result.inputSchema
|
|
173
|
-
};
|
|
174
|
-
if (result.outputSchema)
|
|
175
|
-
metadata.outputSchema = result.outputSchema;
|
|
176
|
-
state.discoveredConnectionTools.set(result.qualifiedName, metadata);
|
|
177
|
-
state.defaultToolNames.add(result.qualifiedName);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return harnessResult(outcome.results, host.env);
|
|
181
|
-
}
|
|
182
|
-
if (parseQualifiedName(name)) {
|
|
183
|
-
const outcome = await executeConnectionTool(host, state.run(), state.connectionRegistry, name, params, false, `tool:${state.run().id}:${name}:${toolCallId}`);
|
|
184
|
-
state.setRun(outcome.run);
|
|
185
|
-
if (outcome.waitingForApproval || outcome.waitingForConnection) {
|
|
186
|
-
const waiting = { run: outcome.run };
|
|
187
|
-
if (outcome.waitingForApproval !== undefined)
|
|
188
|
-
waiting.waitingForApproval = outcome.waitingForApproval;
|
|
189
|
-
if (outcome.waitingForConnection !== undefined)
|
|
190
|
-
waiting.waitingForConnection = outcome.waitingForConnection;
|
|
191
|
-
waiting.toolCallId = toolCallId;
|
|
192
|
-
waiting.toolName = name;
|
|
193
|
-
if (outcome.authorizationSessionId)
|
|
194
|
-
waiting.authorizationSessionId = outcome.authorizationSessionId;
|
|
195
266
|
state.setPause(waiting);
|
|
196
267
|
return harnessPauseOutcome(waiting);
|
|
197
268
|
}
|
|
198
269
|
return harnessResult(outcome.modelOutput ?? {}, host.env);
|
|
199
270
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (outcome.toolName)
|
|
216
|
-
waiting.toolName = outcome.toolName;
|
|
217
|
-
state.setPause(waiting);
|
|
218
|
-
return harnessPauseOutcome(waiting);
|
|
271
|
+
catch (error) {
|
|
272
|
+
// One shared model-tool boundary catches failures that occur before a
|
|
273
|
+
// specialized executor can normalize them (sandbox acquisition, deferred
|
|
274
|
+
// activation preflight, connection approval resolution, delegation, or
|
|
275
|
+
// future dispatch branches). State persistence failures still escape naturally:
|
|
276
|
+
// if we cannot durably record this failure, the run cannot safely continue.
|
|
277
|
+
const run = state.run();
|
|
278
|
+
const existing = (await host.state.listToolCalls(run.id))
|
|
279
|
+
.filter((candidate) => candidate.idempotencyKey === boundaryIdempotencyKey
|
|
280
|
+
|| candidate.idempotencyKey.startsWith(`${boundaryIdempotencyKey}:`))
|
|
281
|
+
.at(-1);
|
|
282
|
+
const toolCall = existing ?? await recordRuntimeHandledToolStart(host, run, name, params, boundaryIdempotencyKey);
|
|
283
|
+
const failure = await failRuntimeHandledTool(host, run, toolCall, toolCall.toolName, error, isConnectionConfigurationError(error) ? { failureKind: "configuration_error" } : undefined);
|
|
284
|
+
state.setRun(failure.run);
|
|
285
|
+
return harnessResult(failure.modelOutput, host.env);
|
|
219
286
|
}
|
|
220
|
-
return harnessResult(outcome.modelOutput ?? {}, host.env);
|
|
221
287
|
}
|
|
222
288
|
function harnessResult(output, env) {
|
|
223
289
|
const prepared = prepareToolModelOutput(output, env);
|
|
@@ -225,31 +291,14 @@ function harnessResult(output, env) {
|
|
|
225
291
|
return { kind: "result", output: prepared.output };
|
|
226
292
|
return { kind: "result", output: prepared.output, media: prepared.media };
|
|
227
293
|
}
|
|
228
|
-
async function executeToolCallBridge(host, run, state, input, idempotencyKey, approved = false) {
|
|
229
|
-
const raw = isJsonObject(input) ? input : {};
|
|
230
|
-
const name = stringValue(raw.name);
|
|
231
|
-
const args = isJsonObject(raw.arguments) ? raw.arguments : isJsonObject(raw.input) ? raw.input : {};
|
|
232
|
-
if (!name)
|
|
233
|
-
throw new Error("tool_call requires name.");
|
|
234
|
-
if (CORE_HARNESS_TOOL_NAMES.includes(name)) {
|
|
235
|
-
throw new Error(`Core harness tool ${name} is already directly visible; call it directly.`);
|
|
236
|
-
}
|
|
237
|
-
if (parseQualifiedName(name)) {
|
|
238
|
-
return executeConnectionTool(host, run, state.connectionRegistry, name, args, approved, `${idempotencyKey}:${name}`);
|
|
239
|
-
}
|
|
240
|
-
const compiledTool = deferredLocalTools(host).find((tool) => tool.name === name);
|
|
241
|
-
if (!compiledTool)
|
|
242
|
-
throw new Error(`Deferred tool not found: ${name}`);
|
|
243
|
-
const outcome = await executeToolImpl(host, run, compiledTool, args, state.sandboxHandle, approved, `${idempotencyKey}:${name}`);
|
|
244
|
-
return { ...outcome, toolName: compiledTool.name };
|
|
245
|
-
}
|
|
246
294
|
export function selectToolImpl(host, options) {
|
|
247
295
|
if (options.toolName) {
|
|
248
|
-
|
|
296
|
+
const surface = options.existingRun ? host.surfaceForRun(options.existingRun) : undefined;
|
|
297
|
+
return runtimeToolsForSurface((surface?.tools ?? host.manifest.tools)).find((tool) => tool.name === options.toolName);
|
|
249
298
|
}
|
|
250
299
|
return undefined;
|
|
251
300
|
}
|
|
252
|
-
export async function executeToolImpl(host, run, tool, input, sandboxHandle, approved, idempotencyKey = `tool:${run.id}:${tool.name}
|
|
301
|
+
export async function executeToolImpl(host, run, tool, input, sandboxHandle, approved, idempotencyKey = `tool:${run.id}:${tool.name}`, signal) {
|
|
253
302
|
const policyTool = applyCoreToolPolicy(tool, host.coreToolPolicy);
|
|
254
303
|
if (!policyTool) {
|
|
255
304
|
await host.state.appendEvent(run.id, "tool.call_requested", { toolName: tool.name, input: redactedToolInput(input) });
|
|
@@ -257,37 +306,30 @@ export async function executeToolImpl(host, run, tool, input, sandboxHandle, app
|
|
|
257
306
|
runId: run.id,
|
|
258
307
|
toolName: tool.name,
|
|
259
308
|
status: "requested",
|
|
260
|
-
input:
|
|
309
|
+
input: safeJson(input),
|
|
261
310
|
idempotencyKey
|
|
262
311
|
});
|
|
263
|
-
return failRuntimeHandledTool(host, run, toolCall, tool.name, `Core tool ${tool.name} is disabled by the
|
|
312
|
+
return failRuntimeHandledTool(host, run, toolCall, tool.name, `Core tool ${tool.name} is disabled by the Assembly Line core tool policy.`);
|
|
264
313
|
}
|
|
265
314
|
tool = policyTool;
|
|
266
315
|
if (tool.name === TOOL_SEARCH_TOOL_NAME) {
|
|
267
316
|
return executeToolSearchTool(host, run, {
|
|
268
317
|
connectionRegistry: createConnectionRegistryForRunImpl(host, run, "local"),
|
|
269
|
-
discoveredConnectionTools: new Map()
|
|
318
|
+
discoveredConnectionTools: new Map(),
|
|
319
|
+
activeToolNames: new Set()
|
|
270
320
|
}, input, idempotencyKey);
|
|
271
321
|
}
|
|
272
|
-
if (tool.name ===
|
|
273
|
-
return
|
|
274
|
-
connectionRegistry: createConnectionRegistryForRunImpl(host, run, "local"),
|
|
275
|
-
discoveredConnectionTools: new Map()
|
|
276
|
-
}, input, idempotencyKey);
|
|
277
|
-
}
|
|
278
|
-
if (tool.name === TOOL_CALL_TOOL_NAME) {
|
|
279
|
-
return executeToolCallBridge(host, run, {
|
|
280
|
-
sandboxHandle,
|
|
281
|
-
connectionRegistry: createConnectionRegistryForRunImpl(host, run, "local", sandboxHandle),
|
|
282
|
-
discoveredConnectionTools: new Map()
|
|
283
|
-
}, input, idempotencyKey, approved);
|
|
322
|
+
if (tool.name === HISTORY_SEARCH_TOOL_NAME) {
|
|
323
|
+
return executeHistorySearchTool(host, run, input, idempotencyKey);
|
|
284
324
|
}
|
|
285
325
|
await host.state.appendEvent(run.id, "tool.call_requested", { toolName: tool.name, input: redactedToolInput(input) });
|
|
286
326
|
let toolCall = await host.state.createToolCall({
|
|
287
327
|
runId: run.id,
|
|
288
328
|
toolName: tool.name,
|
|
289
329
|
status: "requested",
|
|
290
|
-
|
|
330
|
+
// Raw, not redacted: approval resume re-executes this persisted input.
|
|
331
|
+
// Redaction happens at outward read boundaries (redactedToolCallRecord).
|
|
332
|
+
input: safeJson(input),
|
|
291
333
|
idempotencyKey
|
|
292
334
|
});
|
|
293
335
|
const approval = normalizeApprovalPolicy(tool.needsApproval);
|
|
@@ -304,7 +346,7 @@ export async function executeToolImpl(host, run, tool, input, sandboxHandle, app
|
|
|
304
346
|
toolName: tool.name,
|
|
305
347
|
source: "eval"
|
|
306
348
|
});
|
|
307
|
-
return executeToolWithRecordImpl(host, run, tool, toolCall, input, sandboxHandle, true);
|
|
349
|
+
return executeToolWithRecordImpl(host, run, tool, toolCall, input, sandboxHandle, true, signal);
|
|
308
350
|
}
|
|
309
351
|
if (approval.mode === "always" && !approved) {
|
|
310
352
|
toolCall = await host.state.updateToolCall(toolCall.id, { status: "waiting_for_approval" });
|
|
@@ -321,22 +363,34 @@ export async function executeToolImpl(host, run, tool, input, sandboxHandle, app
|
|
|
321
363
|
});
|
|
322
364
|
return { run: waitingRun, waitingForApproval: true, toolCallId: toolCall.id, toolName: tool.name };
|
|
323
365
|
}
|
|
324
|
-
return executeToolWithRecordImpl(host, run, tool, toolCall, input, sandboxHandle, approved);
|
|
366
|
+
return executeToolWithRecordImpl(host, run, tool, toolCall, input, sandboxHandle, approved, signal);
|
|
325
367
|
}
|
|
326
|
-
export async function executeToolWithRecordImpl(host, run, tool, toolCall, input, sandboxHandle, approvedToolCall = false) {
|
|
368
|
+
export async function executeToolWithRecordImpl(host, run, tool, toolCall, input, sandboxHandle, approvedToolCall = false, signal) {
|
|
327
369
|
await host.state.updateToolCall(toolCall.id, { status: "running" });
|
|
328
370
|
await host.state.appendEvent(run.id, "tool.execution_started", { toolCallId: toolCall.id, toolName: tool.name });
|
|
329
371
|
const toolSpanStartedAt = timestamp();
|
|
330
|
-
if (toolRequiresSandbox(tool)) {
|
|
331
|
-
await sandboxHandle.get();
|
|
332
|
-
}
|
|
333
|
-
const ctx = createToolContext(host, run, sandboxHandle, approvedToolCall);
|
|
334
372
|
try {
|
|
335
|
-
const
|
|
336
|
-
|
|
373
|
+
const workspaceTool = WORKSPACE_TOOL_NAMES.has(tool.name);
|
|
374
|
+
const definition = workspaceTool ? undefined : await host.loadTool(tool, run);
|
|
375
|
+
if (!workspaceTool && !definition?.execute)
|
|
337
376
|
throw new Error(`Tool ${tool.name} does not export execute().`);
|
|
338
|
-
const
|
|
339
|
-
|
|
377
|
+
const executed = await withToolTimeout(async () => {
|
|
378
|
+
// Acquisition, provider reconnect, filesystem hydration, credential
|
|
379
|
+
// projection, authored execution, and output conversion share one
|
|
380
|
+
// deadline. A sandbox provider can no longer wedge the tool boundary
|
|
381
|
+
// before its timer starts.
|
|
382
|
+
if (toolRequiresSandbox(tool))
|
|
383
|
+
await sandboxHandle.get();
|
|
384
|
+
const ctx = createToolContext(host, run, sandboxHandle, approvedToolCall);
|
|
385
|
+
const result = workspaceTool
|
|
386
|
+
? await host.executeWorkspaceTool(run, tool.name, input, sandboxHandle)
|
|
387
|
+
: await Promise.resolve(definition.execute(input, ctx));
|
|
388
|
+
const modelOutput = definition?.toModelOutput
|
|
389
|
+
? await definition.toModelOutput(result)
|
|
390
|
+
: boundModelOutput(result, host.toolOutputMaxChars);
|
|
391
|
+
return { result, modelOutput };
|
|
392
|
+
}, definition?.timeoutMs ?? host.toolTimeoutMs, tool.name, signal);
|
|
393
|
+
const { result, modelOutput } = executed;
|
|
340
394
|
await host.state.updateToolCall(toolCall.id, {
|
|
341
395
|
status: "completed",
|
|
342
396
|
result: safeJson(result),
|
|
@@ -369,7 +423,57 @@ export async function executeToolWithRecordImpl(host, run, tool, toolCall, input
|
|
|
369
423
|
return { run: await host.state.getRun(run.id) ?? run, modelOutput };
|
|
370
424
|
}
|
|
371
425
|
catch (error) {
|
|
426
|
+
if (error instanceof ToolOperationInterruptedError && !sandboxHandle.current()) {
|
|
427
|
+
sandboxHandle.abandonAcquisition();
|
|
428
|
+
}
|
|
372
429
|
if (error instanceof HumanInputRequired) {
|
|
430
|
+
if (runUsesChannelReplyForHumanInput(run)) {
|
|
431
|
+
const message = "This run accepts human input through its active channel, not by pausing the run.";
|
|
432
|
+
const modelOutput = {
|
|
433
|
+
error: message,
|
|
434
|
+
question: error.question,
|
|
435
|
+
options: safeJson(error.options ?? {}),
|
|
436
|
+
action: "Ask the question as your final response. The user's next channel message will continue the conversation.",
|
|
437
|
+
failure: {
|
|
438
|
+
kind: "channel_reply_required",
|
|
439
|
+
runCanContinue: true
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
await host.state.updateToolCall(toolCall.id, {
|
|
443
|
+
status: "failed",
|
|
444
|
+
error: message,
|
|
445
|
+
modelOutput
|
|
446
|
+
});
|
|
447
|
+
await host.state.appendEvent(run.id, "tool.execution_failed", {
|
|
448
|
+
toolCallId: toolCall.id,
|
|
449
|
+
toolName: tool.name,
|
|
450
|
+
error: message,
|
|
451
|
+
failureKind: "channel_reply_required",
|
|
452
|
+
recoverable: true
|
|
453
|
+
});
|
|
454
|
+
await host.state.appendEvent(run.id, "human_input.redirected_to_channel", {
|
|
455
|
+
toolCallId: toolCall.id,
|
|
456
|
+
toolName: tool.name,
|
|
457
|
+
question: error.question,
|
|
458
|
+
options: error.options ?? {}
|
|
459
|
+
});
|
|
460
|
+
await host.emitSpan("ai.toolCall", toolSpanStartedAt, host.runSpanAttributes(run, {
|
|
461
|
+
toolCallId: toolCall.id,
|
|
462
|
+
toolName: tool.name,
|
|
463
|
+
status: "failed",
|
|
464
|
+
error: message,
|
|
465
|
+
...host.toolContentAttributes(input, modelOutput)
|
|
466
|
+
}), {
|
|
467
|
+
parentSpanId: host.turnSpanId(run.id),
|
|
468
|
+
status: "error"
|
|
469
|
+
});
|
|
470
|
+
await host.emitSpan("assembly-line.tool", toolSpanStartedAt, {
|
|
471
|
+
runId: run.id,
|
|
472
|
+
toolName: tool.name,
|
|
473
|
+
status: "failed"
|
|
474
|
+
});
|
|
475
|
+
return { run: await host.state.getRun(run.id) ?? run, modelOutput };
|
|
476
|
+
}
|
|
373
477
|
await host.state.updateToolCall(toolCall.id, { status: "waiting_for_approval", error: error.message });
|
|
374
478
|
const waitingRun = await host.state.updateRun(run.id, { status: "waiting_for_input" });
|
|
375
479
|
await host.state.appendEvent(run.id, "human_input.requested", {
|
|
@@ -393,27 +497,14 @@ export async function executeToolWithRecordImpl(host, run, tool, toolCall, input
|
|
|
393
497
|
});
|
|
394
498
|
return { run: waitingRun, waitingForInput: true, toolCallId: toolCall.id, toolName: tool.name };
|
|
395
499
|
}
|
|
396
|
-
//
|
|
397
|
-
//
|
|
398
|
-
//
|
|
399
|
-
//
|
|
400
|
-
//
|
|
401
|
-
// empty /workspace or a first-run state file that doesn't exist yet.
|
|
402
|
-
// Authored tools throwing is a stronger signal (the agent's own code
|
|
403
|
-
// broke) and remains a run failure, so routine/trigger failure detection
|
|
404
|
-
// is unchanged. Terminal conditions (human input, approval, connection
|
|
405
|
-
// auth) are explicit cases above and never reach here.
|
|
500
|
+
// Every durably recordable model-invoked tool failure is returned to the
|
|
501
|
+
// model. RecoverableToolError classifies correctable input, but ordinary
|
|
502
|
+
// tool and infrastructure errors are also visible so the model can choose
|
|
503
|
+
// another action or explain the failure. State persistence failures still
|
|
504
|
+
// escape because continuing without a durable record is unsafe.
|
|
406
505
|
const message = error instanceof Error ? error.message : String(error);
|
|
407
|
-
await host
|
|
408
|
-
|
|
409
|
-
const recoverable = isBuiltInToolName(tool.name);
|
|
410
|
-
const nextRun = recoverable
|
|
411
|
-
? await host.state.getRun(run.id) ?? run
|
|
412
|
-
: await failRun({ state: host.state }, run.id, {
|
|
413
|
-
reason: "tool.execution_failed",
|
|
414
|
-
error: message,
|
|
415
|
-
data: { toolCallId: toolCall.id, toolName: tool.name }
|
|
416
|
-
});
|
|
506
|
+
const failure = await failRuntimeHandledTool(host, run, toolCall, tool.name, error);
|
|
507
|
+
const nextRun = failure.run;
|
|
417
508
|
await host.emitSpan("ai.toolCall", toolSpanStartedAt, host.runSpanAttributes(nextRun, {
|
|
418
509
|
toolCallId: toolCall.id,
|
|
419
510
|
toolName: tool.name,
|
|
@@ -429,44 +520,66 @@ export async function executeToolWithRecordImpl(host, run, tool, toolCall, input
|
|
|
429
520
|
toolName: tool.name,
|
|
430
521
|
status: "failed"
|
|
431
522
|
});
|
|
432
|
-
return { run: nextRun, modelOutput:
|
|
523
|
+
return { run: nextRun, modelOutput: failure.modelOutput };
|
|
433
524
|
}
|
|
434
525
|
}
|
|
526
|
+
const WORKSPACE_TOOL_NAMES = new Set([
|
|
527
|
+
FILES_SEARCH_TOOL_NAME,
|
|
528
|
+
FILES_MOUNT_TOOL_NAME,
|
|
529
|
+
WORKSPACE_SEARCH_TOOL_NAME,
|
|
530
|
+
WORKSPACE_STATUS_TOOL_NAME,
|
|
531
|
+
WORKSPACE_CHECKPOINT_CREATE_TOOL_NAME,
|
|
532
|
+
WORKSPACE_CHECKPOINT_LIST_TOOL_NAME,
|
|
533
|
+
WORKSPACE_CHECKPOINT_RESTORE_TOOL_NAME,
|
|
534
|
+
WORKSPACE_FORK_TOOL_NAME
|
|
535
|
+
]);
|
|
435
536
|
const DEFAULT_SHELL_TIMEOUT_MS = 30_000;
|
|
436
537
|
const DEFAULT_SHELL_TIMEOUT_MAX_MS = 600_000;
|
|
437
|
-
/** Clamp a (possibly model-supplied) shell timeout to [1s,
|
|
538
|
+
/** Clamp a (possibly model-supplied) shell timeout to [1s, ASSEMBLY_LINE_BASH_TIMEOUT_MAX_MS]; 0/negative/NaN fall to the default. */
|
|
438
539
|
export function clampShellTimeoutMs(requested, env) {
|
|
439
|
-
const max = resolvePositiveIntegerEnv(env.
|
|
540
|
+
const max = resolvePositiveIntegerEnv(env.ASSEMBLY_LINE_BASH_TIMEOUT_MAX_MS, DEFAULT_SHELL_TIMEOUT_MAX_MS);
|
|
440
541
|
if (typeof requested !== "number" || !Number.isFinite(requested) || requested <= 0) {
|
|
441
542
|
return Math.min(DEFAULT_SHELL_TIMEOUT_MS, max);
|
|
442
543
|
}
|
|
443
544
|
return Math.min(Math.max(Math.floor(requested), 1_000), max);
|
|
444
545
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
546
|
+
class ToolOperationInterruptedError extends Error {
|
|
547
|
+
}
|
|
548
|
+
/** Bound the complete runtime tool boundary and release its caller on cancel. */
|
|
549
|
+
function withToolTimeout(operation, timeoutMs, toolName, signal) {
|
|
550
|
+
if (signal?.aborted) {
|
|
551
|
+
return Promise.reject(new ToolOperationInterruptedError(`Tool ${toolName} was cancelled.`));
|
|
552
|
+
}
|
|
553
|
+
const pending = Promise.resolve().then(operation);
|
|
554
|
+
if (timeoutMs <= 0 && !signal)
|
|
555
|
+
return pending;
|
|
453
556
|
return new Promise((resolve, reject) => {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
557
|
+
let settled = false;
|
|
558
|
+
const finish = (callback) => {
|
|
559
|
+
if (settled)
|
|
560
|
+
return;
|
|
561
|
+
settled = true;
|
|
562
|
+
if (timer)
|
|
563
|
+
clearTimeout(timer);
|
|
564
|
+
signal?.removeEventListener("abort", onAbort);
|
|
565
|
+
callback();
|
|
566
|
+
};
|
|
567
|
+
const onAbort = () => finish(() => {
|
|
568
|
+
reject(new ToolOperationInterruptedError(`Tool ${toolName} was cancelled.`));
|
|
569
|
+
});
|
|
570
|
+
const timer = timeoutMs > 0 ? setTimeout(() => finish(() => {
|
|
571
|
+
reject(new ToolOperationInterruptedError(`Tool ${toolName} timed out after ${timeoutMs}ms.`));
|
|
572
|
+
}), timeoutMs) : undefined;
|
|
573
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
574
|
+
pending.then((value) => {
|
|
575
|
+
finish(() => resolve(value));
|
|
462
576
|
}, (error) => {
|
|
463
|
-
|
|
464
|
-
reject(error instanceof Error ? error : new Error(String(error)));
|
|
577
|
+
finish(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
465
578
|
});
|
|
466
579
|
});
|
|
467
580
|
}
|
|
468
581
|
export function wrapSandboxImpl(host, runId, session) {
|
|
469
|
-
|
|
582
|
+
const wrapped = {
|
|
470
583
|
...session,
|
|
471
584
|
readFile: async (path) => {
|
|
472
585
|
const contents = await session.readFile(path);
|
|
@@ -506,6 +619,14 @@ export function wrapSandboxImpl(host, runId, session) {
|
|
|
506
619
|
return result;
|
|
507
620
|
}
|
|
508
621
|
};
|
|
622
|
+
if (session.readFileBytes) {
|
|
623
|
+
wrapped.readFileBytes = async (path) => {
|
|
624
|
+
const contents = await session.readFileBytes(path);
|
|
625
|
+
await host.state.appendEvent(runId, "sandbox.file_read", { path, bytes: contents.byteLength });
|
|
626
|
+
return contents;
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
return wrapped;
|
|
509
630
|
}
|
|
510
631
|
async function ensureSandboxSyncObligation(host, runId, session, reason, metadata = {}) {
|
|
511
632
|
const run = await host.state.getRun(runId);
|
|
@@ -513,6 +634,31 @@ async function ensureSandboxSyncObligation(host, runId, session, reason, metadat
|
|
|
513
634
|
throw new Error(`Run not found for sandbox sync obligation: ${runId}`);
|
|
514
635
|
const sessionKey = host.sandboxSessionKey(run);
|
|
515
636
|
const existing = await host.state.getSandboxSession(sessionKey);
|
|
637
|
+
const workspaceId = stringValue(existing?.manifest.workspaceId)?.trim();
|
|
638
|
+
const baseVersionId = existing?.manifest.baseVersionId;
|
|
639
|
+
const hasBaseVersionId = baseVersionId === null || typeof baseVersionId === "string";
|
|
640
|
+
if (!workspaceId || !hasBaseVersionId) {
|
|
641
|
+
const missing = [
|
|
642
|
+
...(!workspaceId ? ["workspaceId"] : []),
|
|
643
|
+
...(!hasBaseVersionId ? ["baseVersionId"] : [])
|
|
644
|
+
];
|
|
645
|
+
const error = `Sandbox is not fully hydrated; refusing ${reason} before creating an invalid sync obligation (missing ${missing.join(", ")}).`;
|
|
646
|
+
await host.state.appendEvent(runId, "sandbox.sync_obligation_rejected", {
|
|
647
|
+
sandboxId: session.id,
|
|
648
|
+
sessionKey,
|
|
649
|
+
reason,
|
|
650
|
+
missing,
|
|
651
|
+
metadata
|
|
652
|
+
});
|
|
653
|
+
throw new Error(error);
|
|
654
|
+
}
|
|
655
|
+
const sessionManifest = {
|
|
656
|
+
...existing?.manifest,
|
|
657
|
+
roots: ["/memory", "/skills", "/workspace"],
|
|
658
|
+
sandboxRoot: session.root,
|
|
659
|
+
...sandboxFilesystemContractMetadata(session.provider === "local" ? "emulated" : "physical")
|
|
660
|
+
};
|
|
661
|
+
const syncManifest = { ...sessionManifest, sessionRecordKey: sessionKey };
|
|
516
662
|
const syncJob = await host.state.enqueueSandboxSyncJob({
|
|
517
663
|
runId,
|
|
518
664
|
sandboxId: session.id,
|
|
@@ -520,13 +666,7 @@ async function ensureSandboxSyncObligation(host, runId, session, reason, metadat
|
|
|
520
666
|
idempotencyKey: `sandbox-sync:${runId}:${session.id}`,
|
|
521
667
|
reason,
|
|
522
668
|
maxAttempts: host.sandboxSyncMaxAttempts,
|
|
523
|
-
manifest:
|
|
524
|
-
...(existing?.manifest ?? {}),
|
|
525
|
-
roots: ["/memory", "/skills", "/workspace"],
|
|
526
|
-
sandboxRoot: session.root,
|
|
527
|
-
sessionKey,
|
|
528
|
-
...sandboxFilesystemContractMetadata(session.provider === "local" ? "emulated" : "physical")
|
|
529
|
-
},
|
|
669
|
+
manifest: syncManifest,
|
|
530
670
|
metadata
|
|
531
671
|
});
|
|
532
672
|
await host.state.updateSandboxSession(sessionKey, {
|
|
@@ -536,13 +676,7 @@ async function ensureSandboxSyncObligation(host, runId, session, reason, metadat
|
|
|
536
676
|
dirty: true,
|
|
537
677
|
lastSeenAt: timestamp(),
|
|
538
678
|
syncJobId: syncJob.id,
|
|
539
|
-
manifest:
|
|
540
|
-
...(existing?.manifest ?? {}),
|
|
541
|
-
roots: ["/memory", "/skills", "/workspace"],
|
|
542
|
-
sandboxRoot: session.root,
|
|
543
|
-
sessionKey,
|
|
544
|
-
...sandboxFilesystemContractMetadata(session.provider === "local" ? "emulated" : "physical")
|
|
545
|
-
}
|
|
679
|
+
manifest: sessionManifest
|
|
546
680
|
}).catch(async () => {
|
|
547
681
|
await host.state.upsertSandboxSession({
|
|
548
682
|
sessionKey,
|
|
@@ -553,12 +687,7 @@ async function ensureSandboxSyncObligation(host, runId, session, reason, metadat
|
|
|
553
687
|
dirty: true,
|
|
554
688
|
lastSeenAt: timestamp(),
|
|
555
689
|
syncJobId: syncJob.id,
|
|
556
|
-
manifest:
|
|
557
|
-
roots: ["/memory", "/skills", "/workspace"],
|
|
558
|
-
sandboxRoot: session.root,
|
|
559
|
-
sessionKey,
|
|
560
|
-
...sandboxFilesystemContractMetadata(session.provider === "local" ? "emulated" : "physical")
|
|
561
|
-
}
|
|
690
|
+
manifest: sessionManifest
|
|
562
691
|
});
|
|
563
692
|
});
|
|
564
693
|
await host.state.appendEvent(runId, "sandbox.sync_obligation", {
|