@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
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { capabilityHeld } from "./model-capability.js";
|
|
2
|
+
import { headerListEntries, lockHeader, takeHeaderSpellings } from "./request-params.js";
|
|
3
|
+
import { MIN_THINKING_TOKENS, RESPONSES_APIS, budgetCapSkipsThinking, declaredEffortLevels, declaredOffSpelling, mintEffortWireValue, reasoningBudgetShare, reasoningRequestCarried, resolveEffort, thinkingOffSpelled, } from "./reasoning.js";
|
|
4
|
+
export function lowestReasoningSeat(model) {
|
|
5
|
+
return thinkingOffSpelled(model) ? "off" : "low";
|
|
6
|
+
}
|
|
7
|
+
const BETA_EFFORT = "effort-2025-11-24";
|
|
8
|
+
const BETA_CONTEXT_MANAGEMENT = "context-management-2025-06-27";
|
|
9
|
+
const BETA_INTERLEAVED_THINKING = "interleaved-thinking-2025-05-14";
|
|
10
|
+
function put(body, key, value) {
|
|
11
|
+
body[key] = value;
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
function withTemplateKwarg(body, enabled) {
|
|
15
|
+
const kwargs = (typeof body.chat_template_kwargs === "object" && body.chat_template_kwargs) || {};
|
|
16
|
+
return put(body, "chat_template_kwargs", { ...kwargs, enable_thinking: enabled });
|
|
17
|
+
}
|
|
18
|
+
function withEffort(body, effort, supportsEffort) {
|
|
19
|
+
if (!supportsEffort || effort === undefined)
|
|
20
|
+
return undefined;
|
|
21
|
+
body.reasoning_effort = effort;
|
|
22
|
+
return effort;
|
|
23
|
+
}
|
|
24
|
+
const COMPLETIONS_DIALECT = {
|
|
25
|
+
openai: {
|
|
26
|
+
off: (body, model) => {
|
|
27
|
+
const spelling = declaredOffSpelling(model);
|
|
28
|
+
return spelling === undefined ? undefined : withEffort(body, spelling, true);
|
|
29
|
+
},
|
|
30
|
+
on: withEffort,
|
|
31
|
+
},
|
|
32
|
+
openrouter: {
|
|
33
|
+
off: (body) => put(body, "reasoning", { enabled: false }),
|
|
34
|
+
on: (body, effort) => {
|
|
35
|
+
put(body, "reasoning", { effort });
|
|
36
|
+
return effort;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
deepseek: {
|
|
40
|
+
off: (body) => put(body, "thinking", { type: "disabled" }),
|
|
41
|
+
on: (body, effort, supportsEffort) => {
|
|
42
|
+
put(body, "thinking", { type: "enabled" });
|
|
43
|
+
return withEffort(body, effort, supportsEffort);
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
together: {
|
|
47
|
+
off: (body) => put(body, "reasoning", { enabled: false }),
|
|
48
|
+
on: (body, effort, supportsEffort) => {
|
|
49
|
+
put(body, "reasoning", { enabled: true });
|
|
50
|
+
return withEffort(body, effort, supportsEffort);
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
qwen: { off: (body) => put(body, "enable_thinking", false), on: (body) => put(body, "enable_thinking", true) },
|
|
54
|
+
zai: { off: (body) => put(body, "enable_thinking", false), on: (body) => put(body, "enable_thinking", true) },
|
|
55
|
+
"qwen-chat-template": { off: (body) => withTemplateKwarg(body, false), on: (body) => withTemplateKwarg(body, true) },
|
|
56
|
+
};
|
|
57
|
+
function completionsDialectOf(format) {
|
|
58
|
+
return typeof format === "string" && Object.prototype.hasOwnProperty.call(COMPLETIONS_DIALECT, format) ? COMPLETIONS_DIALECT[format] : undefined;
|
|
59
|
+
}
|
|
60
|
+
const bodyOnly = (body, effort) => ({ body, headers: {}, effort, wireFacts: undefined });
|
|
61
|
+
function applyCompletions(input, body) {
|
|
62
|
+
const { model, level } = input;
|
|
63
|
+
const compat = (model.compat ?? {});
|
|
64
|
+
const dialect = completionsDialectOf(compat.thinkingFormat ?? "openai");
|
|
65
|
+
if (capabilityHeld(model, "reasoning") && level === "off")
|
|
66
|
+
return bodyOnly(body, dialect?.off(body, model));
|
|
67
|
+
if (!reasoningRequestCarried(model, level))
|
|
68
|
+
return bodyOnly(body);
|
|
69
|
+
const supportsEffort = compat.supportsReasoningEffort ?? true;
|
|
70
|
+
const wire = mintEffortWireValue(level, model, compat.reasoningEffortLevels).wireValue;
|
|
71
|
+
return bodyOnly(body, dialect?.on(body, wire, supportsEffort));
|
|
72
|
+
}
|
|
73
|
+
function applyResponses(input, body) {
|
|
74
|
+
const { model, level } = input;
|
|
75
|
+
const effort = responsesEffort(model, level);
|
|
76
|
+
if (effort !== undefined)
|
|
77
|
+
body.reasoning = { effort };
|
|
78
|
+
return bodyOnly(body, effort);
|
|
79
|
+
}
|
|
80
|
+
function responsesEffort(model, level) {
|
|
81
|
+
if (capabilityHeld(model, "reasoning") && level === "off")
|
|
82
|
+
return declaredOffSpelling(model);
|
|
83
|
+
const compat = (model.compat ?? {});
|
|
84
|
+
if (compat.supportsReasoningEffort === false)
|
|
85
|
+
return undefined;
|
|
86
|
+
if (!reasoningRequestCarried(model, level))
|
|
87
|
+
return undefined;
|
|
88
|
+
return mintEffortWireValue(level, model, compat.reasoningEffortLevels).wireValue;
|
|
89
|
+
}
|
|
90
|
+
function thinkingBudget(maxTokens, share, fixed, hardCap) {
|
|
91
|
+
const max = hardCap ? maxTokens : Math.max(maxTokens, MIN_THINKING_TOKENS * 2);
|
|
92
|
+
const want = fixed ?? Math.floor(max * share);
|
|
93
|
+
const budget = Math.min(Math.max(MIN_THINKING_TOKENS, want), max - 1);
|
|
94
|
+
return { max, budget };
|
|
95
|
+
}
|
|
96
|
+
function applyMessages(input, body) {
|
|
97
|
+
const { model, level } = input;
|
|
98
|
+
const compat = (model.compat ?? {});
|
|
99
|
+
let wireFacts;
|
|
100
|
+
let thinkingOn = false;
|
|
101
|
+
if (reasoningRequestCarried(model, level)) {
|
|
102
|
+
if (compat.thinkingMode === "adaptive") {
|
|
103
|
+
body.thinking = { type: "adaptive" };
|
|
104
|
+
thinkingOn = true;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
if (body.max_tokens === undefined || body.max_tokens === null) {
|
|
108
|
+
throw new TypeError("applyReasoningToRequest: the Messages budget form needs a body.max_tokens (it sizes the thinking budget)");
|
|
109
|
+
}
|
|
110
|
+
const maxTokens = body.max_tokens;
|
|
111
|
+
const hardCap = input.budget?.capIsHard ?? true;
|
|
112
|
+
wireFacts = { outputCapTokens: maxTokens, hardOutputCap: hardCap };
|
|
113
|
+
if (budgetCapSkipsThinking(wireFacts.outputCapTokens, wireFacts.hardOutputCap)) {
|
|
114
|
+
delete body.thinking;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const share = input.budget?.share ?? reasoningBudgetShare(level);
|
|
118
|
+
const { max, budget } = thinkingBudget(maxTokens, share, input.budget?.tokens, hardCap);
|
|
119
|
+
if (!Number.isFinite(Number(max)) || !Number.isFinite(budget)) {
|
|
120
|
+
const shown = (value) => (typeof value === "string" ? JSON.stringify(value) : String(value));
|
|
121
|
+
throw new TypeError(`applyReasoningToRequest: the Messages budget form cannot size a thinking budget from body.max_tokens ${shown(body.max_tokens)}, ` +
|
|
122
|
+
`budget.share ${shown(share)}, budget.tokens ${shown(input.budget?.tokens)} (cap ${shown(max)}, budget ${shown(budget)}); each must read as a finite number`);
|
|
123
|
+
}
|
|
124
|
+
body.max_tokens = max;
|
|
125
|
+
body.thinking = { type: "enabled", budget_tokens: budget };
|
|
126
|
+
thinkingOn = true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (thinkingOn)
|
|
130
|
+
delete body.temperature;
|
|
131
|
+
}
|
|
132
|
+
else if (capabilityHeld(model, "reasoning") && level === "off" && compat.thinkingMode !== "adaptive") {
|
|
133
|
+
body.thinking = { type: "disabled" };
|
|
134
|
+
}
|
|
135
|
+
const betas = [];
|
|
136
|
+
let effort;
|
|
137
|
+
const declaredEffort = declaredEffortLevels(compat.effortLevels);
|
|
138
|
+
if (declaredEffort !== undefined && reasoningRequestCarried(model, level)) {
|
|
139
|
+
const { effective } = resolveEffort(level, declaredEffort);
|
|
140
|
+
effort = effective === "minimal" ? "low" : effective;
|
|
141
|
+
body.output_config = { effort };
|
|
142
|
+
betas.push(BETA_EFFORT);
|
|
143
|
+
}
|
|
144
|
+
if (compat.contextManagement && thinkingOn) {
|
|
145
|
+
body.context_management = { edits: [{ type: "clear_thinking_20251015", keep: "all" }] };
|
|
146
|
+
betas.push(BETA_CONTEXT_MANAGEMENT);
|
|
147
|
+
}
|
|
148
|
+
if (compat.interleavedThinking)
|
|
149
|
+
betas.push(BETA_INTERLEAVED_THINKING);
|
|
150
|
+
return { body, headers: betas.length > 0 ? { "anthropic-beta": betas.join(",") } : {}, effort, wireFacts };
|
|
151
|
+
}
|
|
152
|
+
export function applyReasoningToRequest(input) {
|
|
153
|
+
const body = { ...input.body };
|
|
154
|
+
if (input.api === "anthropic-messages")
|
|
155
|
+
return applyMessages(input, body);
|
|
156
|
+
if (RESPONSES_APIS.has(input.api))
|
|
157
|
+
return applyResponses(input, body);
|
|
158
|
+
return applyCompletions(input, body);
|
|
159
|
+
}
|
|
160
|
+
export function mergeReasoningHeaders(headers, patch) {
|
|
161
|
+
for (const [name, value] of Object.entries(patch)) {
|
|
162
|
+
const lower = name.toLowerCase();
|
|
163
|
+
if (lower !== "anthropic-beta") {
|
|
164
|
+
lockHeader(headers, lower, value);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const present = takeHeaderSpellings(headers, lower).flatMap((held) => headerListEntries(held));
|
|
168
|
+
for (const beta of headerListEntries(value)) {
|
|
169
|
+
if (!present.includes(beta))
|
|
170
|
+
present.push(beta);
|
|
171
|
+
}
|
|
172
|
+
headers[lower] = present.join(",");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -18,8 +18,8 @@ export type ReasoningIntensity = ThinkingLevel;
|
|
|
18
18
|
export declare function isThinkingLevel(v: unknown): v is ThinkingLevel;
|
|
19
19
|
/**
|
|
20
20
|
* THE thinking-request ENTRY predicate — does this request enter an applier's emission path at all?
|
|
21
|
-
* One conjunction, three arms: the model
|
|
22
|
-
*
|
|
21
|
+
* One conjunction, three arms: the model holds reasoning (`capabilityHeld`, the one capability reading —
|
|
22
|
+
* a declaration of the wrong shape throws there instead of reading by truthiness), the requested value is a real
|
|
23
23
|
* {@link ThinkingLevel} (an out-of-contract value — a typo'd tier, a caller's own enum — reads as
|
|
24
24
|
* ABSENCE, never as a declared tier), and it is not the explicit `"off"`.
|
|
25
25
|
*
|
|
@@ -29,8 +29,8 @@ export declare function isThinkingLevel(v: unknown): v is ThinkingLevel;
|
|
|
29
29
|
* their own reporting shape (the `graded:false` intent-echo family, each pinned with its rationale
|
|
30
30
|
* where it lives); this predicate only closes the gate the three appliers used to re-spell.
|
|
31
31
|
*
|
|
32
|
-
* Single-sourced here because every wire applier (
|
|
33
|
-
*
|
|
32
|
+
* Single-sourced here because every wire applier (the completions, Messages and Responses arms of
|
|
33
|
+
* `applyReasoningToRequest`, in reasoning-request.ts) would otherwise re-spell the same three
|
|
34
34
|
* conjuncts while the REPORTING resolver ({@link resolveReasoning}) mirrored one of them, so a
|
|
35
35
|
* garbage tier puts ZERO parameters on the wire while the resolution claims a clamped-to-minimal
|
|
36
36
|
* gradient. A predicate the appliers and the reporter both call cannot drift.
|
|
@@ -58,7 +58,7 @@ export type ReasoningFormat = "openai" | "openrouter" | "deepseek" | "together"
|
|
|
58
58
|
* `reasoning_effort` path (thinking FORM is `thinkingMode`; effort carries the intensity). */
|
|
59
59
|
| "effort"
|
|
60
60
|
/** OpenAI Responses API (`openai-responses` / `azure-openai-responses`, design/163): the tier rides
|
|
61
|
-
* the NESTED `reasoning: { effort }` request field (
|
|
61
|
+
* the NESTED `reasoning: { effort }` request field (the Responses arm of `applyReasoningToRequest`), clamped
|
|
62
62
|
* by the same {@link resolveEffort} against `compat.reasoningEffortLevels` — NOT the completions
|
|
63
63
|
* top-level `reasoning_effort` the `"openai"` tag names. #325 review r3: before this member the
|
|
64
64
|
* resolver fell through to the completions default and labeled Responses resolutions `"openai"`. */
|
|
@@ -127,7 +127,7 @@ export declare function declaredOffSpelling(model: OffCapabilityModel): string |
|
|
|
127
127
|
* `reasoning:{enabled:false}` all spell it; the effort-only wires (stock openai completions, the Responses
|
|
128
128
|
* lane) spell it only through a deployment-declared off spelling ({@link declaredOffSpelling}).
|
|
129
129
|
*
|
|
130
|
-
* A model
|
|
130
|
+
* A model that does not hold reasoning (declared false, or undeclared — `capabilityHeld`) spells NOTHING: every applier returns before writing any key for it, so
|
|
131
131
|
* the request is the gateway's own default — and a default-on gateway thinks regardless (three of four live
|
|
132
132
|
* endpoints, 2026-09-15). This arm used to answer `true` ("a non-reasoning model never thinks"): the engine
|
|
133
133
|
* may size a request by what it SENT, never by what it hopes a gateway does when told nothing. What this
|
|
@@ -172,8 +172,8 @@ export interface ReasoningWireFacts {
|
|
|
172
172
|
export declare function declaredEffortLevels(v: unknown): readonly ThinkingLevel[] | undefined;
|
|
173
173
|
/**
|
|
174
174
|
* The effort-lane WIRE-VALUE mint — clamp ({@link resolveEffort}) + the `Model.thinkingLevelMap`
|
|
175
|
-
* translation in ONE place, consumed by both
|
|
176
|
-
*
|
|
175
|
+
* translation in ONE place, consumed by both effort-lane arms of `applyReasoningToRequest` (completions,
|
|
176
|
+
* Responses) AND the reporting dispatch ({@link resolveReasoning}'s
|
|
177
177
|
* arms), so the value that reaches the wire and the resolution a trace/result face claims are two
|
|
178
178
|
* reads of one computation, never parallel re-derivations. Map semantics (the field's contract): a
|
|
179
179
|
* MISSING key ⇒ provider default (the clamped tier name as-is); a STRING ⇒ that provider-specific
|
|
@@ -200,7 +200,7 @@ export interface ResolvedReasoning extends ReasoningResolution {
|
|
|
200
200
|
endpoint: string;
|
|
201
201
|
/**
|
|
202
202
|
* Present (true) only when the request never CARRIES at all: {@link reasoningRequestCarried} false
|
|
203
|
-
* on a non-"off" request — the model
|
|
203
|
+
* on a non-"off" request — the model does not hold reasoning (`capabilityHeld`: declared false or undeclared),
|
|
204
204
|
* OR the requested value is not a valid {@link ThinkingLevel} (an out-of-contract tier every wire
|
|
205
205
|
* applier reads as ABSENCE — the same three-conjunct gate all of them share) — or, with
|
|
206
206
|
* {@link ReasoningWireFacts} supplied, the anthropic budget path's cap-wins skip
|
|
@@ -212,7 +212,7 @@ export interface ResolvedReasoning extends ReasoningResolution {
|
|
|
212
212
|
* reason at its own tier — the brains deliberately send no disable key for a model declared
|
|
213
213
|
* non-reasoning, so the engine cannot claim a measured off there; `format` tells a consumer which
|
|
214
214
|
* family applies (on every other format, absence is the closest the wire has to off — see
|
|
215
|
-
*
|
|
215
|
+
* the completions arm's own contract). `format`/`endpoint` report the family that WOULD have carried the
|
|
216
216
|
* tier (the why-shape a consumer diagnoses with, not a claim about the request). Absent on every
|
|
217
217
|
* reasoning-capable resolution, so existing consumers see byte-identical objects. Loud-bad-values
|
|
218
218
|
* rule: the one arm where the request evaporates must not be the one arm with no report.
|
|
@@ -240,7 +240,7 @@ export interface ResolvedReasoning extends ReasoningResolution {
|
|
|
240
240
|
* drops the value — trace/result-face drift.
|
|
241
241
|
*
|
|
242
242
|
* - A request that never CARRIES ({@link reasoningRequestCarried} false on a non-"off" value: the model's
|
|
243
|
-
* `reasoning` capability
|
|
243
|
+
* `reasoning` capability is not held, or the requested value is not a valid tier — no brain emits any
|
|
244
244
|
* thinking parameter for either, whatever the format) → `effective:"off"`, `graded:false`, `clamped:true`,
|
|
245
245
|
* `dropped:true` — the loud-drop arm. Describing the capability dispatch instead would report a
|
|
246
246
|
* resolution the request never carried, leaving the one arm where the request evaporates as the one
|
package/dist/brain/reasoning.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { capabilityHeld } from "./model-capability.js";
|
|
1
2
|
const RANK = {
|
|
2
3
|
off: 0,
|
|
3
4
|
minimal: 1,
|
|
@@ -11,7 +12,7 @@ export function isThinkingLevel(v) {
|
|
|
11
12
|
return typeof v === "string" && Object.prototype.hasOwnProperty.call(RANK, v);
|
|
12
13
|
}
|
|
13
14
|
export function reasoningRequestCarried(model, reasoning) {
|
|
14
|
-
return
|
|
15
|
+
return capabilityHeld(model, "reasoning") && isThinkingLevel(reasoning) && reasoning !== "off";
|
|
15
16
|
}
|
|
16
17
|
export function rankOf(level) {
|
|
17
18
|
return RANK[level];
|
|
@@ -31,7 +32,7 @@ export function declaredOffSpelling(model) {
|
|
|
31
32
|
return typeof mapped === "string" && mapped !== "" ? mapped : undefined;
|
|
32
33
|
}
|
|
33
34
|
export function thinkingOffSpelled(model) {
|
|
34
|
-
if (!model
|
|
35
|
+
if (!capabilityHeld(model, "reasoning"))
|
|
35
36
|
return false;
|
|
36
37
|
const compat = (model.compat ?? {});
|
|
37
38
|
if (model.api === "anthropic-messages")
|
|
@@ -101,7 +102,7 @@ function dispatchReasoning(requested, model, facts) {
|
|
|
101
102
|
return { ...mint.resolution, format, endpoint };
|
|
102
103
|
}
|
|
103
104
|
export function reasoningEffortLevelsOf(model) {
|
|
104
|
-
if (!model
|
|
105
|
+
if (!capabilityHeld(model, "reasoning"))
|
|
105
106
|
return undefined;
|
|
106
107
|
const compat = (model.compat ?? {});
|
|
107
108
|
if (model.api === "anthropic-messages") {
|
|
@@ -122,12 +122,15 @@ export declare function applyExtraBody(body: Record<string, unknown>, model: Pic
|
|
|
122
122
|
export declare function lockHeader(headers: Record<string, string>, lowerName: string, value: string): void;
|
|
123
123
|
/**
|
|
124
124
|
* #343 (review r4) — case-fold READ-AND-CLAIM for an AUGMENTABLE structural header (`anthropic-beta`):
|
|
125
|
-
* returns the
|
|
126
|
-
*
|
|
125
|
+
* returns the value under EVERY spelling the bag carried, in key order, and deletes them all, so the
|
|
126
|
+
* caller's canonical lowercase write REPLACES them instead of duplicating beside them (the
|
|
127
127
|
* read-modify-write used to key the read by the exact lowercase name and miss `Anthropic-Beta`,
|
|
128
|
-
* losing the user's betas from the merge AND double-sending the header).
|
|
128
|
+
* losing the user's betas from the merge AND double-sending the header). A spelling is claimed whatever
|
|
129
|
+
* it holds — its value is returned as it is, so a spelling holding `undefined` does not end the claim.
|
|
129
130
|
*/
|
|
130
|
-
export declare function
|
|
131
|
+
export declare function takeHeaderSpellings(headers: Record<string, string>, lowerName: string): unknown[];
|
|
132
|
+
/** The entries of a comma-list header value (`" a , b,,c"` → `a`, `b`, `c`); a value that is not a string carries none. */
|
|
133
|
+
export declare function headerListEntries(value: unknown): string[];
|
|
131
134
|
/** A caller's header bag read ONCE, into a plain copy of its own enumerable entries — what a request build hands both
|
|
132
135
|
* the route law (which credential rides, and its identity) and the merge (what goes on the wire), so a bag whose getters
|
|
133
136
|
* or keys answer differently on a second read cannot be judged as one bag and sent as another. */
|
|
@@ -92,15 +92,18 @@ export function lockHeader(headers, lowerName, value) {
|
|
|
92
92
|
}
|
|
93
93
|
headers[lowerName] = value;
|
|
94
94
|
}
|
|
95
|
-
export function
|
|
95
|
+
export function takeHeaderSpellings(headers, lowerName) {
|
|
96
|
+
const values = [];
|
|
96
97
|
for (const k of Object.keys(headers)) {
|
|
97
98
|
if (k.toLowerCase() === lowerName) {
|
|
98
|
-
|
|
99
|
+
values.push(headers[k]);
|
|
99
100
|
delete headers[k];
|
|
100
|
-
return v;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
return
|
|
103
|
+
return values;
|
|
104
|
+
}
|
|
105
|
+
export function headerListEntries(value) {
|
|
106
|
+
return typeof value === "string" ? value.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "") : [];
|
|
104
107
|
}
|
|
105
108
|
export function headerBagOnce(bag) {
|
|
106
109
|
return bag === undefined ? undefined : { ...bag };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BrainRetryErrClass, BrainStatus } from "../core/types.js";
|
|
2
2
|
import type { ReasoningWireFacts } from "./reasoning.js";
|
|
3
|
+
import type { CapabilityDeclaration, ModelCapability } from "./model-capability.js";
|
|
3
4
|
/** Run `fn` with a per-task brain-status sink in scope. ALS propagates it through the async brain calls
|
|
4
5
|
* inside `fn` (the harness's prompt → brain.stream → connect/retry loop), so {@link emitBrainStatus}
|
|
5
6
|
* reaches THIS task's sink and nothing else. */
|
|
@@ -168,3 +169,22 @@ export declare function runWithCredentialOriginRefusals<T>(observe: (r: Credenti
|
|
|
168
169
|
* `routeRefusalError`; a judgment that only advises reports nothing). The
|
|
169
170
|
* observer is the Runner's own seat, whose one delivery is the guarded `deliverEngineNotice` — nothing is swallowed here. */
|
|
170
171
|
export declare function reportCredentialOriginRefusal(report: CredentialOriginRefusalReport): void;
|
|
172
|
+
/** A request that withheld a capability from the model it was sent to: the model, the capability, the model's declaration
|
|
173
|
+
* that withheld it (`capabilityOf`), and how many blocks it replaced. */
|
|
174
|
+
export interface CapabilityWithheldReport {
|
|
175
|
+
modelId: string;
|
|
176
|
+
capability: ModelCapability;
|
|
177
|
+
cause: Exclude<CapabilityDeclaration, "declared_on">;
|
|
178
|
+
count: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Run `fn` with a per-run withheld-capability sink in scope — the SIXTH brain→runner ALS channel, with the fourth's shape
|
|
182
|
+
* and for its reasons: the WHOLE leg (the end-of-task compaction runs after the leg's prompt, and a child leg running
|
|
183
|
+
* inside its parent's tool call must report to its own leg, not to the scope it inherited), not shielded around the leg's
|
|
184
|
+
* internal calls, not revoked on settlement, no-op outside the scope.
|
|
185
|
+
*/
|
|
186
|
+
export declare function runWithCapabilityWithheld<T>(observe: (r: CapabilityWithheldReport) => void, fn: () => Promise<T>): Promise<T>;
|
|
187
|
+
/** Report a withheld capability to the active per-run sink, if any (called by the message assemblers' one emit,
|
|
188
|
+
* `reportImagesWithheld`). The observer is the Runner's own seat, whose one delivery is the guarded `deliverEngineNotice`
|
|
189
|
+
* — nothing is swallowed here: a seat that fails otherwise fails the request build, never the person's notice in silence. */
|
|
190
|
+
export declare function reportCapabilityWithheld(report: CapabilityWithheldReport): void;
|
|
@@ -75,3 +75,10 @@ export function runWithCredentialOriginRefusals(observe, fn) {
|
|
|
75
75
|
export function reportCredentialOriginRefusal(report) {
|
|
76
76
|
credentialOriginRefusalSinkStore.getStore()?.observe(report);
|
|
77
77
|
}
|
|
78
|
+
const capabilityWithheldSinkStore = new AsyncLocalStorage();
|
|
79
|
+
export function runWithCapabilityWithheld(observe, fn) {
|
|
80
|
+
return capabilityWithheldSinkStore.run({ observe }, fn);
|
|
81
|
+
}
|
|
82
|
+
export function reportCapabilityWithheld(report) {
|
|
83
|
+
capabilityWithheldSinkStore.getStore()?.observe(report);
|
|
84
|
+
}
|
package/dist/core/a2a.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentTool } from "../internal/harness-types.js";
|
|
2
|
+
import { type HostFloor } from "./host-floor.js";
|
|
2
3
|
import type { A2aServerSpec, ToolEffect } from "./types.js";
|
|
3
4
|
/** The hard per-skill description bound (ruled 2026-08-03: ~2KiB). */
|
|
4
5
|
export declare const A2A_SKILL_DESCRIPTION_MAX_CHARS = 2048;
|
|
@@ -96,4 +97,4 @@ export declare class A2aRpcError extends Error {
|
|
|
96
97
|
* `allSettled` keeps it fail-open: one unreachable peer is a skipped peer with a warning, never a task
|
|
97
98
|
* that cannot start.
|
|
98
99
|
*/
|
|
99
|
-
export declare function materializeA2aTools(specs: readonly A2aServerSpec[], principal?: string, signal?: AbortSignal): Promise<MaterializedA2a>;
|
|
100
|
+
export declare function materializeA2aTools(specs: readonly A2aServerSpec[], principal?: string, signal?: AbortSignal, hostFloor?: HostFloor): Promise<MaterializedA2a>;
|
package/dist/core/a2a.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
import { A2A_TASK_STATES } from "./a2a-task-state.js";
|
|
4
|
-
import { assertEndpointBound,
|
|
4
|
+
import { assertEndpointBound, carriesDeclaredHeaders, resolveProtocolHttpHeaders, underDeclaredHeaders } from "./protocol-http-auth.js";
|
|
5
|
+
import { fetchFollowing, hopRefusal, HOST_FLOOR_REFUSED_CODE } from "./host-floor.js";
|
|
5
6
|
import { describeHttpTransportFailure } from "./mcp-failure.js";
|
|
6
7
|
import { findNamespacePrefixCollision, mintNamespacePrefix, mintNamespacedToolName } from "./protocol-naming.js";
|
|
7
8
|
import { A2A_NAMESPACE } from "./protocol-table.js";
|
|
@@ -77,6 +78,7 @@ function safeId(v) {
|
|
|
77
78
|
return undefined;
|
|
78
79
|
return inlineUntrusted(s, A2A_ID_MAX_CHARS);
|
|
79
80
|
}
|
|
81
|
+
const A2A_MAX_REDIRECTS = 20;
|
|
80
82
|
function withRequestDeadline(outer, timeoutMs) {
|
|
81
83
|
const controller = new AbortController();
|
|
82
84
|
let timedOut = false;
|
|
@@ -144,21 +146,25 @@ async function readBoundedText(res, what) {
|
|
|
144
146
|
async function requestJson(t, what, init) {
|
|
145
147
|
const doFetch = resolveFetch();
|
|
146
148
|
const deadline = withRequestDeadline(init.signal, init.timeoutMs);
|
|
149
|
+
const peerLabel = inlineUntrusted(t.peer, A2A_ID_MAX_CHARS);
|
|
147
150
|
try {
|
|
148
|
-
const
|
|
151
|
+
const followed = await fetchFollowing(doFetch, new URL(init.url), {
|
|
149
152
|
method: init.method,
|
|
150
|
-
signal: deadline.signal,
|
|
151
|
-
redirect: redirectPolicy(t.headers),
|
|
152
153
|
headers: underDeclaredHeaders({ accept: "application/json", "a2a-version": A2A_PROTOCOL_VERSION, ...(init.body !== undefined ? { "content-type": "application/json" } : {}) }, t.headers),
|
|
153
154
|
...(init.body !== undefined ? { body: init.body } : {}),
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
signal: deadline.signal,
|
|
156
|
+
}, { refusal: (url) => hopRefusal(url, t.floor, false), follows: () => !carriesDeclaredHeaders(t.headers), maxRedirects: A2A_MAX_REDIRECTS });
|
|
157
|
+
if (followed.kind === "refused")
|
|
158
|
+
throw Object.assign(new Error(`a2a: ${what} on peer "${peerLabel}" is not sent — ${followed.reason}`), { code: HOST_FLOOR_REFUSED_CODE });
|
|
159
|
+
if (followed.kind === "too_many")
|
|
160
|
+
throw new Error(`a2a: ${what} on peer "${peerLabel}" was redirected more than ${A2A_MAX_REDIRECTS} times`);
|
|
161
|
+
const res = followed.res;
|
|
162
|
+
const text = await readBoundedText(res, `${what} from A2A peer "${peerLabel}"`);
|
|
156
163
|
return { status: res.status, text };
|
|
157
164
|
}
|
|
158
165
|
catch (err) {
|
|
159
166
|
if (init.signal?.aborted === true)
|
|
160
167
|
throw err;
|
|
161
|
-
const peerLabel = inlineUntrusted(t.peer, A2A_ID_MAX_CHARS);
|
|
162
168
|
if (deadline.timedOut()) {
|
|
163
169
|
throw new Error(`a2a: ${what} on peer "${peerLabel}" got no answer within ${init.timeoutMs}ms. The client stopped waiting — the peer may still be acting on the request, so treat the outcome as UNKNOWN and verify before retrying.`, { cause: err });
|
|
164
170
|
}
|
|
@@ -553,16 +559,16 @@ function declaredPeerOf(declared, index) {
|
|
|
553
559
|
const judged = judgeEntryToolAxes(snapshot, "a2a");
|
|
554
560
|
return judged.ok ? { spec: judged.entry } : { spec: snapshot, refusal: judged.error };
|
|
555
561
|
}
|
|
556
|
-
async function materializePeer(peer, principal, lifecycle, signal) {
|
|
562
|
+
async function materializePeer(peer, principal, lifecycle, signal, floor) {
|
|
557
563
|
if ("refusal" in peer)
|
|
558
564
|
throw peer.refusal;
|
|
559
565
|
const { spec } = peer;
|
|
560
566
|
const declaredAxes = spec.toolAxes;
|
|
561
567
|
const headers = resolveProtocolHttpHeaders(A2A_NAMESPACE.id, spec, principal);
|
|
562
|
-
const discovery = { peer: spec.name, endpoint: spec.url, headers };
|
|
568
|
+
const discovery = { peer: spec.name, endpoint: spec.url, headers, floor };
|
|
563
569
|
const card = readCard(spec.name, await discoverCardBody(spec, discovery, signal), spec.url);
|
|
564
570
|
assertEndpointBound(A2A_NAMESPACE.id, spec.name, card.endpoint, spec.cardUrl === undefined ? [spec.url] : [spec.url, spec.cardUrl], headers);
|
|
565
|
-
const transport = { peer: spec.name, endpoint: card.endpoint, headers };
|
|
571
|
+
const transport = { peer: spec.name, endpoint: card.endpoint, headers, floor };
|
|
566
572
|
const tools = [];
|
|
567
573
|
const skillAxes = [];
|
|
568
574
|
for (const skill of card.skills) {
|
|
@@ -592,7 +598,7 @@ function asPeerWarning(spec, err) {
|
|
|
592
598
|
warning.code = "a2a.peer_unavailable";
|
|
593
599
|
return warning;
|
|
594
600
|
}
|
|
595
|
-
export async function materializeA2aTools(specs, principal, signal) {
|
|
601
|
+
export async function materializeA2aTools(specs, principal, signal, hostFloor) {
|
|
596
602
|
const peers = specs.map((spec, index) => declaredPeerOf(spec, index));
|
|
597
603
|
if (peers.length > 0) {
|
|
598
604
|
const collision = findNamespacePrefixCollision(A2A_NAMESPACE, peers.map((p) => p.spec.name));
|
|
@@ -610,7 +616,7 @@ export async function materializeA2aTools(specs, principal, signal) {
|
|
|
610
616
|
const toolAxes = [];
|
|
611
617
|
const warnings = [];
|
|
612
618
|
const statuses = [];
|
|
613
|
-
const settled = await Promise.allSettled(peers.map((peer) => materializePeer(peer, principal, lifecycle, signal)));
|
|
619
|
+
const settled = await Promise.allSettled(peers.map((peer) => materializePeer(peer, principal, lifecycle, signal, hostFloor)));
|
|
614
620
|
for (let i = 0; i < peers.length; i++) {
|
|
615
621
|
const spec = peers[i].spec;
|
|
616
622
|
const outcome = settled[i];
|
|
@@ -645,7 +651,7 @@ export async function materializeA2aTools(specs, principal, signal) {
|
|
|
645
651
|
}
|
|
646
652
|
const previous = statuses.find((s) => s.name === spec.name)?.toolNames ?? [];
|
|
647
653
|
try {
|
|
648
|
-
const fresh = await materializePeer(target, principal, lifecycle, signal);
|
|
654
|
+
const fresh = await materializePeer(target, principal, lifecycle, signal, hostFloor);
|
|
649
655
|
const names = fresh.tools.map((t) => t.name);
|
|
650
656
|
results.push({
|
|
651
657
|
peer: spec.name,
|
|
@@ -157,4 +157,14 @@ export interface SkillSpec {
|
|
|
157
157
|
* byte-identical result; a placeholder with no directory stays verbatim.
|
|
158
158
|
*/
|
|
159
159
|
baseDir?: string;
|
|
160
|
+
/**
|
|
161
|
+
* The hooks this skill carries — registrations on the mods bus (the `TaskSpec.mods` form: user tier, a name unique in the
|
|
162
|
+
* run), whose handlers take part only while the skill is ACTIVE on the leg that loads it: from its activation (the `Skill`
|
|
163
|
+
* tool's success, or prepare for a skill the person invoked by name; a resumed run reopens the skills its park recorded
|
|
164
|
+
* active) to the end of that run. A host compiles a frontmatter `hooks:` table into one such registration; the engine
|
|
165
|
+
* reads no hook grammar. Each hangs `classic.*` events only (any other event refuses the prepare, `config.mods_invalid`).
|
|
166
|
+
* They are admitted with the leg's other registrations at its prepare (so a skill never activated still counts as a hook
|
|
167
|
+
* the leg may run) and stay the leg's own: a delegated child neither dispatches them nor is screened by them.
|
|
168
|
+
*/
|
|
169
|
+
mods?: readonly import("./mods/classic-events.js").EngineModRegistration[];
|
|
160
170
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EditRewritten } from "./rewrite-rejudge.js";
|
|
1
2
|
import { type RuleToolNameVerdict } from "./tool-name-aliases.js";
|
|
2
3
|
import type { ToolCallRequest } from "./tool-policy.js";
|
|
3
4
|
import { type AllowRuleMember, type AllowRuleShadow } from "./allow-rule-shadow.js";
|
|
@@ -46,14 +47,15 @@ export type AllowEntryInert = {
|
|
|
46
47
|
readonly entry: string;
|
|
47
48
|
readonly reason: AllowEntryInertReason;
|
|
48
49
|
} & AllowEntryInertDetail;
|
|
49
|
-
/** One entry the grammar reads (kind closed): a whole non-shell tool; a
|
|
50
|
-
*
|
|
51
|
-
* the
|
|
50
|
+
/** One entry the grammar reads (kind closed): a whole non-shell tool; a covering spelling — a set of tool names
|
|
51
|
+
* ({@link isCoveringRuleName}: a protocol peer, a glob over a protocol name's tool segment, and on a deny list a `*` anywhere in
|
|
52
|
+
* the name, `*` alone every tool); the whole shell tool; and one kind per rule grammar (`ruleToolGrammarOf`) — a shell command
|
|
53
|
+
* rule, a path rule, a name rule, a host rule — each the row the persisted grammar parses, its `behavior` the list's direction. */
|
|
52
54
|
export type CompiledAllowEntry = {
|
|
53
55
|
readonly kind: "tool";
|
|
54
56
|
readonly name: string;
|
|
55
57
|
} | {
|
|
56
|
-
readonly kind: "
|
|
58
|
+
readonly kind: "covering";
|
|
57
59
|
readonly pattern: string;
|
|
58
60
|
} | {
|
|
59
61
|
readonly kind: "shell";
|
|
@@ -108,15 +110,13 @@ export type RuleEntryReading = {
|
|
|
108
110
|
* grammar alone is read — what a resume's pre-claim screen can read before the leg has a roster.
|
|
109
111
|
*/
|
|
110
112
|
export declare function readRuleEntry(raw: unknown, behavior: "allow" | "deny", roster?: ReadonlySet<string>): RuleEntryReading;
|
|
111
|
-
/** The tool name a compiled entry speaks for — its tool, its
|
|
113
|
+
/** The tool name a compiled entry speaks for — its tool, its covering spelling, or its rule's tool (what a name audit reads). */
|
|
112
114
|
export declare function compiledEntryName(compiled: CompiledAllowEntry): string;
|
|
113
115
|
/**
|
|
114
|
-
* Compile one list
|
|
115
|
-
* reason and, for a name the roster refuses, the judgment's word and the spelling to write).
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* `*` on a deny list reads as nothing by itself and the rest of that list still refuses: a deny list never loses an entry to
|
|
119
|
-
* a wildcard beside it. `roster` as in {@link readRuleEntry}.
|
|
116
|
+
* Compile one list through {@link readRuleEntry}, entry by entry: the entries it reads and the ones it reads as nothing (each
|
|
117
|
+
* with its reason and, for a name the roster refuses, the judgment's word and the spelling to write). No entry changes how
|
|
118
|
+
* another is read: a `*` on an allow list grants nothing by itself (`wildcard_all`) and the entries beside it keep their
|
|
119
|
+
* reading; on a deny list it refuses every tool. `roster` as in {@link readRuleEntry}.
|
|
120
120
|
*/
|
|
121
121
|
export declare function compileAllowList(entries: readonly string[], behavior: "allow" | "deny", roster?: ReadonlySet<string>): {
|
|
122
122
|
rows: Array<{
|
|
@@ -275,6 +275,10 @@ export declare function screenAllowedToolsValue(value: unknown, seat: AllowedToo
|
|
|
275
275
|
/** The disclosure record for one member, minted from the entries it matched: each sanitized (deployment or model-authored
|
|
276
276
|
* text on a human trust boundary) and capped, the rest counted. */
|
|
277
277
|
export declare function allowRuleShadowOf(member: AllowRuleMember, entries: readonly string[]): AllowRuleShadow;
|
|
278
|
+
/** A disclosure list with one more member's record folded in: ONE record per member — a member already disclosed gains the
|
|
279
|
+
* other record's entries after its own (every speaking, in reading order: two shown names that read alike are two speakers),
|
|
280
|
+
* the cap kept and the rest counted; any other member is appended. Records are minted values already ({@link allowRuleShadowOf}). */
|
|
281
|
+
export declare function withAllowRuleShadow(list: readonly AllowRuleShadow[], shadow: AllowRuleShadow): AllowRuleShadow[];
|
|
278
282
|
/** Read a disclosure value off a decision WITHOUT trusting it (a policy's own value, an ancestor's): every record a known
|
|
279
283
|
* member with a list of strings, or nothing — a display member must never throw where a card is minted. */
|
|
280
284
|
export declare function readAllowRuleShadows(value: unknown): readonly AllowRuleShadow[] | undefined;
|
|
@@ -325,8 +329,9 @@ export declare function allowRuleShadowSentence(shadows: readonly AllowRuleShado
|
|
|
325
329
|
authoredBy?: "deployment";
|
|
326
330
|
probeReason?: string;
|
|
327
331
|
}): string;
|
|
328
|
-
/** The card's
|
|
329
|
-
* sanitized records,
|
|
332
|
+
/** The card's disclosure members off a surviving ask, minted at every station that builds an approval request: the
|
|
333
|
+
* sanitized records, the message with the sentence rendered onto it, and the outlet of a person's rewritten edit (the
|
|
334
|
+
* approved-edit pass's own member, whose form is the bytes the card presents). */
|
|
330
335
|
export declare function cardDisclosureOf(decision: {
|
|
331
336
|
message?: string;
|
|
332
337
|
allowRuleShadowed?: unknown;
|
|
@@ -334,9 +339,11 @@ export declare function cardDisclosureOf(decision: {
|
|
|
334
339
|
mandate?: PersistedRuleMandate;
|
|
335
340
|
authoredBy?: "deployment";
|
|
336
341
|
probeReason?: string;
|
|
342
|
+
editRewritten?: EditRewritten;
|
|
337
343
|
}, fallbackMessage: string): {
|
|
338
344
|
message: string;
|
|
339
345
|
allowRuleShadowed?: readonly AllowRuleShadow[];
|
|
346
|
+
editRewritten?: EditRewritten;
|
|
340
347
|
};
|
|
341
348
|
/** The notice for list entries that grant (or refuse) nothing — one code for every list. */
|
|
342
349
|
export declare const ALLOWED_TOOL_NOT_GRANTED_CODE = "permission.allowed_tool_not_granted";
|