@sema-agent/core 7.54.1 → 7.55.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 +437 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +138 -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/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.js +2 -1
- 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 +43 -9
- package/dist/agents/peer-directory.js +66 -23
- 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 +1 -0
- package/dist/agents/read-inbox-tool.js +2 -1
- 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 +34 -5
- package/dist/agents/subagent.d.ts +34 -79
- package/dist/agents/subagent.js +45 -46
- package/dist/agents/tool-filter.d.ts +29 -46
- package/dist/agents/tool-filter.js +8 -31
- package/dist/agents/verify.d.ts +3 -3
- package/dist/brain/anthropic.js +14 -9
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/model-presets.d.ts +4 -4
- package/dist/brain/open-responses.js +15 -10
- package/dist/brain/openai.js +17 -12
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/request-params.d.ts +55 -5
- package/dist/brain/request-params.js +35 -3
- 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/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +7 -8
- package/dist/core/allow-entry.d.ts +49 -23
- package/dist/core/allow-entry.js +57 -32
- package/dist/core/allow-rule-shadow.d.ts +7 -0
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +63 -11
- package/dist/core/ask-origin.js +27 -5
- package/dist/core/ask-question.js +10 -4
- 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-requirements.d.ts +6 -3
- package/dist/core/checkpoint-requirements.js +4 -14
- package/dist/core/checkpoint-store.d.ts +80 -51
- package/dist/core/checkpoint-store.js +56 -74
- 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 +9 -3
- package/dist/core/cross-boundary-taint.js +5 -3
- package/dist/core/decision-receipt.js +2 -2
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-notice.d.ts +19 -5
- 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 +59 -9
- package/dist/core/file-history-store.js +35 -17
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +12 -8
- package/dist/core/gate-outcome.d.ts +17 -4
- package/dist/core/gate-outcome.js +30 -0
- package/dist/core/governance-codes.d.ts +13 -3
- package/dist/core/governance-codes.js +10 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +4 -4
- package/dist/core/host-target.d.ts +49 -0
- package/dist/core/host-target.js +59 -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 +13 -13
- package/dist/core/mcp.js +187 -162
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/engine.d.ts +9 -9
- 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/namespaced-rule-name.d.ts +33 -7
- package/dist/core/namespaced-rule-name.js +39 -25
- 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 +8 -1
- package/dist/core/parent-spec-seat.js +4 -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 +11 -5
- package/dist/core/permission-rule-consent.js +37 -30
- package/dist/core/permission-rule-model.d.ts +233 -64
- package/dist/core/permission-rule-model.js +384 -85
- package/dist/core/permission-rule-provider.d.ts +2 -1
- package/dist/core/permission-rule-store.d.ts +20 -25
- package/dist/core/permission-rule-store.js +1 -4
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +8 -1
- package/dist/core/permission-rules.d.ts +49 -11
- package/dist/core/permission-rules.js +123 -89
- package/dist/core/persisted-rule-arms.d.ts +4 -2
- package/dist/core/present-plan-tool.js +3 -1
- 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/roles.d.ts +6 -2
- package/dist/core/roles.js +45 -44
- 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 +28 -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 +4 -26
- package/dist/core/runner/announce-once-ledger.js +14 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/caller-roster.d.ts +7 -0
- package/dist/core/runner/caller-roster.js +11 -0
- package/dist/core/runner/classifier-ladder.d.ts +27 -5
- package/dist/core/runner/classifier-ladder.js +12 -11
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/contracts.d.ts +13 -9
- 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 +6 -5
- package/dist/core/runner/cross-boundary-lane.js +26 -15
- 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 +2 -2
- 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/gate-exit.d.ts +6 -0
- package/dist/core/runner/gate-exit.js +7 -2
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +14 -7
- package/dist/core/runner/person-path-rows.js +1 -1
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +6 -4
- package/dist/core/runner/prepare-config-doors.js +18 -12
- 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.js +39 -39
- package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
- package/dist/core/runner/prepare-gate-stations.js +2 -7
- package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
- package/dist/core/runner/prepare-inherited-gate.js +3 -3
- package/dist/core/runner/prepare-park-ask.js +7 -7
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -10
- 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-inputs.js +1 -1
- package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
- package/dist/core/runner/prepare-protocol-tools.js +3 -2
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -6
- package/dist/core/runner/prepare-task.js +15 -18
- package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
- package/dist/core/runner/prepare-wiring-manifest.js +2 -2
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +1 -1
- package/dist/core/runner/run-attachment-seats.js +0 -1
- 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 +2 -3
- package/dist/core/runner/run-leg.js +13 -0
- package/dist/core/runner/run-settle-and-teardown.js +1 -1
- 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 +14 -12
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +13 -28
- 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/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -3
- package/dist/core/runner/synthetic-tools.d.ts +10 -13
- package/dist/core/runner/synthetic-tools.js +4 -2
- package/dist/core/runner/tool-disclosure.js +2 -1
- 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-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 +60 -67
- package/dist/core/runner-deps.d.ts +37 -37
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-merge-corpus.js +17 -1
- 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/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +77 -22
- package/dist/core/session-policy-store.js +56 -14
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +80 -30
- package/dist/core/session-store.js +118 -76
- package/dist/core/session.d.ts +24 -46
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +5 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
- package/dist/core/store-contracts/file-history-store-contract.js +43 -3
- 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 +125 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
- package/dist/core/store-contracts/session-store-contract.js +215 -41
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/task-event.d.ts +10 -4
- package/dist/core/task-notification.d.ts +3 -3
- 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 +4 -4
- package/dist/core/task-registry.js +3 -1
- package/dist/core/task-result.d.ts +3 -3
- package/dist/core/task-spec.d.ts +52 -52
- 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/tool-catalog-entries.d.ts +19 -2
- package/dist/core/tool-catalog-entries.js +57 -42
- 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 +3 -3
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +27 -3
- package/dist/core/tool-name-readings.d.ts +5 -8
- package/dist/core/tool-name-readings.js +1 -2
- package/dist/core/tool-policy.d.ts +24 -5
- package/dist/core/tool-policy.js +34 -10
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +2 -1
- package/dist/core/tool-roster.d.ts +47 -18
- package/dist/core/tool-roster.js +53 -32
- package/dist/core/tool-spec-members.js +1 -1
- package/dist/core/tool-spec.d.ts +35 -21
- package/dist/core/tools.js +3 -2
- package/dist/core/trace.d.ts +4 -0
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +49 -0
- package/dist/core/wiring-manifest.js +13 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +77 -1
- 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/execution-env/node-execution-env.d.ts +19 -5
- package/dist/engine/execution-env/node-execution-env.js +43 -22
- package/dist/engine/harness/agent-harness.d.ts +14 -8
- package/dist/engine/harness/agent-harness.js +33 -26
- package/dist/engine/harness/types.d.ts +29 -7
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +9 -9
- 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 +1 -1
- package/dist/engine/loop/agent-loop.js +10 -8
- package/dist/engine/loop/types.d.ts +15 -13
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +10 -11
- package/dist/engine/session/memory-repo.js +13 -8
- 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 +31 -3
- package/dist/engine/session/repo-utils.js +42 -5
- package/dist/index.d.ts +27 -15
- package/dist/index.js +21 -11
- 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 +1 -1
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -2
- package/dist/orchestration/run-workflow-tool.js +5 -3
- 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 +2 -13
- package/dist/orchestration/workflow.js +21 -31
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
- package/dist/prompt-assembly/tool-catalog.js +3 -0
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +4 -4
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +24 -31
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +6 -15
- package/dist/stores/file/checkpoint-store.d.ts +3 -0
- package/dist/stores/file/checkpoint-store.js +9 -3
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +152 -135
- 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/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 +15 -16
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +21 -14
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +26 -11
- package/dist/stores/file/session-store.js +77 -40
- 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 +2 -1
- 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 +3 -1
- 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/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +1 -1
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +6 -6
- package/dist/tools/fs/shell-read-check.js +6 -1
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -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 +2 -1
- package/dist/tools/web.d.ts +1 -1
- package/dist/tools/web.js +40 -37
- 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 +5756 -5638
- package/wire-changes/core@7.55.0.json +3318 -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
|
@@ -8,6 +8,7 @@ import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imagesOmittedNoVisionNot
|
|
|
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
|
+
import { NAMES_AS_WRITTEN, resolveProviderDialect, endpointToolNames } from "./provider-dialect.js";
|
|
11
12
|
import { declaredOffSpelling, mintEffortWireValue, reasoningRequestCarried } from "./reasoning.js";
|
|
12
13
|
import { runStreamingBrain } from "./stream-engine.js";
|
|
13
14
|
import { refuseRetiredTimeoutKnobs } from "./timeout.js";
|
|
@@ -64,7 +65,7 @@ function toUserParts(content, supportsVision) {
|
|
|
64
65
|
parts.push({ type: "input_text", text: imagesOmittedNoVisionNote(images.length) });
|
|
65
66
|
return parts;
|
|
66
67
|
}
|
|
67
|
-
function toResponsesInput(ctx, model, replayReasoning) {
|
|
68
|
+
function toResponsesInput(ctx, model, replayReasoning, toolNames) {
|
|
68
69
|
const supportsVision = modelSupportsVision(model);
|
|
69
70
|
const out = [];
|
|
70
71
|
let pendingImages = [];
|
|
@@ -116,7 +117,7 @@ function toResponsesInput(ctx, model, replayReasoning) {
|
|
|
116
117
|
if (text !== "")
|
|
117
118
|
out.push({ type: "message", role: "assistant", content: [{ type: "output_text", text }] });
|
|
118
119
|
for (const tc of toolCalls) {
|
|
119
|
-
out.push({ type: "function_call", call_id: providerToolCallId(tc), name: tc.name, arguments: JSON.stringify(tc.arguments ?? {}) });
|
|
120
|
+
out.push({ type: "function_call", call_id: providerToolCallId(tc), name: toolNames.sent(tc.name), arguments: JSON.stringify(tc.arguments ?? {}) });
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
else if (m.role === "toolResult") {
|
|
@@ -145,12 +146,12 @@ function toResponsesInput(ctx, model, replayReasoning) {
|
|
|
145
146
|
flushImages();
|
|
146
147
|
return out;
|
|
147
148
|
}
|
|
148
|
-
function toResponsesTools(ctx) {
|
|
149
|
+
function toResponsesTools(ctx, toolNames) {
|
|
149
150
|
if (!ctx.tools || ctx.tools.length === 0)
|
|
150
151
|
return undefined;
|
|
151
152
|
return ctx.tools.map((t) => ({
|
|
152
153
|
type: "function",
|
|
153
|
-
name: t.name,
|
|
154
|
+
name: toolNames.sent(t.name),
|
|
154
155
|
description: t.description,
|
|
155
156
|
parameters: t.parameters,
|
|
156
157
|
strict: false,
|
|
@@ -231,6 +232,7 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
231
232
|
let sentEffort;
|
|
232
233
|
let builtMaxTokens;
|
|
233
234
|
let builtMaxTokensLane = "unset";
|
|
235
|
+
let sentToolNames = NAMES_AS_WRITTEN;
|
|
234
236
|
return runStreamingBrain({
|
|
235
237
|
model,
|
|
236
238
|
doFetch,
|
|
@@ -245,6 +247,8 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
245
247
|
if (!root) {
|
|
246
248
|
throw new Error("createOpenResponsesBrain: no baseUrl configured (set config.baseUrl or model.baseUrl)");
|
|
247
249
|
}
|
|
250
|
+
const url = joinRequestUrl(root, "/responses");
|
|
251
|
+
const builtToolNames = endpointToolNames(resolveProviderDialect(url, model.api), model.api, (context.tools ?? []).map((t) => t.name));
|
|
248
252
|
const modelHeaders = headerBagOnce(model.headers);
|
|
249
253
|
const optionsHeaders = headerBagOnce(options?.headers);
|
|
250
254
|
const routeCredential = resolveRouteCredential({
|
|
@@ -265,12 +269,12 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
265
269
|
const effort = resolveWireEffort(model, options?.reasoning);
|
|
266
270
|
const body = {
|
|
267
271
|
model: model.id,
|
|
268
|
-
input: toResponsesInput(context, model, config.replayReasoning !== false),
|
|
272
|
+
input: toResponsesInput(context, model, config.replayReasoning !== false, builtToolNames),
|
|
269
273
|
stream: true,
|
|
270
274
|
};
|
|
271
275
|
if (context.systemPrompt)
|
|
272
276
|
body.instructions = context.systemPrompt;
|
|
273
|
-
const tools = toResponsesTools(context);
|
|
277
|
+
const tools = toResponsesTools(context, builtToolNames);
|
|
274
278
|
if (tools)
|
|
275
279
|
body.tools = tools;
|
|
276
280
|
if (options?.temperature !== undefined)
|
|
@@ -293,9 +297,9 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
293
297
|
lockHeader(headers, "content-type", "application/json");
|
|
294
298
|
if (apiKey)
|
|
295
299
|
lockHeader(headers, OPEN_RESPONSES_KEY_HEADER, `Bearer ${apiKey}`);
|
|
296
|
-
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(body, model
|
|
300
|
+
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(body, model, RESPONSES_RESERVED);
|
|
297
301
|
return {
|
|
298
|
-
url
|
|
302
|
+
url,
|
|
299
303
|
headers,
|
|
300
304
|
body: JSON.stringify(wire),
|
|
301
305
|
extraBodyDropped,
|
|
@@ -307,6 +311,7 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
307
311
|
sentMaxTokens = builtMaxTokens;
|
|
308
312
|
sentMaxTokensLane = builtMaxTokensLane;
|
|
309
313
|
sentEffort = effort;
|
|
314
|
+
sentToolNames = builtToolNames;
|
|
310
315
|
},
|
|
311
316
|
};
|
|
312
317
|
},
|
|
@@ -457,7 +462,7 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
457
462
|
else if (itemType === "function_call") {
|
|
458
463
|
const acc = openItem(index, "function_call", itemId);
|
|
459
464
|
acc.callId = frame.item?.call_id ?? "";
|
|
460
|
-
acc.name = frame.item?.name ?? "";
|
|
465
|
+
acc.name = sentToolNames.called(frame.item?.name ?? "");
|
|
461
466
|
if (frame.item?.arguments)
|
|
462
467
|
acc.args += frame.item.arguments;
|
|
463
468
|
}
|
|
@@ -546,7 +551,7 @@ export function createOpenResponsesBrain(given = {}) {
|
|
|
546
551
|
if (!acc.callId && frame.item?.call_id)
|
|
547
552
|
acc.callId = frame.item.call_id;
|
|
548
553
|
if (!acc.name && frame.item?.name)
|
|
549
|
-
acc.name = frame.item.name;
|
|
554
|
+
acc.name = sentToolNames.called(frame.item.name);
|
|
550
555
|
if (acc.args === "" && frame.item?.arguments)
|
|
551
556
|
acc.args = frame.item.arguments;
|
|
552
557
|
}
|
package/dist/brain/openai.js
CHANGED
|
@@ -7,7 +7,7 @@ import { emitBrainTelemetry } from "./status-sink.js";
|
|
|
7
7
|
import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imagesOmittedNoVisionNote, modelSupportsVision, sendableImages } from "./media-degrade.js";
|
|
8
8
|
import { OPENAI_RESERVED, OUTPUT_CAP_KEYS, applyExtraBody, effectiveOutputCap, headerBagOnce, lockHeader, mergeHeaders } from "./request-params.js";
|
|
9
9
|
import { BrainError, providerErrorWord } from "./errors.js";
|
|
10
|
-
import { inBandProviderError } from "./provider-dialect.js";
|
|
10
|
+
import { NAMES_AS_WRITTEN, inBandProviderError, resolveProviderDialect, endpointToolNames } from "./provider-dialect.js";
|
|
11
11
|
import { admitRouteRequest, applyRouteCredentialHeaders, assertServableRequestRoot, brainConfigSnapshot, createBrainRouteJudge, joinRequestUrl, resolveRequestRootOf, resolveRouteCredential } from "./route-adjudicator.js";
|
|
12
12
|
import { requestRouteOf } from "./request-route.js";
|
|
13
13
|
import { declaredOffSpelling, mintEffortWireValue, reasoningRequestCarried } from "./reasoning.js";
|
|
@@ -155,7 +155,7 @@ function applyThinking(body, model, reasoning) {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
|
-
function toOpenAIMessages(ctx, replayThinking = true, model) {
|
|
158
|
+
function toOpenAIMessages(ctx, replayThinking = true, model, toolNames) {
|
|
159
159
|
const supportsVision = modelSupportsVision(model);
|
|
160
160
|
const out = [];
|
|
161
161
|
const needsEmptyReasoningField = !!model?.reasoning && thinkingCompat(model).requiresReasoningContentOnAssistantMessages === true;
|
|
@@ -206,7 +206,7 @@ function toOpenAIMessages(ctx, replayThinking = true, model) {
|
|
|
206
206
|
msg.tool_calls = toolCalls.map((tc) => ({
|
|
207
207
|
id: providerToolCallId(tc),
|
|
208
208
|
type: "function",
|
|
209
|
-
function: { name: tc.name, arguments: JSON.stringify(tc.arguments ?? {}) },
|
|
209
|
+
function: { name: toolNames.sent(tc.name), arguments: JSON.stringify(tc.arguments ?? {}) },
|
|
210
210
|
}));
|
|
211
211
|
}
|
|
212
212
|
out.push(msg);
|
|
@@ -244,13 +244,13 @@ function toolResultText(text, hasCarriedImages, original) {
|
|
|
244
244
|
return "(image attached below)";
|
|
245
245
|
return Array.isArray(original) && original.length > 0 ? "(non-text tool result omitted)" : "";
|
|
246
246
|
}
|
|
247
|
-
function toOpenAITools(ctx) {
|
|
247
|
+
function toOpenAITools(ctx, toolNames) {
|
|
248
248
|
if (!ctx.tools || ctx.tools.length === 0) {
|
|
249
249
|
return undefined;
|
|
250
250
|
}
|
|
251
251
|
return ctx.tools.map((t) => ({
|
|
252
252
|
type: "function",
|
|
253
|
-
function: { name: t.name, description: t.description, parameters: t.parameters },
|
|
253
|
+
function: { name: toolNames.sent(t.name), description: t.description, parameters: t.parameters },
|
|
254
254
|
}));
|
|
255
255
|
}
|
|
256
256
|
const FINISH_REASON_READINGS = Object.freeze({
|
|
@@ -334,6 +334,7 @@ export function createOpenAIBrain(given = {}) {
|
|
|
334
334
|
let sentMaxTokensLane = "unset";
|
|
335
335
|
let builtMaxTokens;
|
|
336
336
|
let builtMaxTokensLane = "unset";
|
|
337
|
+
let sentToolNames = NAMES_AS_WRITTEN;
|
|
337
338
|
return runStreamingBrain({
|
|
338
339
|
model,
|
|
339
340
|
doFetch,
|
|
@@ -348,6 +349,8 @@ export function createOpenAIBrain(given = {}) {
|
|
|
348
349
|
if (!root) {
|
|
349
350
|
throw new Error("createOpenAIBrain: no baseUrl configured (set config.baseUrl or model.baseUrl)");
|
|
350
351
|
}
|
|
352
|
+
const url = joinRequestUrl(root, "/chat/completions");
|
|
353
|
+
const builtToolNames = endpointToolNames(resolveProviderDialect(url, model.api), model.api, (context.tools ?? []).map((t) => t.name));
|
|
351
354
|
const modelHeaders = headerBagOnce(model.headers);
|
|
352
355
|
const optionsHeaders = headerBagOnce(options?.headers);
|
|
353
356
|
const routeCredential = resolveRouteCredential({
|
|
@@ -362,11 +365,11 @@ export function createOpenAIBrain(given = {}) {
|
|
|
362
365
|
const apiKey = routeCredential.apiKey;
|
|
363
366
|
const body = {
|
|
364
367
|
model: model.id,
|
|
365
|
-
messages: toOpenAIMessages(context, config.replayThinking, model),
|
|
368
|
+
messages: toOpenAIMessages(context, config.replayThinking, model, builtToolNames),
|
|
366
369
|
stream: true,
|
|
367
370
|
stream_options: { include_usage: true },
|
|
368
371
|
};
|
|
369
|
-
const tools = toOpenAITools(context);
|
|
372
|
+
const tools = toOpenAITools(context, builtToolNames);
|
|
370
373
|
if (tools)
|
|
371
374
|
body.tools = tools;
|
|
372
375
|
if (options?.temperature !== undefined)
|
|
@@ -393,9 +396,9 @@ export function createOpenAIBrain(given = {}) {
|
|
|
393
396
|
lockHeader(headers, "content-type", "application/json");
|
|
394
397
|
if (apiKey)
|
|
395
398
|
lockHeader(headers, OPENAI_KEY_HEADER, `Bearer ${apiKey}`);
|
|
396
|
-
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(body, model
|
|
399
|
+
const { body: wire, dropped: extraBodyDropped } = applyExtraBody(body, model, OPENAI_RESERVED);
|
|
397
400
|
return {
|
|
398
|
-
url
|
|
401
|
+
url,
|
|
399
402
|
headers,
|
|
400
403
|
body: JSON.stringify(wire),
|
|
401
404
|
extraBodyDropped,
|
|
@@ -406,6 +409,7 @@ export function createOpenAIBrain(given = {}) {
|
|
|
406
409
|
routeAdmission();
|
|
407
410
|
sentMaxTokens = builtMaxTokens;
|
|
408
411
|
sentMaxTokensLane = builtMaxTokensLane;
|
|
412
|
+
sentToolNames = builtToolNames;
|
|
409
413
|
},
|
|
410
414
|
};
|
|
411
415
|
},
|
|
@@ -577,7 +581,7 @@ export function createOpenAIBrain(given = {}) {
|
|
|
577
581
|
if (tc.id)
|
|
578
582
|
acc.id = tc.id;
|
|
579
583
|
if (tc.function?.name)
|
|
580
|
-
acc.name = tc.function.name;
|
|
584
|
+
acc.name = sentToolNames.called(tc.function.name);
|
|
581
585
|
if (tc.function?.arguments && !acc.closedTc)
|
|
582
586
|
acc.args += tc.function.arguments;
|
|
583
587
|
toolAccum.set(idx, acc);
|
|
@@ -619,7 +623,7 @@ export function createOpenAIBrain(given = {}) {
|
|
|
619
623
|
}
|
|
620
624
|
}
|
|
621
625
|
if (config.repairTextToolCalls && toolCalls.length === 0 && textFace && context.tools && context.tools.length > 0) {
|
|
622
|
-
const names = new Set(context.tools.flatMap((t) => [t.name, ...(t.aliases ?? [])]));
|
|
626
|
+
const names = new Set(context.tools.flatMap((t) => [t.name, sentToolNames.sent(t.name), ...(t.aliases ?? [])]));
|
|
623
627
|
const repaired = repairTextToolCalls(textFace, names);
|
|
624
628
|
if (repaired.toolCalls.length > 0) {
|
|
625
629
|
finalContent.length = 0;
|
|
@@ -627,7 +631,8 @@ export function createOpenAIBrain(given = {}) {
|
|
|
627
631
|
finalContent.push({ type: "thinking", thinking: accumReasoning });
|
|
628
632
|
if (repaired.cleanedText)
|
|
629
633
|
finalContent.push({ type: "text", text: repaired.cleanedText });
|
|
630
|
-
for (const
|
|
634
|
+
for (const repairedCall of repaired.toolCalls) {
|
|
635
|
+
const tc = { ...repairedCall, name: sentToolNames.called(repairedCall.name) };
|
|
631
636
|
finalContent.push(tc);
|
|
632
637
|
toolCalls.push(tc);
|
|
633
638
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The provider dialect table — what each provider endpoint MEANS by the way it fails
|
|
3
|
-
* endpoint and read by every seat that reports a provider failure
|
|
2
|
+
* The provider dialect table — what each provider endpoint MEANS by the way it fails and by the tool names it is
|
|
3
|
+
* sent, declared once per endpoint and read by every seat that reports a provider failure or names a tool on the
|
|
4
|
+
* wire.
|
|
4
5
|
*
|
|
5
6
|
* KEY. An endpoint is named by (wire family, host suffix + path): the same brand can serve two endpoints whose
|
|
6
7
|
* failures read in opposite ways (Moonshot's open platform states an exhausted balance as a 429, its coding
|
|
@@ -14,7 +15,9 @@
|
|
|
14
15
|
* column: rows that turn a status, the envelope's word (`error.code`, else `error.type` — the same word
|
|
15
16
|
* `apiErrorCode` carries) and the envelope's sentence (`error.message`) into one {@link ProviderCondition}. The
|
|
16
17
|
* context-limit refusal is a flag on the same rows (`inputTooLong`), so "this 400 is the input being too long"
|
|
17
|
-
* and "this 400 is something else the provider named" are read off one row and cannot disagree.
|
|
18
|
+
* and "this 400 is something else the provider named" are read off one row and cannot disagree. `toolNames` is
|
|
19
|
+
* the tool-name column: names the endpoint gives a meaning of its own on one wire ({@link ToolNameRow}), read by
|
|
20
|
+
* {@link endpointToolNames} — the one projection every brain sends tool names through and reads call names back by.
|
|
18
21
|
*
|
|
19
22
|
* ONE VERDICT, TWO SEATS. {@link judgeHttpFailure} answers once per failed response; the retry decision, the
|
|
20
23
|
* retry frame (`BrainStatus.providerCondition`) and the terminal (`BrainError` → `AssistantMessage` →
|
|
@@ -142,11 +145,24 @@ export interface DialectKey {
|
|
|
142
145
|
/** A path prefix, matched at a segment boundary. Absent = every path on the host. */
|
|
143
146
|
readonly path?: string;
|
|
144
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* One row of the tool-name column. On `wire`, the endpoint treats a tool sent under `name` as a feature of its own
|
|
150
|
+
* rather than as the tool the request declares, so a tool by that name travels as `sentAs` instead, and a call the
|
|
151
|
+
* model makes to `sentAs` is a call to `name`. The name inside the engine, the prompts that mention it and the
|
|
152
|
+
* tool's parameters do not change; only the spelling on this wire does.
|
|
153
|
+
*/
|
|
154
|
+
export interface ToolNameRow {
|
|
155
|
+
readonly wire: Model["api"];
|
|
156
|
+
readonly name: string;
|
|
157
|
+
readonly sentAs: string;
|
|
158
|
+
}
|
|
145
159
|
/** One endpoint's declared dialect: its key and its columns. */
|
|
146
160
|
export interface ProviderDialect {
|
|
147
161
|
readonly name: string;
|
|
148
162
|
readonly key: DialectKey;
|
|
149
163
|
readonly failures: readonly FailureRow[];
|
|
164
|
+
/** Absent = the endpoint gives no tool name a meaning of its own: every name travels as written. */
|
|
165
|
+
readonly toolNames?: readonly ToolNameRow[];
|
|
150
166
|
}
|
|
151
167
|
/**
|
|
152
168
|
* The declared dialects. Each row's source is the provider's own error documentation as collected in the
|
|
@@ -172,6 +188,26 @@ export declare const GENERIC_FAILURES: readonly FailureRow[];
|
|
|
172
188
|
export declare function isTransientStatus(status: number): boolean;
|
|
173
189
|
/** The endpoint a request went to, or `undefined` when no dialect declares it. */
|
|
174
190
|
export declare function resolveProviderDialect(url: string, wire: Model["api"]): ProviderDialect | undefined;
|
|
191
|
+
/**
|
|
192
|
+
* How one request's tool names travel. Both halves read the one set the request declares: `sent` spells a declared
|
|
193
|
+
* tool's name, in the tool table and in every replayed call to it; `called` reads a call name the model sends back as
|
|
194
|
+
* the declared tool that travels under it. A name the request does not declare travels and comes back as written —
|
|
195
|
+
* a replayed call to a tool no longer mounted keeps its name, and a model that calls a tool by the name the prompts
|
|
196
|
+
* use still reaches it. A brain builds one with each request and keeps the one the engine commits; its parser reads
|
|
197
|
+
* call names through it.
|
|
198
|
+
*/
|
|
199
|
+
export interface EndpointToolNames {
|
|
200
|
+
readonly sent: (name: string) => string;
|
|
201
|
+
readonly called: (sentName: string) => string;
|
|
202
|
+
}
|
|
203
|
+
/** Every name travels as written: the projection of an endpoint whose dialect has no tool-name row on the wire. */
|
|
204
|
+
export declare const NAMES_AS_WRITTEN: EndpointToolNames;
|
|
205
|
+
/**
|
|
206
|
+
* The tool-name projection of one request: the dialect's rows for this wire, applied to the tools the request
|
|
207
|
+
* declares. Two declared tools that would travel under one name are refused before anything is sent — the model
|
|
208
|
+
* could not tell them apart, and neither could the call that comes back.
|
|
209
|
+
*/
|
|
210
|
+
export declare function endpointToolNames(dialect: ProviderDialect | undefined, wire: Model["api"], declared: readonly string[]): EndpointToolNames;
|
|
175
211
|
/** One failure's reading off the table. */
|
|
176
212
|
export interface ProviderVerdict {
|
|
177
213
|
readonly condition: ProviderCondition;
|
|
@@ -87,6 +87,7 @@ export const PROVIDER_DIALECTS = Object.freeze([
|
|
|
87
87
|
{ status: [429], word: ["1311", "1313"], condition: "stop_other" },
|
|
88
88
|
{ status: [400], word: ["1261"], condition: "stop_other", inputTooLong: true },
|
|
89
89
|
],
|
|
90
|
+
toolNames: [{ wire: ANTHROPIC, name: "ToolSearch", sentAs: "ToolFinder" }],
|
|
90
91
|
},
|
|
91
92
|
{
|
|
92
93
|
name: "openai",
|
|
@@ -120,6 +121,33 @@ export function resolveProviderDialect(url, wire) {
|
|
|
120
121
|
d.key.hosts.some((h) => host === h || host.endsWith(`.${h}`)) &&
|
|
121
122
|
(d.key.path === undefined || path === d.key.path || path.startsWith(`${d.key.path}/`)));
|
|
122
123
|
}
|
|
124
|
+
export const NAMES_AS_WRITTEN = Object.freeze({ sent: (name) => name, called: (sentName) => sentName });
|
|
125
|
+
export function endpointToolNames(dialect, wire, declared) {
|
|
126
|
+
const rows = (dialect?.toolNames ?? []).filter((r) => r.wire === wire);
|
|
127
|
+
if (rows.length === 0)
|
|
128
|
+
return NAMES_AS_WRITTEN;
|
|
129
|
+
const sentAs = new Map(rows.map((r) => [r.name, r.sentAs]));
|
|
130
|
+
const holderOf = new Map();
|
|
131
|
+
const forward = new Map();
|
|
132
|
+
const back = new Map();
|
|
133
|
+
for (const name of new Set(declared)) {
|
|
134
|
+
const onWire = sentAs.get(name) ?? name;
|
|
135
|
+
const holder = holderOf.get(onWire);
|
|
136
|
+
if (holder !== undefined) {
|
|
137
|
+
const moved = rows.filter((r) => r.sentAs === onWire).map((r) => JSON.stringify(r.name)).join(" / ");
|
|
138
|
+
const asWritten = [holder, name].find((n) => n === onWire);
|
|
139
|
+
throw new BrainError("invalid_request", `the request was not sent: the tools ${JSON.stringify(holder)} and ${JSON.stringify(name)} would both travel as ${JSON.stringify(onWire)}. ` +
|
|
140
|
+
`This endpoint gives the tool name ${moved} a meaning of its own on this wire, so a tool by that name is sent as ${JSON.stringify(onWire)}, ` +
|
|
141
|
+
`and two tools cannot share one name on the wire — rename ${asWritten === undefined ? "one of them" : `the tool named ${JSON.stringify(asWritten)}`}.`);
|
|
142
|
+
}
|
|
143
|
+
holderOf.set(onWire, name);
|
|
144
|
+
if (onWire !== name) {
|
|
145
|
+
forward.set(name, onWire);
|
|
146
|
+
back.set(onWire, name);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { sent: (name) => forward.get(name) ?? name, called: (sentName) => back.get(sentName) ?? sentName };
|
|
150
|
+
}
|
|
123
151
|
function statementOf(err) {
|
|
124
152
|
if (err === undefined)
|
|
125
153
|
return undefined;
|
|
@@ -53,7 +53,7 @@ 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"
|
|
@@ -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
|
};
|
|
@@ -94,8 +144,8 @@ export declare const OUTPUT_CAP_KEYS: Readonly<Record<"openai" | "anthropic" | "
|
|
|
94
144
|
* of the lane's cap keys that is present and usable, or `undefined` when none is.
|
|
95
145
|
*
|
|
96
146
|
* Read off the merged body rather than off the knob the adapter set, because those are not the same
|
|
97
|
-
* thing:
|
|
98
|
-
*
|
|
99
|
-
*
|
|
147
|
+
* thing: what is on the wire is the only cap the provider enforces, and the adapter's own number can differ
|
|
148
|
+
* from it (the Anthropic lane raises `max_tokens` to fit a thinking budget). Smallest wins so a consumer
|
|
149
|
+
* reasoning about the bound stays conservative.
|
|
100
150
|
*/
|
|
101
151
|
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
|
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
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createAssistantMessageEventStream, } from "../internal/llm.js";
|
|
2
2
|
import { STREAM_TORN_WARNING } from "./stream-shared.js";
|
|
3
3
|
import { FLOOR_OUTPUT_TOKENS, parseContextOverflow, planOutputCapAdjustment } from "./context-overflow.js";
|
|
4
|
-
import { abortLikeName, BrainError, brainErrorCodeOf, classifyFetchThrow, classifyHttp, describeNetworkError, isProviderEchoShape, namesTheFailure, proxyTunnelRefusedSentence, readConnectFailure, readProviderErrorCode, readProviderRequestId, refusedTheRequest } from "./errors.js";
|
|
4
|
+
import { abortLikeName, BrainError, brainErrorCodeOf, classifyFetchThrow, classifyHttp, describeNetworkError, isProviderEchoShape, namesTheFailure, proxyTunnelRefusedSentence, readConnectFailure, readProviderErrorCode, readProviderRequestId, refusedTheRequest, thrownBrainFailure } from "./errors.js";
|
|
5
5
|
import { stripUrlCredentials } from "./route-adjudicator.js";
|
|
6
6
|
import { admittedRequestRoute } from "./request-route.js";
|
|
7
7
|
import { isTransientStatus, isProviderCondition, isProviderConditionSource, judgeHttpFailure, PROVIDER_CONDITION_TRAITS, resolveProviderDialect, } from "./provider-dialect.js";
|
|
@@ -314,10 +314,11 @@ export function runStreamingBrain(args) {
|
|
|
314
314
|
}
|
|
315
315
|
errorMsg.stopReason = aborted ? "aborted" : "error";
|
|
316
316
|
errorMsg.errorMessage = thrownText(err);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
317
|
+
const failure = aborted ? {} : thrownBrainFailure(err);
|
|
318
|
+
if (failure.code !== undefined) {
|
|
319
|
+
if (failure.errorKind !== undefined)
|
|
320
|
+
errorMsg.errorKind = failure.errorKind;
|
|
321
|
+
else if (failure.inputTooLongRuledOut === true)
|
|
321
322
|
errorMsg.inputTooLongRuledOut = true;
|
|
322
323
|
if (readMember(err, "errorBodyIncomplete") === true)
|
|
323
324
|
errorMsg.errorBodyIncomplete = true;
|
|
@@ -14,7 +14,7 @@ import { type AssistantMessage, type ModelOutputInvalid, type StreamDropCause }
|
|
|
14
14
|
*
|
|
15
15
|
* Internal module: not re-exported from `src/index.ts`.
|
|
16
16
|
*/
|
|
17
|
-
/** The warning (
|
|
17
|
+
/** The warning (the reference's former words; later replaced by a resume request) stamped beside `partialFinalized` when a stream ended before its close — by the
|
|
18
18
|
* mid-stream promotion (the body threw) and by the parsers' own finalize (content arrived, no finish frame). */
|
|
19
19
|
export declare const STREAM_TORN_WARNING = "Connection closed mid-response. The response above may be incomplete.";
|
|
20
20
|
/** A provider word as a stream-end seat carries it: the word in the provider echo shape, else `?` — the fact that a
|