@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
|
@@ -7,15 +7,26 @@
|
|
|
7
7
|
* sentence that drifts is a string consumers grep for.
|
|
8
8
|
*/
|
|
9
9
|
import type { Model } from "../internal/llm.js";
|
|
10
|
+
import { type CapabilityDeclaration } from "./model-capability.js";
|
|
11
|
+
/** Why a request's images are withheld from the SERVING model: the entry's image declaration, when it is not held
|
|
12
|
+
* (the withheld-capability report's `cause`, `status-sink.ts`). */
|
|
13
|
+
export type ImageWithholdCause = Exclude<CapabilityDeclaration, "declared_on">;
|
|
14
|
+
/** A request whose images are withheld: which model, and why. */
|
|
15
|
+
export interface ImageWithhold {
|
|
16
|
+
readonly modelId: string;
|
|
17
|
+
readonly cause: ImageWithholdCause;
|
|
18
|
+
}
|
|
10
19
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* gets the placeholder path — the case a text-only API rejects with a hard 400 on an image part.
|
|
20
|
+
* The image row of the capability table for one request: `undefined` = images ride as images; otherwise the model and
|
|
21
|
+
* the declaration that withholds them. Read off the one capability reading (`capabilityHeld` / `capabilityOf`), so an
|
|
22
|
+
* entry that never declared `input` gets its images exactly as the table says, and an entry that declares a list without
|
|
23
|
+
* `"image"` gets the placeholder path — the case a text-only API rejects with a hard 400 on an image part. No model =
|
|
24
|
+
* images ride.
|
|
17
25
|
*/
|
|
18
|
-
export declare function
|
|
26
|
+
export declare function imageWithholdOf(model?: Model): ImageWithhold | undefined;
|
|
27
|
+
/** Report `count` images of one request replaced by placeholders — the one emit for every lane: the operator trace frame
|
|
28
|
+
* (telemetry, per request) and the leg's withheld-capability account (the person's notice, once per conversation). */
|
|
29
|
+
export declare function reportImagesWithheld(withhold: ImageWithhold, count: number): void;
|
|
19
30
|
/** Placeholder for an image block dropped because the serving model declares no image input. */
|
|
20
31
|
export declare const IMAGE_OMITTED_NO_VISION = "[image omitted: the serving model does not support image input]";
|
|
21
32
|
/** {@link IMAGE_OMITTED_NO_VISION}, counted — a batch of dropped images states how many were lost. */
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { capabilityHeld, capabilityOf } from "./model-capability.js";
|
|
2
|
+
import { emitBrainTelemetry, reportCapabilityWithheld } from "./status-sink.js";
|
|
3
|
+
export function imageWithholdOf(model) {
|
|
4
|
+
if (model === undefined)
|
|
5
|
+
return undefined;
|
|
6
|
+
const declared = capabilityOf(model, "image");
|
|
7
|
+
return declared === "declared_on" || capabilityHeld(model, "image") ? undefined : { modelId: model.id, cause: declared };
|
|
8
|
+
}
|
|
9
|
+
export function reportImagesWithheld(withhold, count) {
|
|
10
|
+
if (count === 0)
|
|
11
|
+
return;
|
|
12
|
+
emitBrainTelemetry({ kind: "vision_placeholder", count });
|
|
13
|
+
reportCapabilityWithheld({ modelId: withhold.modelId, capability: "image", cause: withhold.cause, count });
|
|
3
14
|
}
|
|
4
15
|
export const IMAGE_OMITTED_NO_VISION = "[image omitted: the serving model does not support image input]";
|
|
5
16
|
export function imagesOmittedNoVisionNote(count) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE reading of a model's capability declarations — image input and reasoning.
|
|
3
|
+
*
|
|
4
|
+
* A `Model` declares each capability in one of three states: on (`reasoning: true`; `input` lists `"image"`), off
|
|
5
|
+
* (`reasoning: false`; an `input` list without `"image"`), or not at all (the key is absent). Every reader in the engine
|
|
6
|
+
* (bar the PDF profile's no-metadata shortcut in `pdfModelCapabilitiesOf`, which looks at the absence itself) asks {@link capabilityOf} for the declaration, or {@link capabilityHeld} for "does the engine treat this model as
|
|
7
|
+
* having it", and what an undeclared capability means is stated once, in {@link UNKNOWN_CAPABILITY_READS} — no caller
|
|
8
|
+
* decides it for itself. A request never carries a capability declared off; one declared on is never dropped here.
|
|
9
|
+
*
|
|
10
|
+
* A declaration of the wrong shape is refused where it is read: a `reasoning` that is not a boolean, or an `input` that
|
|
11
|
+
* is not a list of strings, throws, naming the model and the key. Reading it some other way (by truthiness, or as
|
|
12
|
+
* undeclared) would turn a typo into a capability nobody declared.
|
|
13
|
+
*/
|
|
14
|
+
import type { Model } from "../internal/llm.js";
|
|
15
|
+
/** The capabilities a model declares. `image` = accepts image input (`Model.input` lists `"image"`). */
|
|
16
|
+
export declare const MODEL_CAPABILITIES: readonly ["image", "reasoning"];
|
|
17
|
+
export type ModelCapability = (typeof MODEL_CAPABILITIES)[number];
|
|
18
|
+
/** What a model's entry says about one capability. `unknown` = the entry does not say. */
|
|
19
|
+
export declare const CAPABILITY_DECLARATIONS: readonly ["declared_on", "declared_off", "unknown"];
|
|
20
|
+
export type CapabilityDeclaration = (typeof CAPABILITY_DECLARATIONS)[number];
|
|
21
|
+
/**
|
|
22
|
+
* What the engine does with a capability the entry does not declare, per capability — the only place this is said.
|
|
23
|
+
* Image input is used (an entry that never filled in `input` keeps the images it was always sent). Reasoning is not:
|
|
24
|
+
* no thinking keys go out for an entry that does not declare `reasoning` (the request is the provider's default).
|
|
25
|
+
*/
|
|
26
|
+
export declare const UNKNOWN_CAPABILITY_READS: Readonly<Record<ModelCapability, "held" | "not_held">>;
|
|
27
|
+
/** The part of a model this module reads (`id` only names the model in a refusal; the structural readers that take a
|
|
28
|
+
* model-shaped object without one still get the same answer). */
|
|
29
|
+
export type CapabilityDeclaringModel = {
|
|
30
|
+
readonly id?: Model["id"];
|
|
31
|
+
readonly reasoning?: unknown;
|
|
32
|
+
readonly input?: unknown;
|
|
33
|
+
};
|
|
34
|
+
/** The entry's declaration of `cap`. Throws a `TypeError` on a declaration of the wrong shape (see the module note). */
|
|
35
|
+
export declare function capabilityOf(model: CapabilityDeclaringModel, cap: ModelCapability): CapabilityDeclaration;
|
|
36
|
+
/** Whether the engine treats the model as having `cap`: declared on, or undeclared where {@link UNKNOWN_CAPABILITY_READS} says held. */
|
|
37
|
+
export declare function capabilityHeld(model: CapabilityDeclaringModel, cap: ModelCapability): boolean;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const MODEL_CAPABILITIES = Object.freeze(["image", "reasoning"]);
|
|
2
|
+
export const CAPABILITY_DECLARATIONS = Object.freeze(["declared_on", "declared_off", "unknown"]);
|
|
3
|
+
export const UNKNOWN_CAPABILITY_READS = Object.freeze({
|
|
4
|
+
image: "held",
|
|
5
|
+
reasoning: "not_held",
|
|
6
|
+
});
|
|
7
|
+
function typeWordOf(value) {
|
|
8
|
+
return value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
|
|
9
|
+
}
|
|
10
|
+
function nameOf(model) {
|
|
11
|
+
return typeof model.id === "string" ? `"${model.id}"` : "a model with no id";
|
|
12
|
+
}
|
|
13
|
+
export function capabilityOf(model, cap) {
|
|
14
|
+
if (cap === "reasoning") {
|
|
15
|
+
const declared = model.reasoning;
|
|
16
|
+
if (declared === undefined)
|
|
17
|
+
return "unknown";
|
|
18
|
+
if (typeof declared !== "boolean") {
|
|
19
|
+
throw new TypeError(`Model.reasoning of ${nameOf(model)} must be true, false or absent; got ${typeWordOf(declared)}`);
|
|
20
|
+
}
|
|
21
|
+
return declared ? "declared_on" : "declared_off";
|
|
22
|
+
}
|
|
23
|
+
const input = model.input;
|
|
24
|
+
if (input === undefined)
|
|
25
|
+
return "unknown";
|
|
26
|
+
if (!Array.isArray(input) || !input.every((m) => typeof m === "string")) {
|
|
27
|
+
throw new TypeError(`Model.input of ${nameOf(model)} must be a list of input kinds or absent; got ${Array.isArray(input) ? "a list holding a non-string" : typeWordOf(input)}`);
|
|
28
|
+
}
|
|
29
|
+
return input.includes("image") ? "declared_on" : "declared_off";
|
|
30
|
+
}
|
|
31
|
+
export function capabilityHeld(model, cap) {
|
|
32
|
+
const declared = capabilityOf(model, cap);
|
|
33
|
+
return declared === "declared_on" || (declared === "unknown" && UNKNOWN_CAPABILITY_READS[cap] === "held");
|
|
34
|
+
}
|
|
@@ -19,16 +19,10 @@ import type { AnthropicMessagesCompat, Model } from "../internal/llm.js";
|
|
|
19
19
|
* - `supportsTemperature: false` — CC never sends temperature to this class, thinking on OR off.
|
|
20
20
|
*/
|
|
21
21
|
export declare const FABLE_5_COMPAT: AnthropicMessagesCompat;
|
|
22
|
-
/**
|
|
23
|
-
* The fable lines the classic prompt shape serves. They are prompt text, so they live with the prompt
|
|
24
|
-
* text; this name stays exported for hosts that read them. The preset below no longer carries them as
|
|
25
|
-
* `promptGuidance`: the prompt composes them itself, once, where they are the only fable text.
|
|
26
|
-
*/
|
|
27
|
-
export declare const FABLE_5_PROMPT_GUIDANCE: readonly string[];
|
|
28
22
|
/**
|
|
29
23
|
* A ready-to-use `claude-fable-5` {@link Model} (registry facts: 1M-token native context
|
|
30
24
|
* window, 64k default max output — the 128k tier is opt-in via `maxTokens` override, knowledge
|
|
31
|
-
* cutoff Jan 2026, `default_effort: "high"
|
|
32
|
-
* accounting (not baked — see module note).
|
|
25
|
+
* cutoff Jan 2026, `default_effort: "high"`, prompt capabilities `lean_prompt` + `fable_5_mitigations`).
|
|
26
|
+
* Override anything per deployment; set `cost` for accounting (not baked — see module note).
|
|
33
27
|
*/
|
|
34
28
|
export declare function fable5Model(overrides?: Partial<Model>): Model;
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import { catalogText } from "../prompt-assembly/catalog/index.js";
|
|
2
1
|
import { ANTHROPIC_DEFAULT_BASE_URL } from "./anthropic.js";
|
|
3
2
|
export const FABLE_5_COMPAT = {
|
|
4
3
|
thinkingMode: "adaptive",
|
|
5
4
|
effortLevels: ["low", "medium", "high", "xhigh", "max"],
|
|
6
5
|
supportsTemperature: false,
|
|
7
6
|
};
|
|
8
|
-
export const FABLE_5_PROMPT_GUIDANCE = [
|
|
9
|
-
catalogText("core/behavior.fable-classic.final-message"),
|
|
10
|
-
catalogText("core/behavior.fable-classic.autonomy"),
|
|
11
|
-
catalogText("core/behavior.fable-classic.tool-json"),
|
|
12
|
-
];
|
|
13
7
|
export function fable5Model(overrides = {}) {
|
|
14
8
|
return {
|
|
15
9
|
id: "claude-fable-5",
|
|
@@ -25,6 +19,7 @@ export function fable5Model(overrides = {}) {
|
|
|
25
19
|
maxTokens: 64_000,
|
|
26
20
|
charsPerToken: 3,
|
|
27
21
|
compat: { ...FABLE_5_COMPAT },
|
|
22
|
+
promptTraits: ["lean_prompt", "fable_5_mitigations"],
|
|
28
23
|
...overrides,
|
|
29
24
|
};
|
|
30
25
|
}
|
|
@@ -4,12 +4,12 @@ import { DEGENERATE_MESSAGE, trimDegenerateTail } from "./repetition.js";
|
|
|
4
4
|
import { STREAM_TORN_WARNING, createRepetitionPoll, modelOutputInvalidOf, noteResponseModel, nameMissingCause, parseStreamedToolArgs, placeTurnNotes } from "./stream-shared.js";
|
|
5
5
|
import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCallIds } from "./tool-call-id.js";
|
|
6
6
|
import { emitBrainTelemetry } from "./status-sink.js";
|
|
7
|
-
import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imagesOmittedNoVisionNote,
|
|
7
|
+
import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imageWithholdOf, imagesOmittedNoVisionNote, reportImagesWithheld, sendableImages } from "./media-degrade.js";
|
|
8
8
|
import { OUTPUT_CAP_KEYS, RESPONSES_RESERVED, applyExtraBody, effectiveOutputCap, headerBagOnce, lockHeader, mergeHeaders } from "./request-params.js";
|
|
9
9
|
import { admitRouteRequest, applyRouteCredentialHeaders, assertServableRequestRoot, brainConfigSnapshot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential } from "./route-adjudicator.js";
|
|
10
10
|
import { requestRouteOf } from "./request-route.js";
|
|
11
11
|
import { NAMES_AS_WRITTEN, resolveProviderDialect, endpointToolNames } from "./provider-dialect.js";
|
|
12
|
-
import {
|
|
12
|
+
import { applyReasoningToRequest } from "./reasoning-request.js";
|
|
13
13
|
import { runStreamingBrain } from "./stream-engine.js";
|
|
14
14
|
import { refuseRetiredTimeoutKnobs } from "./timeout.js";
|
|
15
15
|
import { resolveFetch } from "./transport.js";
|
|
@@ -18,9 +18,6 @@ const DEGENERATE_POLL_CHARS = 64;
|
|
|
18
18
|
const MALFORMED_SAMPLE_CHARS = 160;
|
|
19
19
|
const MALFORMED_ARGS_CHARS = 200;
|
|
20
20
|
const CAPABILITY_DIAGNOSTIC_TYPE = "responses_capability";
|
|
21
|
-
function responsesCompat(model) {
|
|
22
|
-
return (model.compat ?? {});
|
|
23
|
-
}
|
|
24
21
|
const NO_CONTENT = "(no content)";
|
|
25
22
|
const DOCUMENT_OMITTED = "[PDF document omitted: PDF direct read requires an Anthropic-family model; re-Read the file (the engine will extract text/render pages when possible) or extract the text via Bash instead (e.g. `pdftotext`).]";
|
|
26
23
|
function textOf(content) {
|
|
@@ -38,16 +35,17 @@ function functionCallOutputText(text, hasCarriedImages, original) {
|
|
|
38
35
|
return "(image attached below)";
|
|
39
36
|
return Array.isArray(original) && original.length > 0 ? "(non-text tool result omitted)" : "";
|
|
40
37
|
}
|
|
41
|
-
function toUserParts(content,
|
|
38
|
+
function toUserParts(content, withhold) {
|
|
42
39
|
if (typeof content === "string") {
|
|
43
40
|
return content === "" ? [] : [{ type: "input_text", text: content }];
|
|
44
41
|
}
|
|
42
|
+
const supportsVision = withhold === undefined;
|
|
45
43
|
const nDocs = content.filter((c) => c.type === "document").length;
|
|
46
44
|
if (nDocs > 0)
|
|
47
45
|
emitBrainTelemetry({ kind: "document_placeholder", count: nDocs });
|
|
48
46
|
const images = content.filter((c) => c.type === "image" && c.data !== undefined && c.mimeType !== undefined);
|
|
49
|
-
if (
|
|
50
|
-
|
|
47
|
+
if (withhold !== undefined)
|
|
48
|
+
reportImagesWithheld(withhold, images.length);
|
|
51
49
|
const parts = [];
|
|
52
50
|
for (const c of content) {
|
|
53
51
|
if (c.type === "text" && typeof c.text === "string" && c.text.length > 0) {
|
|
@@ -66,7 +64,8 @@ function toUserParts(content, supportsVision) {
|
|
|
66
64
|
return parts;
|
|
67
65
|
}
|
|
68
66
|
function toResponsesInput(ctx, model, replayReasoning, toolNames) {
|
|
69
|
-
const
|
|
67
|
+
const imageWithhold = imageWithholdOf(model);
|
|
68
|
+
const supportsVision = imageWithhold === undefined;
|
|
70
69
|
const out = [];
|
|
71
70
|
let pendingImages = [];
|
|
72
71
|
const flushImages = () => {
|
|
@@ -88,7 +87,7 @@ function toResponsesInput(ctx, model, replayReasoning, toolNames) {
|
|
|
88
87
|
if (m.role !== "toolResult")
|
|
89
88
|
flushImages();
|
|
90
89
|
if (m.role === "user") {
|
|
91
|
-
const parts = toUserParts(m.content,
|
|
90
|
+
const parts = toUserParts(m.content, imageWithhold);
|
|
92
91
|
out.push({
|
|
93
92
|
type: "message",
|
|
94
93
|
role: "user",
|
|
@@ -124,8 +123,8 @@ function toResponsesInput(ctx, model, replayReasoning, toolNames) {
|
|
|
124
123
|
const mediaImages = sendableImages(Array.isArray(m.content) ? m.content : []);
|
|
125
124
|
const rawImages = m.isError ? [] : mediaImages;
|
|
126
125
|
const images = supportsVision ? rawImages : [];
|
|
127
|
-
if (
|
|
128
|
-
|
|
126
|
+
if (imageWithhold !== undefined)
|
|
127
|
+
reportImagesWithheld(imageWithhold, rawImages.length);
|
|
129
128
|
const nDocs = Array.isArray(m.content) ? m.content.filter((c) => c.type === "document").length : 0;
|
|
130
129
|
if (nDocs > 0)
|
|
131
130
|
emitBrainTelemetry({ kind: "document_placeholder", count: nDocs });
|
|
@@ -157,16 +156,6 @@ function toResponsesTools(ctx, toolNames) {
|
|
|
157
156
|
strict: false,
|
|
158
157
|
}));
|
|
159
158
|
}
|
|
160
|
-
function resolveWireEffort(model, reasoning) {
|
|
161
|
-
if (model.reasoning && reasoning === "off")
|
|
162
|
-
return declaredOffSpelling(model);
|
|
163
|
-
const compat = responsesCompat(model);
|
|
164
|
-
if (compat.supportsReasoningEffort === false)
|
|
165
|
-
return undefined;
|
|
166
|
-
if (!reasoningRequestCarried(model, reasoning))
|
|
167
|
-
return undefined;
|
|
168
|
-
return mintEffortWireValue(reasoning, model, compat.reasoningEffortLevels).wireValue;
|
|
169
|
-
}
|
|
170
159
|
function computeUsage(model, raw) {
|
|
171
160
|
const input = raw?.input_tokens ?? 0;
|
|
172
161
|
const output = raw?.output_tokens ?? 0;
|
|
@@ -266,7 +255,6 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
266
255
|
"remove it, or serve this model through the chat-completions lane, which does support it");
|
|
267
256
|
}
|
|
268
257
|
const requestedMaxTokens = overrides?.maxOutputTokens ?? options?.maxTokens ?? model.maxTokens;
|
|
269
|
-
const effort = resolveWireEffort(model, options?.reasoning);
|
|
270
258
|
const body = {
|
|
271
259
|
model: model.id,
|
|
272
260
|
input: toResponsesInput(context, model, config.replayReasoning !== false, builtToolNames),
|
|
@@ -290,14 +278,13 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
290
278
|
builtMaxTokens = undefined;
|
|
291
279
|
builtMaxTokensLane = "unset";
|
|
292
280
|
}
|
|
293
|
-
|
|
294
|
-
body.reasoning = { effort };
|
|
281
|
+
const { body: reasoningBody, effort } = applyReasoningToRequest({ api: "openai-responses", model, level: options?.reasoning, body });
|
|
295
282
|
const headers = mergeHeaders(modelHeaders, config.headers, optionsHeaders);
|
|
296
283
|
applyRouteCredentialHeaders(headers, routeCredential);
|
|
297
284
|
lockHeader(headers, "content-type", "application/json");
|
|
298
285
|
if (apiKey)
|
|
299
286
|
lockHeader(headers, OPEN_RESPONSES_KEY_HEADER, `Bearer ${apiKey}`);
|
|
300
|
-
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(
|
|
287
|
+
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(reasoningBody, model, RESPONSES_RESERVED);
|
|
301
288
|
return {
|
|
302
289
|
url,
|
|
303
290
|
headers,
|
package/dist/brain/openai.js
CHANGED
|
@@ -4,13 +4,14 @@ import { DEGENERATE_MESSAGE, trimDegenerateTail } from "./repetition.js";
|
|
|
4
4
|
import { STREAM_TORN_WARNING, createRepetitionPoll, createStreamEndLedger, echoFoldedWord, modelOutputInvalidOf, noteResponseModel, nameMissingCause, parseStreamedToolArgs, placeTurnNotes, truncationCauseClause } from "./stream-shared.js";
|
|
5
5
|
import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCallIds } from "./tool-call-id.js";
|
|
6
6
|
import { emitBrainTelemetry } from "./status-sink.js";
|
|
7
|
-
import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imagesOmittedNoVisionNote,
|
|
7
|
+
import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imageWithholdOf, imagesOmittedNoVisionNote, reportImagesWithheld, sendableImages } from "./media-degrade.js";
|
|
8
|
+
import { capabilityHeld } from "./model-capability.js";
|
|
8
9
|
import { OPENAI_RESERVED, OUTPUT_CAP_KEYS, applyExtraBody, effectiveOutputCap, headerBagOnce, lockHeader, mergeHeaders } from "./request-params.js";
|
|
9
10
|
import { BrainError, providerErrorWord } from "./errors.js";
|
|
10
11
|
import { NAMES_AS_WRITTEN, inBandProviderError, resolveProviderDialect, endpointToolNames } from "./provider-dialect.js";
|
|
11
12
|
import { admitRouteRequest, applyRouteCredentialHeaders, assertServableRequestRoot, brainConfigSnapshot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential } from "./route-adjudicator.js";
|
|
12
13
|
import { requestRouteOf } from "./request-route.js";
|
|
13
|
-
import {
|
|
14
|
+
import { applyReasoningToRequest } from "./reasoning-request.js";
|
|
14
15
|
import { runStreamingBrain } from "./stream-engine.js";
|
|
15
16
|
import { refuseRetiredTimeoutKnobs } from "./timeout.js";
|
|
16
17
|
import { resolveFetch } from "./transport.js";
|
|
@@ -38,7 +39,7 @@ function textOf(content) {
|
|
|
38
39
|
}
|
|
39
40
|
const NO_CONTENT = "(no content)";
|
|
40
41
|
const DOCUMENT_OMITTED = "[PDF document omitted: PDF direct read requires an Anthropic-family model; re-Read the file (the engine will extract text/render pages when possible) or extract the text via Bash instead (e.g. `pdftotext`).]";
|
|
41
|
-
function toUserContent(content,
|
|
42
|
+
function toUserContent(content, withhold) {
|
|
42
43
|
if (typeof content === "string") {
|
|
43
44
|
return content;
|
|
44
45
|
}
|
|
@@ -52,9 +53,9 @@ function toUserContent(content, supportsVision = true) {
|
|
|
52
53
|
return base;
|
|
53
54
|
return base ? `${base}\n${DOCUMENT_OMITTED}` : DOCUMENT_OMITTED;
|
|
54
55
|
}
|
|
55
|
-
if (
|
|
56
|
+
if (withhold !== undefined) {
|
|
56
57
|
const n = content.filter((c) => c.type === "image").length;
|
|
57
|
-
|
|
58
|
+
reportImagesWithheld(withhold, n);
|
|
58
59
|
const base = textOf(content);
|
|
59
60
|
const note = imagesOmittedNoVisionNote(n);
|
|
60
61
|
const withNote = base ? `${base}\n${note}` : note;
|
|
@@ -80,85 +81,11 @@ function toUserContent(content, supportsVision = true) {
|
|
|
80
81
|
function thinkingCompat(model) {
|
|
81
82
|
return (model.compat ?? {});
|
|
82
83
|
}
|
|
83
|
-
function applyThinking(body, model, reasoning) {
|
|
84
|
-
if (model.reasoning && reasoning === "off") {
|
|
85
|
-
const offCompat = thinkingCompat(model);
|
|
86
|
-
const offFormat = offCompat.thinkingFormat ?? "openai";
|
|
87
|
-
switch (offFormat) {
|
|
88
|
-
case "qwen":
|
|
89
|
-
case "zai":
|
|
90
|
-
body.enable_thinking = false;
|
|
91
|
-
break;
|
|
92
|
-
case "qwen-chat-template": {
|
|
93
|
-
const k = (typeof body.chat_template_kwargs === "object" && body.chat_template_kwargs) || {};
|
|
94
|
-
body.chat_template_kwargs = { ...k, enable_thinking: false };
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
case "deepseek":
|
|
98
|
-
body.thinking = { type: "disabled" };
|
|
99
|
-
break;
|
|
100
|
-
case "openrouter":
|
|
101
|
-
case "together":
|
|
102
|
-
body.reasoning = { enabled: false };
|
|
103
|
-
break;
|
|
104
|
-
case "openai": {
|
|
105
|
-
const offSpelling = declaredOffSpelling(model);
|
|
106
|
-
if (offSpelling !== undefined)
|
|
107
|
-
body.reasoning_effort = offSpelling;
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
default: {
|
|
111
|
-
const _exhaustive = offFormat;
|
|
112
|
-
void _exhaustive;
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (!reasoningRequestCarried(model, reasoning))
|
|
119
|
-
return;
|
|
120
|
-
const compat = thinkingCompat(model);
|
|
121
|
-
const supportsEffort = compat.supportsReasoningEffort ?? true;
|
|
122
|
-
const effortWire = mintEffortWireValue(reasoning, model, compat.reasoningEffortLevels).wireValue;
|
|
123
|
-
const format = compat.thinkingFormat ?? "openai";
|
|
124
|
-
switch (format) {
|
|
125
|
-
case "openai":
|
|
126
|
-
if (supportsEffort && effortWire !== undefined)
|
|
127
|
-
body.reasoning_effort = effortWire;
|
|
128
|
-
break;
|
|
129
|
-
case "openrouter":
|
|
130
|
-
body.reasoning = { effort: effortWire };
|
|
131
|
-
break;
|
|
132
|
-
case "deepseek":
|
|
133
|
-
body.thinking = { type: "enabled" };
|
|
134
|
-
if (supportsEffort && effortWire !== undefined)
|
|
135
|
-
body.reasoning_effort = effortWire;
|
|
136
|
-
break;
|
|
137
|
-
case "together":
|
|
138
|
-
body.reasoning = { enabled: true };
|
|
139
|
-
if (supportsEffort && effortWire !== undefined)
|
|
140
|
-
body.reasoning_effort = effortWire;
|
|
141
|
-
break;
|
|
142
|
-
case "qwen":
|
|
143
|
-
case "zai":
|
|
144
|
-
body.enable_thinking = true;
|
|
145
|
-
break;
|
|
146
|
-
case "qwen-chat-template": {
|
|
147
|
-
const k = (typeof body.chat_template_kwargs === "object" && body.chat_template_kwargs) || {};
|
|
148
|
-
body.chat_template_kwargs = { ...k, enable_thinking: true };
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
default: {
|
|
152
|
-
const _exhaustive = format;
|
|
153
|
-
void _exhaustive;
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
84
|
function toOpenAIMessages(ctx, replayThinking = true, model, toolNames) {
|
|
159
|
-
const
|
|
85
|
+
const imageWithhold = imageWithholdOf(model);
|
|
86
|
+
const supportsVision = imageWithhold === undefined;
|
|
160
87
|
const out = [];
|
|
161
|
-
const needsEmptyReasoningField =
|
|
88
|
+
const needsEmptyReasoningField = model !== undefined && capabilityHeld(model, "reasoning") && thinkingCompat(model).requiresReasoningContentOnAssistantMessages === true;
|
|
162
89
|
if (ctx.systemPrompt) {
|
|
163
90
|
out.push({ role: "system", content: ctx.systemPrompt });
|
|
164
91
|
}
|
|
@@ -181,7 +108,7 @@ function toOpenAIMessages(ctx, replayThinking = true, model, toolNames) {
|
|
|
181
108
|
if (m.role !== "toolResult")
|
|
182
109
|
flushImages();
|
|
183
110
|
if (m.role === "user") {
|
|
184
|
-
const uc = toUserContent(m.content,
|
|
111
|
+
const uc = toUserContent(m.content, imageWithhold);
|
|
185
112
|
const empty = uc === "" || (Array.isArray(uc) && uc.length === 0);
|
|
186
113
|
out.push({ role: "user", content: empty ? NO_CONTENT : uc });
|
|
187
114
|
}
|
|
@@ -215,8 +142,8 @@ function toOpenAIMessages(ctx, replayThinking = true, model, toolNames) {
|
|
|
215
142
|
const mediaImages = sendableImages(Array.isArray(m.content) ? m.content : []);
|
|
216
143
|
const rawImages = m.isError ? [] : mediaImages;
|
|
217
144
|
const images = supportsVision ? rawImages : [];
|
|
218
|
-
if (
|
|
219
|
-
|
|
145
|
+
if (imageWithhold !== undefined)
|
|
146
|
+
reportImagesWithheld(imageWithhold, rawImages.length);
|
|
220
147
|
const nDocs = Array.isArray(m.content) ? m.content.filter((c) => c.type === "document").length : 0;
|
|
221
148
|
if (nDocs > 0)
|
|
222
149
|
emitBrainTelemetry({ kind: "document_placeholder", count: nDocs });
|
|
@@ -390,13 +317,13 @@ export function createOpenAIBrain(given = {}) {
|
|
|
390
317
|
}
|
|
391
318
|
if (options?.stop)
|
|
392
319
|
body.stop = options.stop;
|
|
393
|
-
|
|
320
|
+
const { body: reasoningBody } = applyReasoningToRequest({ api: "openai-completions", model, level: options?.reasoning, body });
|
|
394
321
|
const headers = mergeHeaders(modelHeaders, config.headers, optionsHeaders);
|
|
395
322
|
applyRouteCredentialHeaders(headers, routeCredential);
|
|
396
323
|
lockHeader(headers, "content-type", "application/json");
|
|
397
324
|
if (apiKey)
|
|
398
325
|
lockHeader(headers, OPENAI_KEY_HEADER, `Bearer ${apiKey}`);
|
|
399
|
-
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(
|
|
326
|
+
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(reasoningBody, model, OPENAI_RESERVED);
|
|
400
327
|
return {
|
|
401
328
|
url,
|
|
402
329
|
headers,
|
|
@@ -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;
|