@sema-agent/core 7.54.1 → 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 +950 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +139 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +9 -8
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +65 -13
- package/dist/agents/peer-directory.js +90 -25
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +3 -2
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +37 -8
- package/dist/agents/subagent.d.ts +39 -82
- package/dist/agents/subagent.js +109 -106
- package/dist/agents/tool-filter.d.ts +31 -46
- package/dist/agents/tool-filter.js +13 -33
- package/dist/agents/verify.d.ts +6 -5
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +43 -81
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- 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 +6 -12
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +27 -35
- package/dist/brain/openai.js +30 -98
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +12 -12
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +62 -9
- package/dist/brain/request-params.js +42 -7
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +17 -8
- package/dist/core/allow-entry.d.ts +69 -36
- package/dist/core/allow-entry.js +81 -52
- package/dist/core/allow-rule-shadow.d.ts +10 -3
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +127 -29
- package/dist/core/ask-origin.js +87 -25
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +12 -7
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -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 +19 -4
- package/dist/core/checkpoint-requirements.js +8 -14
- package/dist/core/checkpoint-store.d.ts +165 -72
- package/dist/core/checkpoint-store.js +79 -82
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +11 -4
- package/dist/core/cross-boundary-taint.js +3 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +19 -19
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/effective-path-target.d.ts +1 -1
- 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 +45 -12
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +147 -21
- package/dist/core/file-history-store.js +58 -32
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -11
- package/dist/core/gate-lanes.js +81 -68
- package/dist/core/gate-outcome.d.ts +40 -6
- package/dist/core/gate-outcome.js +56 -0
- package/dist/core/governance-codes.d.ts +17 -3
- package/dist/core/governance-codes.js +16 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +21 -20
- 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 +84 -0
- package/dist/core/host-target.js +92 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +17 -13
- package/dist/core/mcp.js +240 -189
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/engine.d.ts +9 -9
- 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/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- 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 +44 -24
- package/dist/core/namespaced-rule-name.js +50 -43
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +13 -1
- package/dist/core/parent-spec-seat.js +6 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +30 -5
- package/dist/core/permission-rule-consent.js +147 -50
- package/dist/core/permission-rule-model.d.ts +245 -65
- package/dist/core/permission-rule-model.js +421 -107
- 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 +6 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +22 -26
- package/dist/core/permission-rule-store.js +12 -6
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +11 -3
- 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 +53 -15
- package/dist/core/permission-rules.js +125 -100
- package/dist/core/persisted-rule-arms.d.ts +6 -4
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/present-plan-tool.js +3 -1
- 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/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- 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 +34 -3
- package/dist/core/roles.js +66 -53
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +29 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +18 -26
- package/dist/core/runner/announce-once-ledger.js +19 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +2 -1
- 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 +21 -2
- package/dist/core/runner/caller-roster.js +38 -0
- 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 +33 -13
- package/dist/core/runner/classifier-ladder.js +15 -14
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +40 -33
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
- package/dist/core/runner/cross-boundary-lane.js +58 -34
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +4 -4
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- 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 +9 -3
- package/dist/core/runner/gate-exit.js +11 -5
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.js +38 -15
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +19 -8
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- 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 +5 -4
- package/dist/core/runner/prepare-config-doors.d.ts +31 -38
- package/dist/core/runner/prepare-config-doors.js +57 -34
- 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-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +41 -73
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
- package/dist/core/runner/prepare-gate-stations.js +12 -8
- 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 +11 -7
- package/dist/core/runner/prepare-inherited-gate.js +8 -6
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +12 -12
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
- package/dist/core/runner/prepare-policy-chain.js +68 -81
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- 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 +4 -6
- package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
- package/dist/core/runner/prepare-protocol-tools.js +5 -4
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -23
- 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 +41 -35
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
- 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 +11 -4
- 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/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +2 -1
- 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 -2
- 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-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +14 -7
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +43 -18
- package/dist/core/runner/run-settle-and-teardown.js +3 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +15 -22
- 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.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +17 -31
- 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/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -6
- package/dist/core/runner/synthetic-tools.d.ts +16 -13
- package/dist/core/runner/synthetic-tools.js +8 -3
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +3 -4
- 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-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- 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/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +91 -80
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +42 -42
- package/dist/core/runtime-caps.d.ts +4 -4
- 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 +26 -2
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- 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/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +102 -35
- package/dist/core/session-policy-store.js +210 -48
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +106 -37
- package/dist/core/session-store.js +165 -91
- package/dist/core/session.d.ts +101 -57
- package/dist/core/session.js +53 -0
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- 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.d.ts +10 -0
- package/dist/core/side-query.js +15 -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 +168 -3
- package/dist/core/store-contracts/file-history-store-contract.js +74 -4
- 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-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +176 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
- package/dist/core/store-contracts/session-store-contract.js +361 -51
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +42 -8
- package/dist/core/task-notification.d.ts +19 -15
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +13 -4
- package/dist/core/task-registry.js +14 -2
- package/dist/core/task-result.d.ts +21 -3
- package/dist/core/task-spec.d.ts +69 -64
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +36 -2
- package/dist/core/tool-catalog-entries.js +69 -43
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +22 -4
- package/dist/core/tool-name-readings.d.ts +10 -43
- package/dist/core/tool-name-readings.js +2 -11
- package/dist/core/tool-policy.d.ts +85 -196
- package/dist/core/tool-policy.js +150 -175
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +5 -1
- package/dist/core/tool-roster.d.ts +57 -33
- package/dist/core/tool-roster.js +56 -68
- package/dist/core/tool-spec-members.js +8 -3
- package/dist/core/tool-spec.d.ts +53 -31
- package/dist/core/tools.js +51 -10
- package/dist/core/trace.d.ts +6 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +58 -0
- package/dist/core/wiring-manifest.js +14 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +78 -2
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
- package/dist/engine/execution-env/node-execution-env.js +54 -24
- package/dist/engine/harness/agent-harness.d.ts +39 -9
- package/dist/engine/harness/agent-harness.js +87 -33
- package/dist/engine/harness/types.d.ts +58 -9
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +36 -19
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +23 -1
- package/dist/engine/loop/agent-loop.js +26 -34
- package/dist/engine/loop/types.d.ts +31 -19
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +18 -12
- package/dist/engine/session/memory-repo.js +24 -9
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +32 -3
- package/dist/engine/session/repo-utils.js +50 -5
- package/dist/index.d.ts +47 -23
- package/dist/index.js +35 -17
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +8 -6
- package/dist/orchestration/run-workflow-tool.js +10 -6
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +5 -13
- package/dist/orchestration/workflow.js +57 -49
- 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 +2 -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 +39 -2
- package/dist/prompt-assembly/tool-catalog.js +117 -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/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +15 -15
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +27 -33
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +9 -17
- package/dist/stores/file/checkpoint-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.js +45 -7
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +157 -141
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +18 -18
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +31 -18
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +54 -16
- package/dist/stores/file/session-store.js +114 -85
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +5 -3
- 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/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +8 -6
- 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/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- 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/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +18 -8
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +16 -6
- 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 +12 -20
- 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-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- 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/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +65 -64
- package/dist/tools/web.d.ts +20 -15
- package/dist/tools/web.js +55 -69
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5894 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type OffCapabilityModel, type ReasoningWireFacts } from "./reasoning.js";
|
|
2
|
+
/**
|
|
3
|
+
* THE reasoning WIRE applier — the one place that knows how a requested thinking tier is spelled on each
|
|
4
|
+
* wire family. The three brains (completions, Responses, Messages) build their requests through
|
|
5
|
+
* {@link applyReasoningToRequest}, and a host that sends its own request to one of those endpoints (a title
|
|
6
|
+
* generator, a side query) calls the same function with the same model entry, so the keys it puts on the wire
|
|
7
|
+
* are the keys the engine would have put there — nothing is re-spelled per caller.
|
|
8
|
+
*
|
|
9
|
+
* What is decided elsewhere and only READ here: whether the request carries thinking at all
|
|
10
|
+
* ({@link reasoningRequestCarried}), the tier clamp and the `thinkingLevelMap` translation
|
|
11
|
+
* ({@link mintEffortWireValue}), and whether "off" has a deployment-declared spelling ({@link declaredOffSpelling}).
|
|
12
|
+
*/
|
|
13
|
+
/** The tiers a request for the answer alone can ask for: `off` where the wire spells it, `low` where it cannot. */
|
|
14
|
+
export type ReasoningSeat = "off" | "low";
|
|
15
|
+
/**
|
|
16
|
+
* The lowest reasoning tier a request for the answer alone can take on this model's wire — one predicate: does the wire
|
|
17
|
+
* spell off ({@link thinkingOffSpelled})? Yes ⇒ `"off"`, and the output cap needs room for the answer only. No ⇒ `"low"`:
|
|
18
|
+
* a model whose thinking the wire cannot turn off is asked for the least it can grade, and the cap needs room for that
|
|
19
|
+
* thinking too — `AUTO_MODE_CLASSIFIER_LOW_REASONING_BUDGET_TOKENS` is the allowance the engine's own side requests add.
|
|
20
|
+
* A model that declares no reasoning is on the `low` seat as well: its wire carries nothing either way, so the request is
|
|
21
|
+
* the gateway's default, and a default-on gateway thinks.
|
|
22
|
+
*
|
|
23
|
+
* Callers pass the seat as `level` to {@link applyReasoningToRequest}; the classifier's seat tier is this verdict.
|
|
24
|
+
*/
|
|
25
|
+
export declare function lowestReasoningSeat(model: OffCapabilityModel): ReasoningSeat;
|
|
26
|
+
/** The model entry the applier reads. A `Model` satisfies it; `id` only names the model in a refusal. */
|
|
27
|
+
export interface ReasoningRequestModel extends OffCapabilityModel {
|
|
28
|
+
readonly id?: string;
|
|
29
|
+
}
|
|
30
|
+
/** The Messages-family knobs a host may set (the engine's own lane sets them from its construction config). */
|
|
31
|
+
export interface ReasoningBudgetKnobs {
|
|
32
|
+
/**
|
|
33
|
+
* Whether `body.max_tokens` is a bound the caller set. `true` (the default): the cap is never raised, and thinking
|
|
34
|
+
* is skipped when the cap cannot host a legal budget plus answer room. `false`: the cap is a default the lane
|
|
35
|
+
* raises to host one.
|
|
36
|
+
*/
|
|
37
|
+
capIsHard?: boolean;
|
|
38
|
+
/** The share of `max_tokens` the thinking budget takes; absent = the tier's own share. */
|
|
39
|
+
share?: number;
|
|
40
|
+
/** A fixed budget in tokens; overrides `share`. */
|
|
41
|
+
tokens?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface ApplyReasoningInput {
|
|
44
|
+
/**
|
|
45
|
+
* The wire family of the request: `"anthropic-messages"` (Messages), one of the Open Responses apis
|
|
46
|
+
* (`openai-responses`, `azure-openai-responses`, `openai-chatgpt-responses`), anything else = the chat-completions
|
|
47
|
+
* family, whose `model.compat.thinkingFormat` picks the dialect. A host passes the model entry's own `api`.
|
|
48
|
+
*/
|
|
49
|
+
api: string;
|
|
50
|
+
model: ReasoningRequestModel;
|
|
51
|
+
/** The requested tier. `"off"` is spelled where the wire has an off spelling; `undefined` and any value that is
|
|
52
|
+
* not a {@link ThinkingLevel} write nothing (the provider's default). */
|
|
53
|
+
level: string | undefined;
|
|
54
|
+
/** The request body so far. Never mutated — the result carries a copy. */
|
|
55
|
+
body: Readonly<Record<string, unknown>>;
|
|
56
|
+
/** Messages family only: a body with no numeric `max_tokens` is refused where the budget needs one. */
|
|
57
|
+
budget?: ReasoningBudgetKnobs;
|
|
58
|
+
}
|
|
59
|
+
export interface AppliedReasoning {
|
|
60
|
+
/** A copy of the input body with the thinking keys written (and, on Messages, `temperature` dropped when thinking is on). */
|
|
61
|
+
body: Record<string, unknown>;
|
|
62
|
+
/**
|
|
63
|
+
* The request headers the thinking keys need, to be folded into the request's own with
|
|
64
|
+
* {@link mergeReasoningHeaders}: the Messages family's `anthropic-beta` list (effort, context management,
|
|
65
|
+
* interleaved thinking — whichever the model entry declares). `{}` where the wire needs none.
|
|
66
|
+
*/
|
|
67
|
+
headers: Record<string, string>;
|
|
68
|
+
/** The effort value the request carries (completions `reasoning_effort`, Responses `reasoning.effort`), or `undefined`. */
|
|
69
|
+
effort: string | undefined;
|
|
70
|
+
/** Messages budget form only: the output-cap facts the thinking decision weighed (see {@link ReasoningWireFacts}). */
|
|
71
|
+
wireFacts: ReasoningWireFacts | undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Write the thinking keys a requested tier needs onto a request body, in the dialect of the model's wire family, and
|
|
75
|
+
* say which headers the keys need. A pure function of (api, model entry, level, body): the input body is not mutated,
|
|
76
|
+
* the result carries the body to send and the headers to fold into the request's own.
|
|
77
|
+
*
|
|
78
|
+
* It answers the question a host that builds its own request has — "which keys does THIS model take for THIS tier?" —
|
|
79
|
+
* from the same table the engine's brains read, so a host never keeps a copy of a dialect. Absence is meaningful:
|
|
80
|
+
* a model that does not declare `reasoning`, a `level` that is `undefined` or not a real tier, and a tier the wire
|
|
81
|
+
* cannot carry write nothing, and the provider's default governs.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* const { body, headers } = applyReasoningToRequest({ api: model.api, model, level: "low", body: { model: model.id, max_tokens: 2304, messages } });
|
|
85
|
+
* mergeReasoningHeaders(requestHeaders, headers);
|
|
86
|
+
*/
|
|
87
|
+
export declare function applyReasoningToRequest(input: ApplyReasoningInput): AppliedReasoning;
|
|
88
|
+
/**
|
|
89
|
+
* Fold the header patch {@link applyReasoningToRequest} returned into a request's headers, in place. A beta LIST
|
|
90
|
+
* (`anthropic-beta`) is unioned with whatever the request already sends under that name in any letter case and in any
|
|
91
|
+
* number of spellings (a spelling that holds no string contributes none and is claimed all the same) — the existing
|
|
92
|
+
* entries first, as given, then each new entry not already there, written under the lowercase name; any other name
|
|
93
|
+
* replaces its case variants. Assigning the patch over the headers instead would drop a beta the request already carries.
|
|
94
|
+
* This is the ONE reading of the beta list: the Messages brain folds its own header layers through it too.
|
|
95
|
+
*/
|
|
96
|
+
export declare function mergeReasoningHeaders(headers: Record<string, string>, patch: Readonly<Record<string, string>>): void;
|
|
@@ -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.
|
|
@@ -53,12 +53,12 @@ export declare const DEFAULT_EFFORT_LEVELS: readonly ThinkingLevel[];
|
|
|
53
53
|
* here so {@link resolveReasoning} can report ONE endpoint discriminant across both brain families.
|
|
54
54
|
*/
|
|
55
55
|
export type ReasoningFormat = "openai" | "openrouter" | "deepseek" | "together" | "zai" | "qwen" | "qwen-chat-template" | "budget"
|
|
56
|
-
/** Anthropic `output_config.effort` (
|
|
56
|
+
/** Anthropic `output_config.effort` (Fable-5 class, design/119): the tier is a named
|
|
57
57
|
* effort string, clamped to `compat.effortLevels` — the anthropic-side twin of the OpenAI
|
|
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") {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Model } from "../internal/llm.js";
|
|
1
2
|
/** OpenAI request-body keys core owns; `extraBody` cannot override these. */
|
|
2
3
|
export declare const OPENAI_RESERVED: ReadonlySet<string>;
|
|
3
4
|
/** Anthropic request-body keys core owns; `extraBody` cannot override these. (Note the asymmetry vs
|
|
@@ -13,17 +14,66 @@ export declare const ANTHROPIC_RESERVED: ReadonlySet<string>;
|
|
|
13
14
|
* wire and the drop announced, never a silently server-linked turn.
|
|
14
15
|
*/
|
|
15
16
|
export declare const RESPONSES_RESERVED: ReadonlySet<string>;
|
|
17
|
+
/** What {@link judgeExtraBody} refuses: the code, the one sentence, and (on `config.invalid_argument`) the member it names.
|
|
18
|
+
* Not an engine notice (a refusal is thrown, never delivered), so it carries none of a notice's members. */
|
|
19
|
+
export interface ExtraBodyRefusal {
|
|
20
|
+
readonly code: "config.invalid_argument" | "config.extra_body_output_cap";
|
|
21
|
+
readonly sentence: string;
|
|
22
|
+
readonly field?: "Model.extraBody";
|
|
23
|
+
}
|
|
16
24
|
/**
|
|
17
|
-
*
|
|
25
|
+
* {@link judgeExtraBody}'s answer: the refusal, or — admitted — the model's keys as ONE copy (`undefined` when the model
|
|
26
|
+
* carries no `extraBody` at all). The copy is what was judged, and it is what the merge walks: nothing is read from the
|
|
27
|
+
* object a second time.
|
|
28
|
+
*/
|
|
29
|
+
export type ExtraBodyVerdict = {
|
|
30
|
+
readonly refused: ExtraBodyRefusal;
|
|
31
|
+
readonly entries?: undefined;
|
|
32
|
+
} | {
|
|
33
|
+
readonly refused?: undefined;
|
|
34
|
+
readonly entries: ReadonlyArray<readonly [string, unknown]> | undefined;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* THE admission law for a model's `extraBody`, asked at both seats that can hand a request a model spec: the prepare step
|
|
38
|
+
* (the task's own model, before the session is acquired — a refused request never touches the session) and the request
|
|
39
|
+
* build ({@link applyExtraBody} — a model spec a host brain swapped in for one request, the compaction model, any other
|
|
40
|
+
* call of the leg). One judge, one sentence per refusal, whichever seat asks. Absent is admitted; otherwise the value must
|
|
41
|
+
* be a plain object of request-body keys, and it must not carry `max_completion_tokens`.
|
|
42
|
+
*
|
|
43
|
+
* The keys are read ONCE (`Object.entries`, one walk of the object): the refusal is decided on that copy and an admitted
|
|
44
|
+
* verdict hands the same copy to the merge, so an object that answers differently the second time it is asked (a getter, a
|
|
45
|
+
* Proxy trap) cannot pass one answer and send another.
|
|
46
|
+
*
|
|
47
|
+
* - A value that is not a plain object is refused as `config.invalid_argument` (`detail.field` = `Model.extraBody`). It is
|
|
48
|
+
* never read as keys: a string or an array would spread into the body as numbered keys, a number or `false` would be
|
|
49
|
+
* ignored without a word.
|
|
50
|
+
* - `max_completion_tokens` is refused as `config.extra_body_output_cap` on every wire: it is a spelling of the output cap, and
|
|
51
|
+
* the engine owns the output cap (it writes the per-request cap itself), so a cap is never taken from `extraBody` and the key
|
|
52
|
+
* is refused rather than stripped-and-announced like the keys in a wire's reserved set. On the OpenAI wire the spelling is
|
|
53
|
+
* also one the endpoint reads and the overflow retry lowers (stripping it would silently un-cap a deployment that used it as
|
|
54
|
+
* its only bound; passing it on would let a constant fight the retry); the other two wires' endpoints do not read it, and the
|
|
55
|
+
* refusal was never wire-dependent at the task's own model, so it is not made so here. (The sibling spelling `max_tokens` IS
|
|
56
|
+
* reserved: the adapter always writes it, so a stray copy never survives.)
|
|
57
|
+
*
|
|
58
|
+
* The sentence names the kind of a refused value and reads none of its members: it never echoes the value (an `extraBody`
|
|
59
|
+
* can hold a credential-bearing template).
|
|
60
|
+
*/
|
|
61
|
+
export declare function judgeExtraBody(extraBody: unknown, modelId: string): ExtraBodyVerdict;
|
|
62
|
+
/**
|
|
63
|
+
* Merge a model's `extraBody` into a brain's already-built request `body`, dropping any key the brain owns so core
|
|
18
64
|
* always wins. `body` is a NEW object (passthrough keys first, then core keys) when `extraBody` is set; the
|
|
19
65
|
* exact `body` reference (no allocation, byte-identical serialization) when it isn't — so an existing
|
|
20
66
|
* deployment with no `extraBody` is unaffected.
|
|
21
67
|
*
|
|
68
|
+
* The request seat of {@link judgeExtraBody}: an `extraBody` it refuses ends the build with a `BrainError`
|
|
69
|
+
* (`invalid_request`, the sentence led by the refusal's code — the shape a pre-flight route refusal has) before anything is
|
|
70
|
+
* merged or sent. The three wire adapters reach this function and nothing else; none of them judges the value itself.
|
|
71
|
+
*
|
|
22
72
|
* `dropped` is the keys of `extraBody` that were stripped, in `extraBody`'s insertion order, names only (a
|
|
23
73
|
* value never leaves this function except inside `body`). It is a property of the same walk that strips, so
|
|
24
74
|
* what is said and what is dropped cannot disagree; empty when nothing was stripped.
|
|
25
75
|
*/
|
|
26
|
-
export declare function applyExtraBody(body: Record<string, unknown>,
|
|
76
|
+
export declare function applyExtraBody(body: Record<string, unknown>, model: Pick<Model, "id" | "extraBody">, reserved: ReadonlySet<string>): {
|
|
27
77
|
body: Record<string, unknown>;
|
|
28
78
|
dropped: readonly string[];
|
|
29
79
|
};
|
|
@@ -72,12 +122,15 @@ export declare function applyExtraBody(body: Record<string, unknown>, extraBody:
|
|
|
72
122
|
export declare function lockHeader(headers: Record<string, string>, lowerName: string, value: string): void;
|
|
73
123
|
/**
|
|
74
124
|
* #343 (review r4) — case-fold READ-AND-CLAIM for an AUGMENTABLE structural header (`anthropic-beta`):
|
|
75
|
-
* returns the
|
|
76
|
-
*
|
|
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
|
|
77
127
|
* read-modify-write used to key the read by the exact lowercase name and miss `Anthropic-Beta`,
|
|
78
|
-
* 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.
|
|
79
130
|
*/
|
|
80
|
-
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[];
|
|
81
134
|
/** A caller's header bag read ONCE, into a plain copy of its own enumerable entries — what a request build hands both
|
|
82
135
|
* the route law (which credential rides, and its identity) and the merge (what goes on the wire), so a bag whose getters
|
|
83
136
|
* or keys answer differently on a second read cannot be judged as one bag and sent as another. */
|
|
@@ -94,8 +147,8 @@ export declare const OUTPUT_CAP_KEYS: Readonly<Record<"openai" | "anthropic" | "
|
|
|
94
147
|
* of the lane's cap keys that is present and usable, or `undefined` when none is.
|
|
95
148
|
*
|
|
96
149
|
* Read off the merged body rather than off the knob the adapter set, because those are not the same
|
|
97
|
-
* thing:
|
|
98
|
-
*
|
|
99
|
-
*
|
|
150
|
+
* thing: what is on the wire is the only cap the provider enforces, and the adapter's own number can differ
|
|
151
|
+
* from it (the Anthropic lane raises `max_tokens` to fit a thinking budget). Smallest wins so a consumer
|
|
152
|
+
* reasoning about the bound stays conservative.
|
|
100
153
|
*/
|
|
101
154
|
export declare function effectiveOutputCap(body: Record<string, unknown>, keys: readonly string[]): number | undefined;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { isCredentialHeaderName } from "../core/secret-env.js";
|
|
2
|
+
import { isPlainRecord } from "../core/mods/kernel/receive.js";
|
|
3
|
+
import { BrainError } from "./errors.js";
|
|
2
4
|
export const OPENAI_RESERVED = new Set([
|
|
3
5
|
"model",
|
|
4
6
|
"messages",
|
|
@@ -40,12 +42,42 @@ export const RESPONSES_RESERVED = new Set([
|
|
|
40
42
|
"conversation",
|
|
41
43
|
]);
|
|
42
44
|
const NO_KEYS = Object.freeze([]);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
const extraBodyKind = (v) => (v === null ? "null" : Array.isArray(v) ? "an array" : typeof v === "object" ? "an object that is not plain (a class instance, a Map, …)" : `a ${typeof v}`);
|
|
46
|
+
export function judgeExtraBody(extraBody, modelId) {
|
|
47
|
+
if (extraBody === undefined)
|
|
48
|
+
return { entries: undefined };
|
|
49
|
+
const whose = `Model.extraBody of model ${JSON.stringify(modelId)}`;
|
|
50
|
+
if (!isPlainRecord(extraBody)) {
|
|
51
|
+
return {
|
|
52
|
+
refused: {
|
|
53
|
+
code: "config.invalid_argument",
|
|
54
|
+
field: "Model.extraBody",
|
|
55
|
+
sentence: `${whose} is ${extraBodyKind(extraBody)} — it must be a plain object of request-body keys, or absent; any other value is refused rather than spread into the request body as numbered keys or left out without a word. Write a plain object, or remove it.`,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const entries = Object.entries(extraBody);
|
|
60
|
+
if (entries.some(([k]) => k === "max_completion_tokens")) {
|
|
61
|
+
return {
|
|
62
|
+
refused: {
|
|
63
|
+
code: "config.extra_body_output_cap",
|
|
64
|
+
sentence: `${whose} supplies "max_completion_tokens" — an output-cap spelling the engine owns: it writes the per-request cap ` +
|
|
65
|
+
`itself, so a cap is never taken from extraBody. Set it via limits.maxOutputTokens (per request) or Model.maxTokens; ` +
|
|
66
|
+
`on the OpenAI wire Model.compat.maxTokensField picks the spelling.`,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { entries };
|
|
71
|
+
}
|
|
72
|
+
export function applyExtraBody(body, model, reserved) {
|
|
73
|
+
const verdict = judgeExtraBody(model.extraBody, model.id);
|
|
74
|
+
if (verdict.refused !== undefined)
|
|
75
|
+
throw new BrainError("invalid_request", `${verdict.refused.code}: ${verdict.refused.sentence}`);
|
|
76
|
+
if (verdict.entries === undefined)
|
|
45
77
|
return { body, dropped: NO_KEYS };
|
|
46
78
|
const passthrough = {};
|
|
47
79
|
const dropped = [];
|
|
48
|
-
for (const [k, v] of
|
|
80
|
+
for (const [k, v] of verdict.entries) {
|
|
49
81
|
if (reserved.has(k))
|
|
50
82
|
dropped.push(k);
|
|
51
83
|
else
|
|
@@ -60,15 +92,18 @@ export function lockHeader(headers, lowerName, value) {
|
|
|
60
92
|
}
|
|
61
93
|
headers[lowerName] = value;
|
|
62
94
|
}
|
|
63
|
-
export function
|
|
95
|
+
export function takeHeaderSpellings(headers, lowerName) {
|
|
96
|
+
const values = [];
|
|
64
97
|
for (const k of Object.keys(headers)) {
|
|
65
98
|
if (k.toLowerCase() === lowerName) {
|
|
66
|
-
|
|
99
|
+
values.push(headers[k]);
|
|
67
100
|
delete headers[k];
|
|
68
|
-
return v;
|
|
69
101
|
}
|
|
70
102
|
}
|
|
71
|
-
return
|
|
103
|
+
return values;
|
|
104
|
+
}
|
|
105
|
+
export function headerListEntries(value) {
|
|
106
|
+
return typeof value === "string" ? value.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "") : [];
|
|
72
107
|
}
|
|
73
108
|
export function headerBagOnce(bag) {
|
|
74
109
|
return bag === undefined ? undefined : { ...bag };
|
package/dist/brain/retry.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Transient-failure retry backoff (RB-420-b
|
|
2
|
+
* Transient-failure retry backoff (RB-420-b).
|
|
3
3
|
*
|
|
4
4
|
* The shape is **increasing exponential + light additive jitter**, not full jitter:
|
|
5
5
|
* `min(base * 2^attempt, 32s)` plus up to 25% of that. Full jitter (`random(0, exp)`) made the Nth
|
|
@@ -375,3 +375,18 @@ export declare function unroutableSeatNotice(args: {
|
|
|
375
375
|
sessionId?: string;
|
|
376
376
|
runId?: string;
|
|
377
377
|
}): EngineNotice;
|
|
378
|
+
/**
|
|
379
|
+
* The third twin, for a seat with nothing to fall back TO and nothing worth keeping (the advisor tool: serving it with
|
|
380
|
+
* the primary model would advise the agent with itself, and keeping it would refuse every call the model makes): the
|
|
381
|
+
* pairing is broken, so the seat is DETACHED for this run — not mounted, no model swapped. Same `detail` keys as
|
|
382
|
+
* {@link unroutableSeatNotice}; `action: "detached"` is the discriminator.
|
|
383
|
+
*/
|
|
384
|
+
export declare function seatDetachedNotice(args: {
|
|
385
|
+
seat: string;
|
|
386
|
+
from: string;
|
|
387
|
+
verdict: Extract<RouteAdjudication, {
|
|
388
|
+
ok: false;
|
|
389
|
+
}>;
|
|
390
|
+
sessionId?: string;
|
|
391
|
+
runId?: string;
|
|
392
|
+
}): EngineNotice;
|
|
@@ -531,3 +531,18 @@ export function unroutableSeatNotice(args) {
|
|
|
531
531
|
},
|
|
532
532
|
};
|
|
533
533
|
}
|
|
534
|
+
export function seatDetachedNotice(args) {
|
|
535
|
+
return {
|
|
536
|
+
code: "route.seat_detached",
|
|
537
|
+
message: `derived model "${args.from}" (${args.seat}) is not routable (${args.verdict.code}) — the seat is detached for this run and nothing serves it in its place. ${args.verdict.detail.fixHint}`,
|
|
538
|
+
detail: {
|
|
539
|
+
seat: args.seat,
|
|
540
|
+
from: args.from,
|
|
541
|
+
cause: args.verdict.code,
|
|
542
|
+
fixHint: args.verdict.detail.fixHint,
|
|
543
|
+
action: "detached",
|
|
544
|
+
...(args.sessionId !== undefined ? { sessionId: args.sessionId } : {}),
|
|
545
|
+
...(args.runId !== undefined ? { runId: args.runId } : {}),
|
|
546
|
+
},
|
|
547
|
+
};
|
|
548
|
+
}
|