@sema-agent/core 7.55.0 → 7.56.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/CHANGELOG.md +513 -0
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.js +1 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +7 -7
- package/dist/agents/peer-directory.d.ts +22 -4
- package/dist/agents/peer-directory.js +24 -2
- package/dist/agents/peer-session-drain.js +2 -2
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/send-message-tool.js +4 -4
- package/dist/agents/subagent.d.ts +6 -4
- package/dist/agents/subagent.js +64 -60
- package/dist/agents/tool-filter.d.ts +7 -5
- package/dist/agents/tool-filter.js +12 -9
- package/dist/agents/verify.d.ts +3 -2
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +30 -73
- package/dist/brain/media-degrade.d.ts +18 -7
- package/dist/brain/media-degrade.js +13 -2
- package/dist/brain/model-capability.d.ts +37 -0
- package/dist/brain/model-capability.js +34 -0
- package/dist/brain/model-presets.d.ts +2 -8
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +13 -26
- package/dist/brain/openai.js +14 -87
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +11 -11
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +7 -4
- package/dist/brain/request-params.js +7 -4
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/agent-definition.d.ts +10 -0
- package/dist/core/allow-entry.d.ts +20 -13
- package/dist/core/allow-entry.js +26 -22
- package/dist/core/allow-rule-shadow.d.ts +3 -3
- package/dist/core/ask-origin.d.ts +64 -18
- package/dist/core/ask-origin.js +63 -23
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +3 -4
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +13 -1
- package/dist/core/checkpoint-requirements.js +4 -0
- package/dist/core/checkpoint-store.d.ts +88 -24
- package/dist/core/checkpoint-store.js +24 -9
- package/dist/core/cross-boundary-taint.d.ts +6 -5
- package/dist/core/cross-boundary-taint.js +1 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +17 -17
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/engine-attestation.d.ts +93 -0
- package/dist/core/engine-attestation.js +70 -0
- package/dist/core/engine-capabilities.d.ts +4 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +30 -11
- package/dist/core/file-history-store.d.ts +90 -14
- package/dist/core/file-history-store.js +23 -15
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +22 -10
- package/dist/core/gate-lanes.js +73 -64
- package/dist/core/gate-outcome.d.ts +26 -5
- package/dist/core/gate-outcome.js +26 -0
- package/dist/core/governance-codes.d.ts +5 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/hooks.d.ts +17 -16
- package/dist/core/hooks.js +3 -1
- package/dist/core/host-floor.d.ts +128 -0
- package/dist/core/host-floor.js +206 -0
- package/dist/core/host-target.d.ts +38 -3
- package/dist/core/host-target.js +38 -5
- package/dist/core/mcp.d.ts +5 -1
- package/dist/core/mcp.js +67 -41
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/engine.js +4 -4
- package/dist/core/memory-engine/layout.d.ts +60 -8
- package/dist/core/memory-engine/layout.js +65 -6
- package/dist/core/model-seat.d.ts +10 -3
- package/dist/core/mods/classic-events.d.ts +67 -0
- package/dist/core/mods/classic-events.js +1 -0
- package/dist/core/mods/dollar.d.ts +13 -0
- package/dist/core/mods/extension-call.d.ts +31 -0
- package/dist/core/mods/extension-call.js +43 -0
- package/dist/core/mods/kernel/dispatch.d.ts +20 -3
- package/dist/core/mods/kernel/dispatch.js +140 -69
- package/dist/core/mods/kernel/events.d.ts +47 -11
- package/dist/core/mods/kernel/events.js +66 -42
- package/dist/core/mods/kernel/index.d.ts +4 -4
- package/dist/core/mods/kernel/index.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -5
- package/dist/core/mods/kernel/receive.js +290 -17
- package/dist/core/mods/kernel/registration.d.ts +33 -2
- package/dist/core/mods/kernel/registration.js +6 -7
- package/dist/core/mods/kernel/site-rules.d.ts +44 -16
- package/dist/core/mods/kernel/site-rules.js +24 -42
- package/dist/core/mods/spec-seats.d.ts +69 -0
- package/dist/core/mods/spec-seats.js +114 -0
- package/dist/core/mods/stations.d.ts +28 -8
- package/dist/core/mods/stations.js +29 -13
- package/dist/core/mods/tool-call.d.ts +79 -0
- package/dist/core/mods/tool-call.js +152 -0
- package/dist/core/namespaced-rule-name.d.ts +32 -38
- package/dist/core/namespaced-rule-name.js +29 -36
- package/dist/core/parent-spec-seat.d.ts +6 -1
- package/dist/core/parent-spec-seat.js +2 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +19 -0
- package/dist/core/permission-rule-consent.js +116 -26
- package/dist/core/permission-rule-model.d.ts +14 -3
- package/dist/core/permission-rule-model.js +39 -24
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +7 -3
- package/dist/core/permission-rule-provider.d.ts +5 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +3 -2
- package/dist/core/permission-rule-store.js +11 -2
- package/dist/core/permission-rule-sync.js +3 -2
- package/dist/core/permission-rule-syntax.d.ts +5 -4
- package/dist/core/permission-rule-syntax.js +2 -2
- package/dist/core/permission-rules.d.ts +4 -4
- package/dist/core/permission-rules.js +11 -20
- package/dist/core/persisted-rule-arms.d.ts +2 -2
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/principal-name.d.ts +20 -0
- package/dist/core/principal-name.js +22 -0
- package/dist/core/prompt-section-seat.js +4 -6
- package/dist/core/protocol-http-auth.d.ts +26 -5
- package/dist/core/protocol-http-auth.js +137 -4
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +28 -1
- package/dist/core/roles.js +31 -19
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-owner.d.ts +3 -3
- package/dist/core/rule-owner.js +3 -2
- package/dist/core/runner/announce-once-ledger.d.ts +14 -0
- package/dist/core/runner/announce-once-ledger.js +5 -0
- package/dist/core/runner/assemble-result.d.ts +1 -0
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/call-hook-stations.d.ts +3 -2
- package/dist/core/runner/caller-roster.d.ts +16 -4
- package/dist/core/runner/caller-roster.js +33 -6
- package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
- package/dist/core/runner/capability-withheld-seat.js +24 -0
- package/dist/core/runner/classifier-ladder.d.ts +7 -9
- package/dist/core/runner/classifier-ladder.js +3 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +28 -25
- package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
- package/dist/core/runner/cross-boundary-lane.js +40 -27
- package/dist/core/runner/denial-limit-arms.d.ts +2 -2
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/file-history-request.d.ts +18 -0
- package/dist/core/runner/file-history-request.js +21 -13
- package/dist/core/runner/file-history-restore.d.ts +45 -0
- package/dist/core/runner/file-history-restore.js +46 -0
- package/dist/core/runner/gate-exit.d.ts +3 -3
- package/dist/core/runner/gate-exit.js +4 -3
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
- package/dist/core/runner/permission-rule-lanes.js +26 -10
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +18 -7
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
- package/dist/core/runner/prepare-ask-lane.js +5 -2
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
- package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
- package/dist/core/runner/prepare-config-doors.d.ts +29 -38
- package/dist/core/runner/prepare-config-doors.js +42 -25
- package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
- package/dist/core/runner/prepare-defer-classify.js +7 -8
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +7 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
- package/dist/core/runner/prepare-gate-stations.js +10 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
- package/dist/core/runner/prepare-hands-readface.js +15 -14
- package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
- package/dist/core/runner/prepare-inherited-gate.js +5 -3
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +5 -5
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
- package/dist/core/runner/prepare-policy-chain.js +65 -72
- package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
- package/dist/core/runner/prepare-prompt-assembly.js +10 -8
- package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
- package/dist/core/runner/prepare-prompt-inputs.js +3 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
- package/dist/core/runner/prepare-protocol-tools.js +3 -3
- package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
- package/dist/core/runner/prepare-safety-scan.js +0 -17
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -6
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +29 -20
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
- package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -7
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
- package/dist/core/runner/prepare-wiring-manifest.js +3 -3
- package/dist/core/runner/resume-admission.js +1 -1
- package/dist/core/runner/resume-apply.js +11 -12
- package/dist/core/runner/resume-checkpoint-screen.js +3 -0
- package/dist/core/runner/resume-claim.d.ts +4 -2
- package/dist/core/runner/resume-claim.js +15 -8
- package/dist/core/runner/retired-runner-deps.js +1 -0
- package/dist/core/runner/rewind-files.d.ts +15 -0
- package/dist/core/runner/rewind-files.js +132 -0
- package/dist/core/runner/run-attachment-seats.js +2 -1
- package/dist/core/runner/run-brain-sinks.d.ts +4 -1
- package/dist/core/runner/run-brain-sinks.js +4 -2
- package/dist/core/runner/run-harness-handlers.js +12 -4
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +30 -18
- package/dist/core/runner/run-settle-and-teardown.js +2 -1
- package/dist/core/runner/run-turn-boundary.js +1 -10
- package/dist/core/runner/runtask.d.ts +3 -0
- package/dist/core/runner/runtask.js +8 -9
- package/dist/core/runner/session-read-file-states.d.ts +15 -0
- package/dist/core/runner/session-read-file-states.js +28 -0
- package/dist/core/runner/session-rule-policy.js +4 -3
- package/dist/core/runner/shell-env-withheld.d.ts +33 -0
- package/dist/core/runner/shell-env-withheld.js +51 -0
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -7
- package/dist/core/runner/synthetic-tools.d.ts +6 -0
- package/dist/core/runner/synthetic-tools.js +4 -1
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +1 -3
- package/dist/core/runner/tool-end-body.d.ts +1 -1
- package/dist/core/runner/tool-end-body.js +10 -9
- package/dist/core/runner/tool-not-executed.d.ts +5 -0
- package/dist/core/runner/tool-not-executed.js +11 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -0
- package/dist/core/runner/tool-occurrence.js +7 -0
- package/dist/core/runner/turn-attachments.d.ts +33 -15
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +5 -5
- package/dist/core/safety-axis-vocab.d.ts +6 -4
- package/dist/core/safety-axis-vocab.js +6 -5
- package/dist/core/safety-merge-corpus.js +11 -3
- package/dist/core/secret-env.d.ts +26 -3
- package/dist/core/secret-env.js +44 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/session-policy-store.d.ts +27 -15
- package/dist/core/session-policy-store.js +156 -36
- package/dist/core/session-store.d.ts +29 -10
- package/dist/core/session-store.js +51 -19
- package/dist/core/session.d.ts +82 -16
- package/dist/core/session.js +53 -0
- package/dist/core/shell-read-silence.d.ts +11 -12
- package/dist/core/shell-read-silence.js +9 -5
- package/dist/core/shell-run-candidates.js +3 -1
- package/dist/core/shell-wrapper-projection.js +1 -1
- package/dist/core/shell-wrapper-table.d.ts +14 -7
- package/dist/core/shell-wrapper-table.js +5 -4
- package/dist/core/side-query.js +10 -1
- package/dist/core/skill-grant.d.ts +7 -2
- package/dist/core/skill-grant.js +5 -0
- package/dist/core/skills-directory.js +6 -2
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
- package/dist/core/store-contracts/file-history-store-contract.js +31 -1
- package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
- package/dist/core/store-contracts/peer-directory-contract.js +14 -2
- package/dist/core/store-contracts/session-repo-contract.js +51 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
- package/dist/core/store-contracts/session-store-contract.js +150 -14
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +32 -4
- package/dist/core/task-notification.d.ts +16 -12
- package/dist/core/task-registry.d.ts +9 -0
- package/dist/core/task-registry.js +11 -1
- package/dist/core/task-result.d.ts +18 -0
- package/dist/core/task-spec.d.ts +18 -13
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +17 -0
- package/dist/core/tool-catalog-entries.js +13 -2
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-model-gate.d.ts +2 -2
- package/dist/core/tool-name-aliases.d.ts +16 -16
- package/dist/core/tool-name-aliases.js +13 -19
- package/dist/core/tool-name-readings.d.ts +5 -35
- package/dist/core/tool-name-readings.js +1 -9
- package/dist/core/tool-policy.d.ts +68 -198
- package/dist/core/tool-policy.js +149 -198
- package/dist/core/tool-result-store.js +3 -0
- package/dist/core/tool-roster.d.ts +14 -19
- package/dist/core/tool-roster.js +11 -44
- package/dist/core/tool-spec-members.js +7 -2
- package/dist/core/tool-spec.d.ts +19 -11
- package/dist/core/tools.js +49 -9
- package/dist/core/trace.d.ts +2 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/wiring-manifest.d.ts +9 -0
- package/dist/core/wiring-manifest.js +1 -0
- package/dist/core/workflow-journal-store.js +1 -1
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
- package/dist/engine/execution-env/node-execution-env.js +11 -2
- package/dist/engine/harness/agent-harness.d.ts +25 -1
- package/dist/engine/harness/agent-harness.js +54 -7
- package/dist/engine/harness/types.d.ts +29 -2
- package/dist/engine/llm/types.d.ts +28 -11
- package/dist/engine/loop/agent-loop.d.ts +22 -0
- package/dist/engine/loop/agent-loop.js +16 -26
- package/dist/engine/loop/types.d.ts +16 -6
- package/dist/engine/session/memory-repo.d.ts +9 -2
- package/dist/engine/session/memory-repo.js +11 -1
- package/dist/engine/session/repo-utils.d.ts +6 -5
- package/dist/engine/session/repo-utils.js +14 -6
- package/dist/index.d.ts +22 -10
- package/dist/index.js +15 -7
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/llm.d.ts +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +6 -4
- package/dist/orchestration/run-workflow-tool.js +5 -3
- package/dist/orchestration/workflow.d.ts +3 -0
- package/dist/orchestration/workflow.js +36 -18
- package/dist/prompt-assembly/artifact.d.ts +2 -2
- package/dist/prompt-assembly/artifact.js +5 -3
- package/dist/prompt-assembly/assemble.d.ts +3 -2
- package/dist/prompt-assembly/assemble.js +1 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
- package/dist/prompt-assembly/catalog/schema.js +34 -2
- package/dist/prompt-assembly/catalog/sections.js +0 -1
- package/dist/prompt-assembly/composer.d.ts +3 -1
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/overlay.js +3 -3
- package/dist/prompt-assembly/renderers.d.ts +1 -1
- package/dist/prompt-assembly/renderers.js +0 -3
- package/dist/prompt-assembly/role-base.d.ts +15 -0
- package/dist/prompt-assembly/role-base.js +9 -0
- package/dist/prompt-assembly/select.d.ts +39 -14
- package/dist/prompt-assembly/select.js +47 -16
- package/dist/prompt-assembly/sugar.d.ts +17 -11
- package/dist/prompt-assembly/sugar.js +8 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
- package/dist/prompt-assembly/tool-catalog.js +114 -4
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
- package/dist/prompt-assembly/turn-snapshot.js +0 -3
- package/dist/prompt-assembly/types.d.ts +0 -7
- package/dist/scenarios/full-body.d.ts +11 -11
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.js +4 -3
- package/dist/stores/file/adoption/marker.js +3 -2
- package/dist/stores/file/checkpoint-store.d.ts +21 -0
- package/dist/stores/file/checkpoint-store.js +38 -6
- package/dist/stores/file/file-history-store.js +6 -7
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/permission-rule-adopt.js +4 -3
- package/dist/stores/file/permission-rule-store.js +11 -5
- package/dist/stores/file/session-store.d.ts +29 -6
- package/dist/stores/file/session-store.js +42 -50
- package/dist/tools/artifact/artifact-tool.js +3 -2
- package/dist/tools/fs/bash-program-position.d.ts +19 -2
- package/dist/tools/fs/bash-program-position.js +56 -9
- package/dist/tools/fs/fs-bash.js +5 -5
- package/dist/tools/fs/fs-glob.d.ts +86 -0
- package/dist/tools/fs/fs-glob.js +226 -0
- package/dist/tools/fs/fs-read.js +14 -14
- package/dist/tools/fs/fs-search-tools.js +7 -7
- package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
- package/dist/tools/fs/pattern-kill-guard.js +397 -0
- package/dist/tools/fs/pdf.d.ts +9 -6
- package/dist/tools/fs/pdf.js +3 -3
- package/dist/tools/fs/program-read-model.d.ts +57 -7
- package/dist/tools/fs/program-read-model.js +11 -1
- package/dist/tools/fs/program-read-model.rows.js +78 -21
- package/dist/tools/fs/read-deny-home.js +3 -2
- package/dist/tools/fs/removal-targets.d.ts +17 -7
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/search.d.ts +10 -0
- package/dist/tools/fs/search.js +20 -26
- package/dist/tools/fs/shell-read-argv.js +89 -12
- package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
- package/dist/tools/fs/shell-read-bindings.js +41 -0
- package/dist/tools/fs/shell-read-check.js +6 -19
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-plan.js +24 -16
- package/dist/tools/fs/shell-read-start.d.ts +6 -1
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
- package/dist/tools/fs/shell-read-write-targets.js +2 -3
- package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
- package/dist/tools/fs/shell-reentry-text.js +40 -2
- package/dist/tools/todo.js +63 -63
- package/dist/tools/web.d.ts +19 -14
- package/dist/tools/web.js +38 -55
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +143 -5
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
|
@@ -255,12 +255,10 @@ export function createTurnBoundary(input) {
|
|
|
255
255
|
const pendingTools = tdRef !== undefined && tdRef.pending.length > 0 ? [...tdRef.pending] : undefined;
|
|
256
256
|
const pendingRemovedTools = tdRef !== undefined && tdRef.pendingRemoved.length > 0 ? [...tdRef.pendingRemoved] : undefined;
|
|
257
257
|
const pendingReaddedTools = tdRef !== undefined && tdRef.pendingReadded.length > 0 ? [...tdRef.pendingReadded] : undefined;
|
|
258
|
-
const
|
|
259
|
-
const mcpToolsDelta = pendingRemovedTools !== undefined || pendingReaddedTools !== undefined || pendingFailedMcp !== undefined
|
|
258
|
+
const mcpToolsDelta = pendingRemovedTools !== undefined || pendingReaddedTools !== undefined
|
|
260
259
|
? {
|
|
261
260
|
...(pendingRemovedTools !== undefined ? { removed: pendingRemovedTools } : {}),
|
|
262
261
|
...(pendingReaddedTools !== undefined ? { readded: pendingReaddedTools } : {}),
|
|
263
|
-
...(pendingFailedMcp !== undefined ? { failedServers: pendingFailedMcp } : {}),
|
|
264
262
|
}
|
|
265
263
|
: undefined;
|
|
266
264
|
const mcpInstructionsOn = rs.attach.attachmentsCfg?.mcpInstructions === true;
|
|
@@ -359,13 +357,6 @@ export function createTurnBoundary(input) {
|
|
|
359
357
|
ref.pendingRemoved.splice(0, pendingRemovedTools.length);
|
|
360
358
|
if (pendingReaddedTools !== undefined)
|
|
361
359
|
ref.pendingReadded.splice(0, pendingReaddedTools.length);
|
|
362
|
-
if (pendingFailedMcp !== undefined) {
|
|
363
|
-
ref.pendingFailed.splice(0, pendingFailedMcp.length);
|
|
364
|
-
if (!noNextRequest()) {
|
|
365
|
-
prepared.announcedListingsRef.mcpFailed = [...(prepared.announcedListingsRef.mcpFailed ?? []), ...pendingFailedMcp];
|
|
366
|
-
announcedOnceDirty = true;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
360
|
}
|
|
370
361
|
}
|
|
371
362
|
if ((mcpAdds !== undefined || mcpRemovals !== undefined) &&
|
|
@@ -8,6 +8,7 @@ import type { AgentDefinition, ModelRef, ModelRoles, RunnerDeps, TaskEvent, Task
|
|
|
8
8
|
import { type ContextSettings, type ContextWindowOverlay } from "../context-settings.js";
|
|
9
9
|
import type { ResumeRun, ResumeTaskConfig, RunInternals, RunnerSelfSeat } from "./contracts.js";
|
|
10
10
|
export type { ResumeTaskConfig } from "./contracts.js";
|
|
11
|
+
import type { RewindFilesRequest, RewindFilesResult } from "../file-history-store.js";
|
|
11
12
|
/**
|
|
12
13
|
* A stateless task runner. Holds shared deps (the external brain, model catalog) and an
|
|
13
14
|
* in-memory session store so that passing a `sessionId` continues a prior conversation.
|
|
@@ -133,6 +134,8 @@ export declare class Runner implements RunnerSelfSeat {
|
|
|
133
134
|
* the same model resolution as tasks, returns real usage/model. No session, no tool execution, no
|
|
134
135
|
* policy gate, no accounting — caller-trusted. */
|
|
135
136
|
sideQuery(spec: SideQuerySpec): Promise<SideQueryResult>;
|
|
137
|
+
/** The out-of-run code-only rewind, no model call and no session entry — the contract is {@link rewindSessionFiles}'s (refused while a leg of this Runner holds or awaits the session's lock). */
|
|
138
|
+
rewindFiles(request: RewindFilesRequest): Promise<RewindFilesResult>;
|
|
136
139
|
/** Run a task and stream live events; await `.result()` for the final TaskResult. `resume` (internal)
|
|
137
140
|
* drives a durable resume through the same loop instead of a fresh objective prompt.
|
|
138
141
|
* `internals` (internal) is a TRUSTED run-scoped channel for live per-task state the
|
|
@@ -7,7 +7,7 @@ import { createRapidRefillState } from "../auto-compaction.js";
|
|
|
7
7
|
import { boundInputHashOf } from "../canonical-json.js";
|
|
8
8
|
import { emitTrace } from "../trace.js";
|
|
9
9
|
import { emitTaskOutcome } from "../task-outcome.js";
|
|
10
|
-
import { runWithReasoningWireFacts } from "../../brain/status-sink.js";
|
|
10
|
+
import { runWithCapabilityWithheld, runWithReasoningWireFacts } from "../../brain/status-sink.js";
|
|
11
11
|
import { expandTiers } from "../roles.js";
|
|
12
12
|
import { announceReadDenySwap, screenSwappableDeps } from "../swappable-deps.js";
|
|
13
13
|
import { runSideQuery } from "../side-query.js";
|
|
@@ -62,6 +62,7 @@ import { runStopAndFinalVerify } from "./run-stop-and-final-verify.js";
|
|
|
62
62
|
import { runRecoveryLanes } from "./run-recovery-lanes.js";
|
|
63
63
|
import { runGitLane } from "./run-git-lane.js";
|
|
64
64
|
import { deploymentCanRerootChild } from "./child-tree.js";
|
|
65
|
+
import { rewindSessionFiles } from "./rewind-files.js";
|
|
65
66
|
import { thrownText } from "../thrown-value.js";
|
|
66
67
|
export class Runner {
|
|
67
68
|
deps;
|
|
@@ -160,11 +161,8 @@ export class Runner {
|
|
|
160
161
|
await prev.catch(() => { });
|
|
161
162
|
return () => {
|
|
162
163
|
release();
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
this.sessionLocks.delete(sessionId);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
164
|
+
if (this.sessionLocks.get(sessionId) === chain)
|
|
165
|
+
this.sessionLocks.delete(sessionId);
|
|
168
166
|
};
|
|
169
167
|
}
|
|
170
168
|
swapDeps(next) {
|
|
@@ -233,8 +231,9 @@ export class Runner {
|
|
|
233
231
|
announceReadDenySwap(this.deps.onNotice, seats, this.deps);
|
|
234
232
|
}
|
|
235
233
|
sideQuery(spec) {
|
|
236
|
-
return runWithReasoningWireFacts(() => { }, () => runSideQuery(spec, { brain: this.deps.brain, models: this.deps.models, roles: this.deps.roles }));
|
|
234
|
+
return runWithReasoningWireFacts(() => { }, () => runWithCapabilityWithheld(() => { }, () => runSideQuery(spec, { brain: this.deps.brain, models: this.deps.models, roles: this.deps.roles })));
|
|
237
235
|
}
|
|
236
|
+
rewindFiles(request) { return rewindSessionFiles({ deps: this.deps, sessions: this.sessions, readStates: this.sessionReadStates, sessionBusy: (id) => this.sessionLocks.has(id), takeSessionLock: (id) => this.acquireSessionLock(id) }, request); }
|
|
238
237
|
runTaskStream(spec, resume, internals) {
|
|
239
238
|
if (resume !== undefined && (typeof resume !== "object" || resume.outcome === undefined)) {
|
|
240
239
|
throw new TypeError("runTaskStream: `resume` must be a ResumeRun carrying `outcome` — got a value without one. " +
|
|
@@ -403,7 +402,7 @@ export class Runner {
|
|
|
403
402
|
const { effectiveTimeoutMs, walltimeMonotonicDeadline, timeout, pushContent, ownCommittedTailRef, emitCommitted } = runClockAndContent({ spec, prepared, queue, internals, rs, ident, parentToolCallId, startedToolCallIds });
|
|
404
403
|
const toolProgress = createToolProgressLane(pushContent, ident, prepared.toolOccurrences);
|
|
405
404
|
prepared.toolProgressRef.current = toolProgress;
|
|
406
|
-
const { withBrainSinks, withLegRequestSinks } = runBrainSinks({ queue, internals, rs, ident, observeReasoningWireFacts, notice: { onNotice: this.deps.onNotice, sessionId: prepared.sessionId, runId: prepared.runId } });
|
|
405
|
+
const { withBrainSinks, withLegRequestSinks } = runBrainSinks({ queue, internals, rs, ident, observeReasoningWireFacts, notice: { onNotice: this.deps.onNotice, sessionId: prepared.sessionId, runId: prepared.runId }, announced: prepared });
|
|
407
406
|
const toolLabels = new Map(prepared.tools.flatMap((t) => (t.label !== undefined && t.label !== t.name ? [[t.name, t.label]] : [])));
|
|
408
407
|
for (const orphan of prepared.wakeRecovered) {
|
|
409
408
|
emitSettled(prepared.toolOccurrences, { toolCallId: orphan.toolCallId, spelledName: orphan.toolName, ...(toolLabels.has(orphan.toolName) ? { label: toolLabels.get(orphan.toolName) } : {}), args: orphan.args }, reconciledEnd(orphan), { push: (f) => queue.push({ ...f, ...ident() }), structured: prepared.structuredProjector, mediaByteCapBytes: this.deps.mediaByteCapBytes });
|
|
@@ -502,7 +501,7 @@ export class Runner {
|
|
|
502
501
|
token, cp, resumeSignal, recheckGovernanceWindow, store, runner: this.depsSeat,
|
|
503
502
|
locallyClaimedTokens: this.locallyClaimedTokens, parentConstraintRegistry: this.parentConstraintRegistry, suspendedEnvReaps: this.suspendedEnvReaps,
|
|
504
503
|
next: () => resumeClaim({
|
|
505
|
-
token, cp, store, outcomeForStore,
|
|
504
|
+
token, cp, store, outcomeForStore, holder: internals?.holder,
|
|
506
505
|
locallyClaimedTokens: this.locallyClaimedTokens, parentConstraintRegistry: this.parentConstraintRegistry,
|
|
507
506
|
next: () => this.resumeHandoff({ token, cp, store, config, internals, resumeInternals, plainPolicyOutcome, redeemedAnswer, outcomeForStore, wakeMessage, wakeHookContext, legMods, resumeSignal }),
|
|
508
507
|
}),
|
|
@@ -39,7 +39,22 @@ import type { ReadFileState } from "../../tools/fs/safety.js";
|
|
|
39
39
|
*/
|
|
40
40
|
export declare class SessionReadFileStates {
|
|
41
41
|
private readonly seats;
|
|
42
|
+
/**
|
|
43
|
+
* The ONE handoff of "which files did a file-history restore of this session move" to the read state that
|
|
44
|
+
* must stop vouching for their old bytes — written by every restore (the run's restore seat and the
|
|
45
|
+
* out-of-run `Runner.rewindFiles`), read by the next leg's read face, which checks each path against the disk
|
|
46
|
+
* after every seeding rung and settles the batch only once its own map is adopted as the seat. A leg that
|
|
47
|
+
* throws before adopting, or skips the adoption, leaves the batch for the next one. Bounded like the seats
|
|
48
|
+
* (LRU over session ids): a dropped batch costs a refusal whose wording blames an outside edit, never an admission.
|
|
49
|
+
*/
|
|
50
|
+
private readonly restored;
|
|
42
51
|
private static readonly CAP;
|
|
52
|
+
/** Record the ABSOLUTE paths a restore of `sessionId`'s history wrote, deleted or failed to write. */
|
|
53
|
+
noteRestored(sessionId: string, absPaths: readonly string[]): void;
|
|
54
|
+
/** The paths still owed a read-state check on `sessionId` — a copy; nothing is cleared by reading. */
|
|
55
|
+
pendingRestored(sessionId: string): readonly string[];
|
|
56
|
+
/** Clear exactly the paths a leg checked and then adopted over; a path noted since stays owed. */
|
|
57
|
+
settleRestored(sessionId: string, checked: readonly string[]): void;
|
|
43
58
|
/** The session's seat row, or undefined (cross-process / evicted / first turn) ⇒ caller replays.
|
|
44
59
|
* The caller must verify the anchor against the session's CURRENT branch before using `state`. */
|
|
45
60
|
get(sessionId: string): {
|
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
export class SessionReadFileStates {
|
|
2
2
|
seats = new Map();
|
|
3
|
+
restored = new Map();
|
|
3
4
|
static CAP = 1024;
|
|
5
|
+
noteRestored(sessionId, absPaths) {
|
|
6
|
+
if (absPaths.length === 0)
|
|
7
|
+
return;
|
|
8
|
+
const batch = this.restored.get(sessionId) ?? new Set();
|
|
9
|
+
for (const p of absPaths)
|
|
10
|
+
batch.add(p);
|
|
11
|
+
this.restored.delete(sessionId);
|
|
12
|
+
this.restored.set(sessionId, batch);
|
|
13
|
+
while (this.restored.size > SessionReadFileStates.CAP) {
|
|
14
|
+
const oldest = this.restored.keys().next().value;
|
|
15
|
+
if (oldest === undefined)
|
|
16
|
+
break;
|
|
17
|
+
this.restored.delete(oldest);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
pendingRestored(sessionId) {
|
|
21
|
+
return [...(this.restored.get(sessionId) ?? [])];
|
|
22
|
+
}
|
|
23
|
+
settleRestored(sessionId, checked) {
|
|
24
|
+
const batch = this.restored.get(sessionId);
|
|
25
|
+
if (batch === undefined)
|
|
26
|
+
return;
|
|
27
|
+
for (const p of checked)
|
|
28
|
+
batch.delete(p);
|
|
29
|
+
if (batch.size === 0)
|
|
30
|
+
this.restored.delete(sessionId);
|
|
31
|
+
}
|
|
4
32
|
get(sessionId) {
|
|
5
33
|
const seat = this.seats.get(sessionId);
|
|
6
34
|
if (seat !== undefined) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { canonicalizeTarget, isWinFormPath, pathFamilyOf, writeTargetPath } from "../../tools/fs/safety.js";
|
|
2
|
-
import { SESSION_RULES_GRAMMAR, compileSessionRuleBucket, continuesLineage, earlierGrammarAnnouncer, earlierGrammarRefusalClause, readSessionRulesShape, unreadableDenyEntries } from "../session-policy-store.js";
|
|
2
|
+
import { SESSION_RULES_GRAMMAR, compileSessionRuleBucket, continuesLineage, earlierGrammarAnnouncer, earlierGrammarEntries, earlierGrammarRefusalClause, readSessionRulesShape, unreadableDenyEntries } from "../session-policy-store.js";
|
|
3
3
|
import { compiledEntryName, judgeAllowEntries, uncoveredCommandSegment } from "../allow-entry.js";
|
|
4
4
|
import { inlineUntrusted } from "../untrusted-text.js";
|
|
5
5
|
import { callTargetReadingOf, pathTargetBaseOf, readCallTarget } from "../effective-path-target.js";
|
|
@@ -95,7 +95,7 @@ function compileSessionRules(rules) {
|
|
|
95
95
|
if ("fault" in shaped) {
|
|
96
96
|
const { field, got } = shaped.fault;
|
|
97
97
|
const what = got === "not a rule bucket" ? "a key that is no rule bucket" : field === "" ? `a value that is ${got}, not an object of rule buckets` : `${field} holding ${got}`;
|
|
98
|
-
return { deny: [], allow: undefined, earlier: { grammar: SESSION_RULES_GRAMMAR, toolAllow: [], toolDeny: [] }, allowDirs: undefined, pathRows: false, names: { deny: [], allow: [] }, unreadable: refuseEvery(what) };
|
|
98
|
+
return { deny: [], allow: undefined, earlier: { grammar: SESSION_RULES_GRAMMAR, toolAllow: [], toolDeny: [] }, announced: { toolAllow: [], toolDeny: [] }, allowDirs: undefined, pathRows: false, names: { deny: [], allow: [] }, unreadable: refuseEvery(what) };
|
|
99
99
|
}
|
|
100
100
|
const { toolAllow, allowDirs, grammar } = shaped.rules;
|
|
101
101
|
const unreadDeny = unreadableDenyEntries(shaped.rules).length;
|
|
@@ -109,6 +109,7 @@ function compileSessionRules(rules) {
|
|
|
109
109
|
deny,
|
|
110
110
|
allow,
|
|
111
111
|
earlier: { grammar, toolAllow: named(allowList, true), toolDeny: named(denyList, true) },
|
|
112
|
+
announced: { toolAllow: earlierGrammarEntries(shaped.rules, "toolAllow"), toolDeny: earlierGrammarEntries(shaped.rules, "toolDeny") },
|
|
112
113
|
allowDirs: allowDirs !== undefined && allowDirs.length > 0 ? allowDirs : undefined,
|
|
113
114
|
pathRows: [...deny, ...(allow ?? [])].some((r) => r.compiled.kind === "path"),
|
|
114
115
|
names: { deny: [...deny.map((r) => compiledEntryName(r.compiled)), ...named(denyList, false)], allow: [...(allow ?? []).map((r) => compiledEntryName(r.compiled)), ...named(allowList, false)] },
|
|
@@ -128,7 +129,7 @@ export function createSessionRulePolicy(rules, opts) {
|
|
|
128
129
|
if (compiled === undefined || compiledFor !== r) {
|
|
129
130
|
compiled = compileSessionRules(r);
|
|
130
131
|
for (const field of ["toolAllow", "toolDeny"])
|
|
131
|
-
announceEarlier(compiled.
|
|
132
|
+
announceEarlier(compiled.announced[field], field, compiled.earlier.grammar);
|
|
132
133
|
compiledFor = r;
|
|
133
134
|
}
|
|
134
135
|
return compiled;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The run's seat for `inherit_env.names_withheld`: the person whose run drives the engine's shell tool is told which
|
|
3
|
+
* variables of the engine's environment that shell does not receive.
|
|
4
|
+
*
|
|
5
|
+
* ONE FACT, ONE MINT. Which entries a shell child loses is decided by the execution environment's one composition
|
|
6
|
+
* (`inheritedHostEnv(policy, findings)` and the adapter's explicit grants), and the environment hands the result over as
|
|
7
|
+
* the read `ExecutionEnv.withheldEnv`. This seat reads that answer and tells it; it never recomputes it (the policy and
|
|
8
|
+
* the grants are the adapter's, not the run's). The split into the scrub's half and the deployment's own credentials is
|
|
9
|
+
* the one the operator notice uses (`withheldEnvNames`).
|
|
10
|
+
*
|
|
11
|
+
* WHEN. At the start of every call to the engine's own shell tool (its mount, judged by the catalog's mount judge), on a
|
|
12
|
+
* root leg (the person reads the root; the delegation fact is the hook identity's, the leg's one derivation). The answer
|
|
13
|
+
* is read at each such call because it can grow during a run — a credential the engine takes in when it first routes a
|
|
14
|
+
* model, dials a peer or builds a seat is withheld from the next child — and a call follows at least one model request.
|
|
15
|
+
* Told once per SESSION per answer: the digest rides the session's announced record (`advisories`), and a run-time record
|
|
16
|
+
* write is parked for the leg's flush like every other run-time arm of that record.
|
|
17
|
+
*
|
|
18
|
+
* An answer of `"unknown"` is told as unknown, never as silence. A value that is neither a list of findings nor
|
|
19
|
+
* `"unknown"` (or a read that throws) is a wiring fault: it is announced to the operator under the existing
|
|
20
|
+
* capability-shape code, once per run, and the person is told nothing — no reading defaults to `"unknown"`.
|
|
21
|
+
*/
|
|
22
|
+
import { type EngineNotice } from "../engine-notice.js";
|
|
23
|
+
import type { ExecutionEnv } from "../../internal/harness.js";
|
|
24
|
+
import type { Prepared } from "./contracts.js";
|
|
25
|
+
export type WithheldShellEnvSeatInput = Pick<Prepared, "sessionId" | "runId" | "hookIdentity" | "toolRosterDeltas" | "announcedListingsRef" | "frameReceipts"> & {
|
|
26
|
+
readonly harness: {
|
|
27
|
+
readonly env: Pick<ExecutionEnv, "withheldEnv">;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
/** The seat, per run. `onToolStart` never throws: a diagnostic may not be what fails a call. */
|
|
31
|
+
export declare function createWithheldShellEnvSeat(prepared: WithheldShellEnvSeatInput, onNotice: ((notice: EngineNotice) => void) | undefined): {
|
|
32
|
+
onToolStart(toolName: string): void;
|
|
33
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { deliverEngineNotice } from "../engine-notice.js";
|
|
2
|
+
import { withheldEnvUserNotice } from "../secret-env.js";
|
|
3
|
+
import { isEngineShellFace } from "../tool-catalog-entries.js";
|
|
4
|
+
import { toolCallFaceOf } from "../tool-roster.js";
|
|
5
|
+
import { announceDigest, withAnnounceDigests } from "./announce-once-ledger.js";
|
|
6
|
+
const isFinding = (f) => typeof f === "object" && f !== null && typeof Reflect.get(f, "key") === "string" && typeof Reflect.get(f, "kind") === "string";
|
|
7
|
+
function readWithheldEnv(env) {
|
|
8
|
+
try {
|
|
9
|
+
const value = env.withheldEnv;
|
|
10
|
+
if (value === "unknown")
|
|
11
|
+
return "unknown";
|
|
12
|
+
if (!Array.isArray(value))
|
|
13
|
+
return { malformed: value === null ? "null" : typeof value };
|
|
14
|
+
return value.every(isFinding) ? value : { malformed: "array holding a non-finding" };
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return { malformed: "unreadable" };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function createWithheldShellEnvSeat(prepared, onNotice) {
|
|
21
|
+
let shapeFaultTold = false;
|
|
22
|
+
return {
|
|
23
|
+
onToolStart(toolName) {
|
|
24
|
+
if (prepared.hookIdentity.isDelegatedChild || !isEngineShellFace(toolCallFaceOf(prepared.toolRosterDeltas.current, toolName)))
|
|
25
|
+
return;
|
|
26
|
+
const answer = readWithheldEnv(prepared.harness.env);
|
|
27
|
+
if (typeof answer === "object" && "malformed" in answer) {
|
|
28
|
+
if (shapeFaultTold)
|
|
29
|
+
return;
|
|
30
|
+
shapeFaultTold = true;
|
|
31
|
+
deliverEngineNotice(onNotice, {
|
|
32
|
+
code: "config.execution_env_capability_invalid",
|
|
33
|
+
message: `The execution environment declares withheldEnv as (${answer.malformed}), not a list of findings or "unknown". The person whose run drives its shell is told nothing about the variables that shell does not receive. Fix the adapter — this is a wiring fault, not a supported way to leave the member unanswered.`,
|
|
34
|
+
detail: { key: "withheldEnv", valueType: answer.malformed },
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const notice = withheldEnvUserNotice(answer, { sessionId: prepared.sessionId, runId: prepared.runId });
|
|
39
|
+
if (notice === undefined)
|
|
40
|
+
return;
|
|
41
|
+
const d = notice.detail;
|
|
42
|
+
const digest = announceDigest(notice.code, `${d.state}\n${[...(d.names ?? [])].sort().join("\n")}\n\n${[...(d.ownCredentials ?? [])].sort().join("\n")}`);
|
|
43
|
+
const record = prepared.announcedListingsRef;
|
|
44
|
+
if (record.advisories?.includes(digest) === true)
|
|
45
|
+
return;
|
|
46
|
+
deliverEngineNotice(onNotice, notice);
|
|
47
|
+
record.advisories = withAnnounceDigests(record.advisories, [digest]);
|
|
48
|
+
prepared.frameReceipts.listingSnapshotOwed = true;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -39,7 +39,7 @@ export function readSkillsSeat(skills) {
|
|
|
39
39
|
const at = `${SKILLS_SEAT}[${i}]`;
|
|
40
40
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
41
41
|
throw skillsSeatRefusal(at, `must be an object { name, description, content } (got ${kindOf(raw)})`);
|
|
42
|
-
const { name, description, content, allowedTools, disallowedTools, files: rawFiles, baseDir, ...rest } = raw;
|
|
42
|
+
const { name, description, content, allowedTools, disallowedTools, files: rawFiles, baseDir, mods: rawMods, ...rest } = raw;
|
|
43
43
|
void rest;
|
|
44
44
|
for (const [member, value] of [["name", name], ["description", description], ["content", content]]) {
|
|
45
45
|
if (typeof value !== "string")
|
|
@@ -47,11 +47,15 @@ export function readSkillsSeat(skills) {
|
|
|
47
47
|
}
|
|
48
48
|
const files = readSkillFiles(rawFiles, `${at}.files`);
|
|
49
49
|
skillBaseDirOf(baseDir);
|
|
50
|
+
if (rawMods !== undefined && !Array.isArray(rawMods))
|
|
51
|
+
throw skillsSeatRefusal(`${at}.mods`, `must be a list of mods registrations (got ${kindOf(rawMods)})`);
|
|
50
52
|
if (seen.has(name))
|
|
51
53
|
continue;
|
|
52
54
|
seen.add(name);
|
|
53
55
|
const [allowed, denied] = [readSkillTable(allowedTools), readSkillTable(disallowedTools)];
|
|
54
|
-
|
|
56
|
+
const list = rawMods;
|
|
57
|
+
const mods = list === undefined ? undefined : Object.freeze(Array.from({ length: list.length }, (_, j) => list[j]));
|
|
58
|
+
out.push({ name, description, content, ...(allowed !== undefined ? { allowedTools: allowed } : {}), ...(denied !== undefined ? { disallowedTools: denied } : {}), ...(files !== undefined ? { files } : {}), ...(baseDir !== undefined ? { baseDir } : {}), ...(mods !== undefined ? { mods } : {}) });
|
|
55
59
|
}
|
|
56
60
|
return out;
|
|
57
61
|
}
|
|
@@ -74,7 +74,7 @@ export function streamSettleBackstop(input) {
|
|
|
74
74
|
sessionId: taskIdRef.sessionId ?? "unknown",
|
|
75
75
|
...(taskIdRef.runId !== undefined ? { runId: taskIdRef.runId } : {}),
|
|
76
76
|
terminal: { kind: "failed", ...(code !== undefined ? { code } : {}), message, ...(detail !== undefined ? { detail } : {}) },
|
|
77
|
-
result: "",
|
|
77
|
+
result: "", resultEntryIds: [],
|
|
78
78
|
...(remoteEnvFailure !== undefined ? { remoteEnvFailures: remoteEnvFailure } : {}),
|
|
79
79
|
...(taskIdRef.effectiveMemoryScopes !== undefined ? { effectiveMemoryScopes: taskIdRef.effectiveMemoryScopes } : {}),
|
|
80
80
|
...(taskIdRef.effectiveReasoning !== undefined ? { effectiveReasoning: taskIdRef.effectiveReasoning } : {}),
|
|
@@ -6,7 +6,7 @@ import { ENGINE_TOOLS } from "../tool-catalog-entries.js";
|
|
|
6
6
|
import { callerToolNameProblem } from "../caller-tool-name.js";
|
|
7
7
|
import { mintNamespacePrefix } from "../protocol-naming.js";
|
|
8
8
|
import { PROTOCOL_TABLE, protocolOf } from "../protocol-table.js";
|
|
9
|
-
import { mountedToolNames, splitNamespacedName
|
|
9
|
+
import { grantWildcardRefusalOf, mountedToolNames, splitNamespacedName } from "../tool-name-aliases.js";
|
|
10
10
|
import { projectionToolNames } from "../tool-policy.js";
|
|
11
11
|
import { declaredDelegationNameOf } from "../delegation-name.js";
|
|
12
12
|
export function renamedDelegationMountSentence(...rosters) {
|
|
@@ -97,9 +97,6 @@ function readableToolNameList(where, side, value, code) {
|
|
|
97
97
|
throw refused(notAStringSentence(where, side, index, read.type), code, "not_a_string");
|
|
98
98
|
if (read.kind === "unreadable")
|
|
99
99
|
throw grammarRefusal(where, side, { entry: read.entry, reason: "grammar" }, code);
|
|
100
|
-
if (side === "denied" && read.name === "*") {
|
|
101
|
-
throw refused(`${where} declares ${renderListEntry(entry)} in its ${LIST_WORD[side]}: a denied list has no wildcard — the entry would hide nothing. To give the agent no tools, write an empty allowed list.`, code, "unsupported_pattern");
|
|
102
|
-
}
|
|
103
100
|
return { entry: entry, name: read.name, content: read.content };
|
|
104
101
|
});
|
|
105
102
|
}
|
|
@@ -117,11 +114,11 @@ function judgeToolNameList(where, side, value, universe, advise, code) {
|
|
|
117
114
|
const content = side === "denied" && written;
|
|
118
115
|
const reach = side === "denied" ? readDeniedToolList([entry]) : (readAllowedToolList([entry]) ?? readDeniedToolList([]));
|
|
119
116
|
const split = splitNamespacedName(name);
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
117
|
+
const toolSplit = splitNamespacedName(toolName);
|
|
118
|
+
if (toolName.includes("*") && (toolSplit === undefined || toolSplit.peer.includes("*"))) {
|
|
122
119
|
if (side === "denied")
|
|
123
120
|
continue;
|
|
124
|
-
throw refused(`${where} declares ${renderListEntry(entry)} in its ${LIST_WORD[side]}:
|
|
121
|
+
throw refused(`${where} declares ${renderListEntry(entry)} in its ${LIST_WORD[side]}: ${grantWildcardRefusalOf(name)}.`, code, "unsupported_pattern");
|
|
125
122
|
}
|
|
126
123
|
const { inert } = compileAllowList([toolName], "deny", universe.known);
|
|
127
124
|
const flaw = inert[0] === undefined ? undefined : { ...inert[0], entry, ...(inert[0].reason === "near_miss" && inert[0].currentName !== undefined ? { carriedBy: universe.carrierOf(inert[0].currentName) } : {}) };
|
|
@@ -58,6 +58,12 @@ export declare const SKILL_TOOL_NAME = "Skill";
|
|
|
58
58
|
* an oversized skill is excluded from the disclosure block and the tool, with an operator-visible config error. The compaction-time retention caps are a
|
|
59
59
|
* different door, deliberately. */
|
|
60
60
|
export declare const SKILL_CONTENT_MAX_CHARS: number;
|
|
61
|
+
/** The skills a leg LOADS — those the load gate above passes ({@link skillLoadReading}, the one predicate): the skills whose
|
|
62
|
+
* hooks the leg's mods admission takes, as the roster's filter (which also reports each one it excludes) takes the same. */
|
|
63
|
+
export declare function skillsThatLoad<T extends {
|
|
64
|
+
readonly content: string;
|
|
65
|
+
readonly baseDir?: unknown;
|
|
66
|
+
}>(skills: readonly T[] | undefined): T[];
|
|
61
67
|
/** Total per-invoke cap for a skill's inlined attachments (`SkillSpec.files`) — an ATTACHMENT-face budget, distinct from the (gone) body truncation door:
|
|
62
68
|
* the body is delivered untruncated at invoke time (CC parity), while attachments ride along bounded and truncation-disclosed. */
|
|
63
69
|
export declare const SKILL_ATTACHMENTS_MAX_CHARS = 50000;
|
|
@@ -4,7 +4,7 @@ import { sanitizeUntrustedText, SHELLED_BODY_ENVELOPE_TAGS } from "../untrusted-
|
|
|
4
4
|
import { SKILL_LISTING_DEFAULT_BUDGET, SKILL_LISTING_DESC_MAX_CHARS_DEFAULT } from "../skill-listing-budget.js";
|
|
5
5
|
import { readSkillTable, skillNamedBy } from "../skill-grant.js";
|
|
6
6
|
import { OUTPUT_TOOL_NAME, mountRuleFace, toolFace } from "../tool-catalog-entries.js";
|
|
7
|
-
import { substituteSkillRoot, substituteSkillRootBounded } from "./skill-base-dir.js";
|
|
7
|
+
import { skillLoadReading, substituteSkillRoot, substituteSkillRootBounded } from "./skill-base-dir.js";
|
|
8
8
|
import { readSkillsSeat } from "./skills-seat.js";
|
|
9
9
|
import { foldListingWithin } from "./listing-fold.js";
|
|
10
10
|
export const REPORT_BLOCKED_TOOL_NAME = "ReportBlocked";
|
|
@@ -90,6 +90,9 @@ export function createReportFindingsTool() {
|
|
|
90
90
|
}
|
|
91
91
|
export const SKILL_TOOL_NAME = "Skill";
|
|
92
92
|
export const SKILL_CONTENT_MAX_CHARS = 1024 * 1024;
|
|
93
|
+
export function skillsThatLoad(skills) {
|
|
94
|
+
return (skills ?? []).filter((s) => skillLoadReading(s, SKILL_CONTENT_MAX_CHARS).loads);
|
|
95
|
+
}
|
|
93
96
|
export const SKILL_ATTACHMENTS_MAX_CHARS = 50_000;
|
|
94
97
|
export const SKILL_ATTACHMENT_PATH_MAX_CHARS = 512;
|
|
95
98
|
const SKILL_FILES_LIST_MAX_CHARS = 200;
|
|
@@ -64,20 +64,18 @@ export declare function buildDeferredRegistry(deferred: ReadonlySet<string>, too
|
|
|
64
64
|
* validation, not activation state: a call whose arguments validate against the REAL tool's
|
|
65
65
|
* declared schema runs the real tool directly (activation is only about whether the model has
|
|
66
66
|
* been SHOWN the schema, never an execution gate). Governance cannot be laundered through this
|
|
67
|
-
* lane:
|
|
68
|
-
*
|
|
69
|
-
*
|
|
67
|
+
* lane: the gate judges the call before any execute, and the call runs the one mounted instance its
|
|
68
|
+
* placeholder stands for — the harness resolves a call to its placeholder before the gate, as it
|
|
69
|
+
* resolves any call to its tool, so what runs is fixed before anything is judged.
|
|
70
70
|
*/
|
|
71
71
|
export interface PlaceholderDirectCall {
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* roster moved on. Returns `undefined` when the name no longer resolves — a withdrawn name has no
|
|
78
|
-
* direct lane, and the caller falls back to the teaching rejection.
|
|
73
|
+
* The mounted instance this placeholder stands for, bound when the placeholder is minted for it (one
|
|
74
|
+
* placeholder per instance; a refresh that replaces the instance mints a new placeholder for the new
|
|
75
|
+
* one). Never re-resolved by name: a call the gate judged while a refresh landed runs the instance it
|
|
76
|
+
* was resolved to, whose own checks answer a declaration that changed meanwhile.
|
|
79
77
|
*/
|
|
80
|
-
|
|
78
|
+
real: PlaceholderDirectTarget;
|
|
81
79
|
/**
|
|
82
80
|
* The scheduling declaration this placeholder carries while it stands in for the real
|
|
83
81
|
* tool. Mirrors the REAL tool's own `executionMode` (see the mirror rationale in
|
|
@@ -91,7 +89,7 @@ export interface PlaceholderDirectCall {
|
|
|
91
89
|
* schema it hands back actually lives (this result only, versus this result AND every later
|
|
92
90
|
* request's tools block). Absent ⇒ the swap posture.
|
|
93
91
|
*
|
|
94
|
-
* A FUNCTION, evaluated per call
|
|
92
|
+
* A FUNCTION, evaluated per call: the answer is not
|
|
95
93
|
* a prepare-time constant. The run-wide strategy is, but the per-tool exemption on top of it reads
|
|
96
94
|
* the LIVE roster — an MCP refresh can replace a tool with a declaration that no longer fits the
|
|
97
95
|
* result-text carrier (or one that now does), and a boolean captured when the placeholder was built
|
|
@@ -113,7 +111,7 @@ export interface PlaceholderDirectCall {
|
|
|
113
111
|
*/
|
|
114
112
|
activate: () => Promise<string | undefined>;
|
|
115
113
|
}
|
|
116
|
-
/** The
|
|
114
|
+
/** The real tool behind a placeholder (see {@link PlaceholderDirectCall.real}). */
|
|
117
115
|
export interface PlaceholderDirectTarget {
|
|
118
116
|
/** The REAL tool's declared parameter schema — the shape gate for a direct call. */
|
|
119
117
|
parameters: TSchema;
|
|
@@ -93,9 +93,7 @@ export function createPlaceholderTool(info, direct) {
|
|
|
93
93
|
parameters: EMPTY_PARAMS,
|
|
94
94
|
...(direct.executionMode !== undefined ? { executionMode: direct.executionMode } : {}),
|
|
95
95
|
execute: async (toolCallId, params, signal, onUpdate) => {
|
|
96
|
-
const real = direct
|
|
97
|
-
if (real === undefined)
|
|
98
|
-
return teachingRejection();
|
|
96
|
+
const { real } = direct;
|
|
99
97
|
if (Value.Check(real.parameters, params)) {
|
|
100
98
|
lastFailureShape = undefined;
|
|
101
99
|
repeats = 0;
|
|
@@ -95,7 +95,7 @@ export interface SettledOccurrence extends Pick<OccurrenceEnd, "notExecuted"> {
|
|
|
95
95
|
* The END projection — the ONE mint of `tool_end`, for every station that closes a call: the live loop's
|
|
96
96
|
* `tool_execution_end`, the resumed leg's resolution, an interrupted run's reconcile and the reconcile replayed at
|
|
97
97
|
* the next process start. It reads the occurrence and nothing else: `gate` is its latest gate record, `isError` is
|
|
98
|
-
* the tool's bit or the refusal that record names, and `notExecuted` rides on positive evidence only: the station's own or `
|
|
98
|
+
* the tool's bit or the refusal that record names, and `notExecuted` rides on positive evidence only: the station's own or `neverExecuted` (returned for the rows).
|
|
99
99
|
*
|
|
100
100
|
* A call whose start never went out on this stream (a call the loop never reached, a call announced by a dead
|
|
101
101
|
* process) gets its start minted here first, marked `recovered` and carrying the input the closing station holds —
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {} from "../../internal/harness.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { isPlainRecord } from "../mods/kernel/receive.js";
|
|
3
|
+
import { neverExecuted } from "./tool-not-executed.js";
|
|
4
4
|
import { MCP_DELIVERY_VERDICTS } from "../mcp-failure.js";
|
|
5
5
|
import { closeNeverExecuted } from "../session-reconcile.js";
|
|
6
6
|
import { TOOL_SEARCH_NAME } from "./tool-disclosure.js";
|
|
@@ -38,11 +38,12 @@ export function batchResponseDigest(result) {
|
|
|
38
38
|
export function toolEndBodyFrom(result, isError, leg, gate, gatedCallIdOfRun) {
|
|
39
39
|
const o = toolOutputFrom(result, leg.mediaByteCapBytes);
|
|
40
40
|
const st = leg.structured(result);
|
|
41
|
-
const det = isError ?
|
|
42
|
-
const
|
|
43
|
-
const
|
|
41
|
+
const det = isError ? result?.details : undefined;
|
|
42
|
+
const card = isPlainRecord(det) ? det : undefined;
|
|
43
|
+
const codeRaw = card?.code;
|
|
44
|
+
const kindRaw = card?.errorKind;
|
|
44
45
|
const code = typeof codeRaw === "string" ? codeRaw : typeof kindRaw === "string" ? kindRaw : undefined;
|
|
45
|
-
const deliveredRaw =
|
|
46
|
+
const deliveredRaw = card?.delivered;
|
|
46
47
|
const delivered = typeof deliveredRaw === "string" && MCP_DELIVERY_VERDICTS.includes(deliveredRaw) ? deliveredRaw : undefined;
|
|
47
48
|
const gatedCallId = code === "gate.parked" ? gatedCallIdOfRun : undefined;
|
|
48
49
|
return {
|
|
@@ -54,7 +55,7 @@ export function toolEndBodyFrom(result, isError, leg, gate, gatedCallIdOfRun) {
|
|
|
54
55
|
...(gate !== undefined ? { gate } : {}),
|
|
55
56
|
};
|
|
56
57
|
}
|
|
57
|
-
const startFrameOf = (o, recovered) => ({ type: "tool_start", toolCallId: o.toolCallId, toolName: o.spelledName, ...(o.label !== undefined ? { label: o.label } : {}), args: o.args, ...(recovered ? { recovered: true } : {}) });
|
|
58
|
+
const startFrameOf = (o, recovered) => ({ type: "tool_start", toolCallId: o.toolCallId, toolName: o.spelledName, ...(o.label !== undefined ? { label: o.label } : {}), args: o.args, ...(recovered ? { recovered: true } : {}), ...(o.requestedBy !== undefined ? { requestedBy: o.requestedBy } : {}) });
|
|
58
59
|
export function announceToolCall(table, start, frames) {
|
|
59
60
|
table.open(start);
|
|
60
61
|
frames.push(startFrameOf(start, false));
|
|
@@ -65,7 +66,7 @@ export function emitSettled(table, start, end, frames) {
|
|
|
65
66
|
if (!occ.startEmitted)
|
|
66
67
|
frames.push(startFrameOf(occ, true));
|
|
67
68
|
const gate = occ.gateRounds.at(-1);
|
|
68
|
-
const isError = end.isError || gate?.disposition.kind === "denied", notExecuted = end.notExecuted === true ||
|
|
69
|
+
const isError = end.isError || gate?.disposition.kind === "denied", notExecuted = end.notExecuted === true || neverExecuted(occ);
|
|
69
70
|
table.close(occ.toolCallId, end.interrupted === true ? "interrupted" : "settled");
|
|
70
71
|
frames.push({
|
|
71
72
|
type: "tool_end",
|
|
@@ -75,7 +76,7 @@ export function emitSettled(table, start, end, frames) {
|
|
|
75
76
|
isError,
|
|
76
77
|
...toolEndBodyFrom(end.result, isError, frames, gate, end.gatedCallIdOfRun),
|
|
77
78
|
...(gate?.disposition.kind === "denied" && occ.wireName !== undefined ? { wireName: occ.wireName } : {}),
|
|
78
|
-
...(notExecuted ? { notExecuted: true } : {}),
|
|
79
|
+
...(notExecuted ? { notExecuted: true } : {}), ...(occ.answeredInPlaceBy !== undefined ? { answeredBy: occ.answeredInPlaceBy } : {}), ...(occ.requestedBy !== undefined ? { requestedBy: occ.requestedBy } : {}),
|
|
79
80
|
});
|
|
80
81
|
return { ...(gate !== undefined ? { gate } : {}), isError, ...(notExecuted ? { notExecuted: true } : {}) };
|
|
81
82
|
}
|
|
@@ -4,9 +4,14 @@ import type { ToolOccurrence } from "./tool-occurrence.js";
|
|
|
4
4
|
* release, by a station inside the execution, is not). A call whose start this stream never carried (a recovered
|
|
5
5
|
* one, closed by a station that knows only its own class) is not read here. */
|
|
6
6
|
export declare function refusedBeforeRelease(occ: Pick<ToolOccurrence, "life" | "gateRounds" | "startEmitted">): boolean;
|
|
7
|
+
/** The one reading of the engine's positive evidence that a call never ran: refused before it was let go
|
|
8
|
+
* ({@link refusedBeforeRelease}), or answered in place of its body by an extension at `tool.call` (the body was never called). */
|
|
9
|
+
export declare function neverExecuted(occ: Pick<ToolOccurrence, "life" | "gateRounds" | "startEmitted" | "answeredInPlaceBy">): boolean;
|
|
7
10
|
/** `details` as a persisted `toolResult` row carries it: `notExecuted` is the ENGINE's key — the settlement's fact when it holds,
|
|
8
11
|
* absent otherwise, whatever a tool wrote under that name. Returns `details` itself unless the key has to move; never mutates it. */
|
|
9
12
|
export declare function rowDetailsOf(details: unknown, notExecuted: boolean): unknown;
|
|
13
|
+
/** The persisted row's mark: the call this `toolResult` row closes never ran (the key {@link rowDetailsOf} writes). */
|
|
14
|
+
export declare function rowNotExecuted(details: unknown): boolean;
|
|
10
15
|
/** A row the resumed leg mints (`toolResultMsg`) with the settlement's fact on it. */
|
|
11
16
|
export declare function withRowNotExecuted<T extends object>(row: T, notExecuted: boolean): T;
|
|
12
17
|
/** Write the end projection's one `notExecuted` onto the result the live loop persists as the call's row: the loop builds that message
|
|
@@ -2,6 +2,9 @@ import { readOwnMembers } from "../thrown-value.js";
|
|
|
2
2
|
export function refusedBeforeRelease(occ) {
|
|
3
3
|
return occ.life === "announced" && occ.startEmitted && occ.gateRounds.at(-1)?.disposition.kind === "denied";
|
|
4
4
|
}
|
|
5
|
+
export function neverExecuted(occ) {
|
|
6
|
+
return refusedBeforeRelease(occ) || occ.answeredInPlaceBy !== undefined;
|
|
7
|
+
}
|
|
5
8
|
export function rowDetailsOf(details, notExecuted) {
|
|
6
9
|
const carries = (() => { try {
|
|
7
10
|
return details !== null && typeof details === "object" && !Array.isArray(details) && Object.keys(details).includes("notExecuted");
|
|
@@ -18,6 +21,14 @@ export function rowDetailsOf(details, notExecuted) {
|
|
|
18
21
|
delete bag["notExecuted"];
|
|
19
22
|
return bag;
|
|
20
23
|
}
|
|
24
|
+
export function rowNotExecuted(details) {
|
|
25
|
+
try {
|
|
26
|
+
return details !== null && typeof details === "object" && details.notExecuted === true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
21
32
|
export function withRowNotExecuted(row, notExecuted) {
|
|
22
33
|
return notExecuted ? { ...row, details: rowDetailsOf(undefined, true) } : row;
|
|
23
34
|
}
|
|
@@ -42,6 +42,8 @@ export interface OccurrenceStart {
|
|
|
42
42
|
readonly label?: string;
|
|
43
43
|
/** The arguments the start frame carries (for a recovered start: the call's own input as the transcript holds it). */
|
|
44
44
|
readonly args: unknown;
|
|
45
|
+
/** An extension's own call (`$.tool.call`): who asked for it — the frames carry it. Absent for a call a model message carried. */
|
|
46
|
+
readonly requestedBy?: import("../task-event.js").ExtensionRequester;
|
|
45
47
|
}
|
|
46
48
|
/** The record, as its readers see it. Written only through {@link ToolOccurrenceTable}. */
|
|
47
49
|
export interface ToolOccurrence extends OccurrenceStart {
|
|
@@ -63,6 +65,9 @@ export interface ToolOccurrence extends OccurrenceStart {
|
|
|
63
65
|
/** The heartbeat covers it. Cleared when the loop leaves the call behind at a turn end with no end of its own:
|
|
64
66
|
* the record stays (a later settlement must still know its start frame went out) but no beat describes it. */
|
|
65
67
|
readonly beating: boolean;
|
|
68
|
+
/** An extension at `tool.call` answered for the call in place of its body — its result, or its refusal — and named here:
|
|
69
|
+
* the body was never called (positive evidence the call did not run). Absent: no station answered in its place. */
|
|
70
|
+
readonly answeredInPlaceBy?: string;
|
|
66
71
|
}
|
|
67
72
|
/** The table of one leg's occurrences — the record's only writer. */
|
|
68
73
|
export interface ToolOccurrenceTable {
|
|
@@ -86,6 +91,9 @@ export interface ToolOccurrenceTable {
|
|
|
86
91
|
/** A station after the gate refused the call: one more gate record, minted as a veto of whatever the latest one
|
|
87
92
|
* settled (a person's yes stays on the settlement; the refusing layer is the disposition). Returns the record. */
|
|
88
93
|
refuse(toolCallId: string, layer: DeniedBy): GateOutcome;
|
|
94
|
+
/** An extension at `tool.call` answered for the call before its body was called (the kernel's record says the body had
|
|
95
|
+
* not started): the body is never called for this attempt. Once per attempt; a second is an engine defect. */
|
|
96
|
+
answeredInPlace(toolCallId: string, by: string): void;
|
|
89
97
|
/** An ask for this call is put to the person: the count rises, and the returned `resumeFromUser` lowers it once
|
|
90
98
|
* (a second call is a no-op). The pair is bound to THIS attempt — a return after the call ended, or after a
|
|
91
99
|
* reused id re-opened, touches nothing — and an ask for a call this leg does not hold counts nothing: the wait
|
|
@@ -21,6 +21,7 @@ export function createToolOccurrenceTable() {
|
|
|
21
21
|
...(start.wireName !== undefined ? { wireName: start.wireName } : {}),
|
|
22
22
|
...(start.label !== undefined ? { label: start.label } : {}),
|
|
23
23
|
args: start.args,
|
|
24
|
+
...(start.requestedBy !== undefined ? { requestedBy: start.requestedBy } : {}),
|
|
24
25
|
attempt,
|
|
25
26
|
life: "announced",
|
|
26
27
|
awaitingUser: 0,
|
|
@@ -96,6 +97,12 @@ export function createToolOccurrenceTable() {
|
|
|
96
97
|
occ.gateRounds.push(round);
|
|
97
98
|
return round;
|
|
98
99
|
},
|
|
100
|
+
answeredInPlace(toolCallId, by) {
|
|
101
|
+
const occ = held(toolCallId, "an answer in place of the body");
|
|
102
|
+
if (occ.answeredInPlaceBy !== undefined)
|
|
103
|
+
throw new Error(`tool occurrence: call "${toolCallId}" (attempt ${occ.attempt}) was already answered in place`);
|
|
104
|
+
occ.answeredInPlaceBy = by;
|
|
105
|
+
},
|
|
99
106
|
heard(toolCallId) {
|
|
100
107
|
const occ = byId.get(toolCallId);
|
|
101
108
|
if (occ !== undefined)
|