@sema-agent/core 7.54.1 → 7.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +950 -0
- package/dist/agents/agent-transcript-tool.js +2 -1
- package/dist/agents/builtin-agents.d.ts +12 -14
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/cc-peer-directory.d.ts +36 -0
- package/dist/agents/cc-peer-directory.js +139 -0
- package/dist/agents/cc-peer-wire.d.ts +105 -0
- package/dist/agents/cc-peer-wire.js +98 -0
- package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
- package/dist/agents/cc-uds-peer-channel.js +457 -0
- package/dist/agents/child-model-seat.d.ts +0 -11
- package/dist/agents/child-model-seat.js +0 -3
- package/dist/agents/cross-session-envelope.d.ts +4 -1
- package/dist/agents/cross-session-envelope.js +8 -1
- package/dist/agents/cross-session-judge.d.ts +2 -2
- package/dist/agents/list-agents-tool.d.ts +3 -1
- package/dist/agents/list-agents-tool.js +9 -8
- package/dist/agents/observer.d.ts +4 -5
- package/dist/agents/observer.js +2 -1
- package/dist/agents/peer-admission.d.ts +6 -0
- package/dist/agents/peer-admission.js +4 -1
- package/dist/agents/peer-directory.d.ts +65 -13
- package/dist/agents/peer-directory.js +90 -25
- package/dist/agents/peer-notices.d.ts +1 -1
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +3 -2
- package/dist/agents/read-inbox-tool.js +2 -1
- package/dist/agents/repair-loop.js +2 -2
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/roster-store.d.ts +1 -1
- package/dist/agents/send-message-tool.d.ts +10 -0
- package/dist/agents/send-message-tool.js +37 -8
- package/dist/agents/subagent.d.ts +39 -82
- package/dist/agents/subagent.js +109 -106
- package/dist/agents/tool-filter.d.ts +31 -46
- package/dist/agents/tool-filter.js +13 -33
- package/dist/agents/verify.d.ts +6 -5
- package/dist/agents/verify.js +3 -3
- package/dist/brain/anthropic.js +43 -81
- package/dist/brain/errors.d.ts +15 -0
- package/dist/brain/errors.js +10 -0
- package/dist/brain/media-degrade.d.ts +18 -7
- package/dist/brain/media-degrade.js +13 -2
- package/dist/brain/model-capability.d.ts +37 -0
- package/dist/brain/model-capability.js +34 -0
- package/dist/brain/model-presets.d.ts +6 -12
- package/dist/brain/model-presets.js +1 -6
- package/dist/brain/open-responses.js +27 -35
- package/dist/brain/openai.js +30 -98
- package/dist/brain/provider-dialect.d.ts +39 -3
- package/dist/brain/provider-dialect.js +28 -0
- package/dist/brain/reasoning-request.d.ts +96 -0
- package/dist/brain/reasoning-request.js +174 -0
- package/dist/brain/reasoning.d.ts +12 -12
- package/dist/brain/reasoning.js +4 -3
- package/dist/brain/request-params.d.ts +62 -9
- package/dist/brain/request-params.js +42 -7
- package/dist/brain/retry.d.ts +1 -1
- package/dist/brain/route-adjudicator.d.ts +15 -0
- package/dist/brain/route-adjudicator.js +15 -0
- package/dist/brain/status-sink.d.ts +20 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/brain/stream-engine.js +6 -5
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/a2a.d.ts +2 -1
- package/dist/core/a2a.js +19 -13
- package/dist/core/advisor-verdict.d.ts +120 -0
- package/dist/core/advisor-verdict.js +92 -0
- package/dist/core/agent-definition.d.ts +17 -8
- package/dist/core/allow-entry.d.ts +69 -36
- package/dist/core/allow-entry.js +81 -52
- package/dist/core/allow-rule-shadow.d.ts +10 -3
- package/dist/core/approval-object.d.ts +2 -1
- package/dist/core/approval-object.js +6 -6
- package/dist/core/ask-origin.d.ts +127 -29
- package/dist/core/ask-origin.js +87 -25
- package/dist/core/ask-question.d.ts +51 -8
- package/dist/core/ask-question.js +12 -7
- package/dist/core/ask-unresolvable-notice.d.ts +8 -3
- package/dist/core/ask-unresolvable-notice.js +16 -2
- package/dist/core/auto-compaction.d.ts +11 -8
- package/dist/core/auto-compaction.js +4 -2
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/auto-mode-defaults.d.ts +8 -8
- package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
- package/dist/core/auto-mode-prompt.d.ts +1 -1
- package/dist/core/auto-mode.d.ts +17 -9
- package/dist/core/auto-mode.js +9 -6
- package/dist/core/background-agent-store.d.ts +3 -3
- package/dist/core/canonical-json.d.ts +1 -1
- package/dist/core/canonical-json.js +2 -2
- package/dist/core/checkpoint-generation.d.ts +53 -0
- package/dist/core/checkpoint-generation.js +35 -0
- package/dist/core/checkpoint-queries.d.ts +180 -0
- package/dist/core/checkpoint-queries.js +272 -0
- package/dist/core/checkpoint-requirements.d.ts +19 -4
- package/dist/core/checkpoint-requirements.js +8 -14
- package/dist/core/checkpoint-store.d.ts +165 -72
- package/dist/core/checkpoint-store.js +79 -82
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +3 -16
- package/dist/core/compliance.d.ts +2 -2
- package/dist/core/context-edit.d.ts +6 -7
- package/dist/core/cross-boundary-taint.d.ts +11 -4
- package/dist/core/cross-boundary-taint.js +3 -3
- package/dist/core/decision-receipt.d.ts +37 -3
- package/dist/core/decision-receipt.js +19 -19
- package/dist/core/delegation-not-started.d.ts +6 -0
- package/dist/core/delegation-not-started.js +17 -0
- package/dist/core/effective-path-target.d.ts +1 -1
- package/dist/core/engine-attestation.d.ts +93 -0
- package/dist/core/engine-attestation.js +70 -0
- package/dist/core/engine-capabilities.d.ts +4 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +45 -12
- package/dist/core/exec-output-tail.d.ts +1 -1
- package/dist/core/file-history-retention.d.ts +1 -1
- package/dist/core/file-history-store.d.ts +147 -21
- package/dist/core/file-history-store.js +58 -32
- package/dist/core/gate-fold.d.ts +1 -1
- package/dist/core/gate-fold.js +24 -11
- package/dist/core/gate-lanes.js +81 -68
- package/dist/core/gate-outcome.d.ts +40 -6
- package/dist/core/gate-outcome.js +56 -0
- package/dist/core/governance-codes.d.ts +17 -3
- package/dist/core/governance-codes.js +16 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +21 -20
- package/dist/core/hooks.js +3 -1
- package/dist/core/host-floor.d.ts +128 -0
- package/dist/core/host-floor.js +206 -0
- package/dist/core/host-target.d.ts +84 -0
- package/dist/core/host-target.js +92 -0
- package/dist/core/image-downsample.d.ts +1 -1
- package/dist/core/lsp-diagnostics.d.ts +4 -4
- package/dist/core/lsp.d.ts +3 -3
- package/dist/core/mailbox-store.d.ts +4 -0
- package/dist/core/mcp-connection-pool.d.ts +18 -2
- package/dist/core/mcp-connection-pool.js +53 -6
- package/dist/core/mcp-failure.d.ts +23 -4
- package/dist/core/mcp-failure.js +26 -11
- package/dist/core/mcp-listing-drift.d.ts +10 -0
- package/dist/core/mcp-listing-drift.js +6 -0
- package/dist/core/mcp-server-link.d.ts +173 -0
- package/dist/core/mcp-server-link.js +127 -0
- package/dist/core/mcp-server-spec.d.ts +4 -2
- package/dist/core/mcp-session-end.d.ts +26 -0
- package/dist/core/mcp-session-end.js +29 -0
- package/dist/core/mcp-startup-request.d.ts +17 -0
- package/dist/core/mcp-startup-request.js +17 -0
- package/dist/core/mcp.d.ts +17 -13
- package/dist/core/mcp.js +240 -189
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-engine/delegation-settlement.js +15 -24
- package/dist/core/memory-engine/engine.d.ts +9 -9
- package/dist/core/memory-engine/engine.js +4 -4
- package/dist/core/memory-engine/layout.d.ts +60 -8
- package/dist/core/memory-engine/layout.js +65 -6
- package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
- package/dist/core/memory-engine/tools.js +4 -1
- package/dist/core/mode-policy.d.ts +1 -1
- package/dist/core/model-seat.d.ts +10 -3
- package/dist/core/mods/classic-events.d.ts +67 -0
- package/dist/core/mods/classic-events.js +1 -0
- package/dist/core/mods/dollar.d.ts +13 -0
- package/dist/core/mods/extension-call.d.ts +31 -0
- package/dist/core/mods/extension-call.js +43 -0
- package/dist/core/mods/kernel/dispatch.d.ts +20 -3
- package/dist/core/mods/kernel/dispatch.js +140 -69
- package/dist/core/mods/kernel/events.d.ts +47 -11
- package/dist/core/mods/kernel/events.js +66 -42
- package/dist/core/mods/kernel/index.d.ts +4 -4
- package/dist/core/mods/kernel/index.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -5
- package/dist/core/mods/kernel/receive.js +290 -17
- package/dist/core/mods/kernel/registration.d.ts +33 -2
- package/dist/core/mods/kernel/registration.js +6 -7
- package/dist/core/mods/kernel/site-rules.d.ts +44 -16
- package/dist/core/mods/kernel/site-rules.js +24 -42
- package/dist/core/mods/spec-seats.d.ts +69 -0
- package/dist/core/mods/spec-seats.js +114 -0
- package/dist/core/mods/stations.d.ts +28 -8
- package/dist/core/mods/stations.js +29 -13
- package/dist/core/mods/tool-call.d.ts +79 -0
- package/dist/core/mods/tool-call.js +152 -0
- package/dist/core/namespaced-rule-name.d.ts +44 -24
- package/dist/core/namespaced-rule-name.js +50 -43
- package/dist/core/output-style.d.ts +1 -1
- package/dist/core/param-rule-reach.d.ts +15 -0
- package/dist/core/param-rule-reach.js +30 -0
- package/dist/core/parent-spec-seat.d.ts +13 -1
- package/dist/core/parent-spec-seat.js +6 -0
- package/dist/core/park-selfcheck.js +1 -0
- package/dist/core/pause-registry.d.ts +16 -5
- package/dist/core/pause-registry.js +6 -2
- package/dist/core/peer-channel.d.ts +70 -0
- package/dist/core/peer-channel.js +1 -0
- package/dist/core/permission-rule-consent.d.ts +30 -5
- package/dist/core/permission-rule-consent.js +147 -50
- package/dist/core/permission-rule-model.d.ts +245 -65
- package/dist/core/permission-rule-model.js +421 -107
- package/dist/core/permission-rule-org.d.ts +6 -2
- package/dist/core/permission-rule-org.js +7 -3
- package/dist/core/permission-rule-provider.d.ts +6 -2
- package/dist/core/permission-rule-provider.js +41 -11
- package/dist/core/permission-rule-store.d.ts +22 -26
- package/dist/core/permission-rule-store.js +12 -6
- package/dist/core/permission-rule-sync.d.ts +11 -2
- package/dist/core/permission-rule-sync.js +11 -3
- package/dist/core/permission-rule-syntax.d.ts +5 -4
- package/dist/core/permission-rule-syntax.js +2 -2
- package/dist/core/permission-rules.d.ts +53 -15
- package/dist/core/permission-rules.js +125 -100
- package/dist/core/persisted-rule-arms.d.ts +6 -4
- package/dist/core/persisted-rule-arms.js +10 -12
- package/dist/core/present-plan-tool.js +3 -1
- package/dist/core/principal-name.d.ts +20 -0
- package/dist/core/principal-name.js +22 -0
- package/dist/core/prompt-section-seat.js +4 -6
- package/dist/core/protocol-http-auth.d.ts +26 -5
- package/dist/core/protocol-http-auth.js +137 -4
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/read-only-shell-table.d.ts +1 -1
- package/dist/core/read-only-shell.d.ts +1 -1
- package/dist/core/retired-keys.d.ts +16 -0
- package/dist/core/retired-keys.js +16 -4
- package/dist/core/rewrite-rejudge.d.ts +60 -0
- package/dist/core/rewrite-rejudge.js +36 -0
- package/dist/core/roles.d.ts +34 -3
- package/dist/core/roles.js +66 -53
- package/dist/core/rule-lane-reads.d.ts +20 -15
- package/dist/core/rule-lane-reads.js +45 -17
- package/dist/core/rule-offer-read.d.ts +53 -0
- package/dist/core/rule-offer-read.js +146 -0
- package/dist/core/rule-owner.d.ts +46 -0
- package/dist/core/rule-owner.js +29 -0
- package/dist/core/runner/advisor-instructions.d.ts +70 -0
- package/dist/core/runner/advisor-instructions.js +61 -0
- package/dist/core/runner/advisor-tool.d.ts +33 -0
- package/dist/core/runner/advisor-tool.js +112 -0
- package/dist/core/runner/announce-once-ledger.d.ts +18 -26
- package/dist/core/runner/announce-once-ledger.js +19 -46
- package/dist/core/runner/approval-feedback.js +6 -3
- package/dist/core/runner/assemble-result.d.ts +2 -1
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/call-hook-stations.d.ts +3 -2
- package/dist/core/runner/caller-roster.d.ts +21 -2
- package/dist/core/runner/caller-roster.js +38 -0
- package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
- package/dist/core/runner/capability-withheld-seat.js +24 -0
- package/dist/core/runner/classifier-ladder.d.ts +33 -13
- package/dist/core/runner/classifier-ladder.js +15 -14
- package/dist/core/runner/compaction-restate.d.ts +10 -6
- package/dist/core/runner/compaction-restate.js +9 -3
- package/dist/core/runner/construction-doors.js +3 -0
- package/dist/core/runner/contracts.d.ts +40 -33
- package/dist/core/runner/conversation-segment.d.ts +28 -0
- package/dist/core/runner/conversation-segment.js +42 -0
- package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
- package/dist/core/runner/cross-boundary-lane.js +58 -34
- package/dist/core/runner/decide-continuation.d.ts +7 -4
- package/dist/core/runner/decide-continuation.js +2 -2
- package/dist/core/runner/denial-limit-arms.d.ts +4 -4
- package/dist/core/runner/denial-limit-arms.js +1 -1
- package/dist/core/runner/derived-route-fallback.d.ts +24 -24
- package/dist/core/runner/derived-route-fallback.js +9 -7
- package/dist/core/runner/file-history-request.d.ts +18 -0
- package/dist/core/runner/file-history-request.js +21 -13
- package/dist/core/runner/file-history-restore.d.ts +45 -0
- package/dist/core/runner/file-history-restore.js +46 -0
- package/dist/core/runner/gate-exit.d.ts +9 -3
- package/dist/core/runner/gate-exit.js +11 -5
- package/dist/core/runner/image.d.ts +7 -17
- package/dist/core/runner/image.js +9 -60
- package/dist/core/runner/initial-run-state.js +1 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.js +38 -15
- package/dist/core/runner/person-path-rows.d.ts +12 -9
- package/dist/core/runner/person-path-rows.js +19 -8
- package/dist/core/runner/prepare-advisor.d.ts +63 -0
- package/dist/core/runner/prepare-advisor.js +77 -0
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
- package/dist/core/runner/prepare-ask-lane.js +5 -2
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
- package/dist/core/runner/prepare-caps-and-workflow.js +5 -4
- package/dist/core/runner/prepare-config-doors.d.ts +31 -38
- package/dist/core/runner/prepare-config-doors.js +57 -34
- package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
- package/dist/core/runner/prepare-defer-classify.js +7 -8
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +48 -8
- package/dist/core/runner/prepare-file-history.js +41 -73
- package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
- package/dist/core/runner/prepare-gate-stations.js +12 -8
- package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
- package/dist/core/runner/prepare-hands-readface.js +15 -14
- package/dist/core/runner/prepare-inherited-gate.d.ts +11 -7
- package/dist/core/runner/prepare-inherited-gate.js +8 -6
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +12 -12
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
- package/dist/core/runner/prepare-policy-chain.js +68 -81
- package/dist/core/runner/prepare-project-context.d.ts +5 -2
- package/dist/core/runner/prepare-project-context.js +6 -3
- package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
- package/dist/core/runner/prepare-prompt-assembly.js +10 -8
- package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
- package/dist/core/runner/prepare-prompt-inputs.js +4 -6
- package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
- package/dist/core/runner/prepare-protocol-tools.js +5 -4
- package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
- package/dist/core/runner/prepare-safety-scan.js +8 -23
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
- package/dist/core/runner/prepare-suspend-saga.js +5 -6
- package/dist/core/runner/prepare-task.d.ts +1 -1
- package/dist/core/runner/prepare-task.js +41 -35
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
- package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
- package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -7
- package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
- package/dist/core/runner/prepare-wiring-manifest.js +3 -3
- package/dist/core/runner/resume-admission.js +1 -1
- package/dist/core/runner/resume-apply.js +11 -12
- package/dist/core/runner/resume-checkpoint-screen.js +3 -0
- package/dist/core/runner/resume-claim.d.ts +4 -2
- package/dist/core/runner/resume-claim.js +15 -8
- package/dist/core/runner/resume-policy-outcome.js +1 -1
- package/dist/core/runner/retired-runner-deps.js +2 -1
- package/dist/core/runner/rewind-files.d.ts +15 -0
- package/dist/core/runner/rewind-files.js +132 -0
- package/dist/core/runner/run-attachment-seats.js +2 -2
- package/dist/core/runner/run-brain-sinks.d.ts +4 -1
- package/dist/core/runner/run-brain-sinks.js +4 -2
- package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
- package/dist/core/runner/run-compaction-machinery.js +2 -12
- package/dist/core/runner/run-git-lane.d.ts +1 -0
- package/dist/core/runner/run-harness-handlers.js +14 -7
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +43 -18
- package/dist/core/runner/run-settle-and-teardown.js +3 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.d.ts +1 -0
- package/dist/core/runner/run-turn-boundary.js +15 -22
- package/dist/core/runner/runtask.d.ts +3 -0
- package/dist/core/runner/runtask.js +8 -9
- package/dist/core/runner/session-read-file-states.d.ts +15 -0
- package/dist/core/runner/session-read-file-states.js +28 -0
- package/dist/core/runner/session-rule-policy.d.ts +22 -21
- package/dist/core/runner/session-rule-policy.js +17 -31
- package/dist/core/runner/shell-env-withheld.d.ts +33 -0
- package/dist/core/runner/shell-env-withheld.js +51 -0
- package/dist/core/runner/side-call-account.d.ts +32 -8
- package/dist/core/runner/side-call-account.js +23 -1
- package/dist/core/runner/skills-seat.js +6 -2
- package/dist/core/runner/stream-settle-backstop.js +1 -1
- package/dist/core/runner/strict-output-schema.d.ts +1 -1
- package/dist/core/runner/sub-agent-deny-lists.js +4 -6
- package/dist/core/runner/synthetic-tools.d.ts +16 -13
- package/dist/core/runner/synthetic-tools.js +8 -3
- package/dist/core/runner/tool-disclosure.d.ts +10 -12
- package/dist/core/runner/tool-disclosure.js +3 -4
- package/dist/core/runner/tool-end-body.d.ts +1 -1
- package/dist/core/runner/tool-end-body.js +10 -9
- package/dist/core/runner/tool-face-overlay.d.ts +2 -1
- package/dist/core/runner/tool-face-overlay.js +17 -1
- package/dist/core/runner/tool-not-executed.d.ts +5 -0
- package/dist/core/runner/tool-not-executed.js +11 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -0
- package/dist/core/runner/tool-occurrence.js +7 -0
- package/dist/core/runner/tool-progress-lane.d.ts +2 -2
- package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
- package/dist/core/runner/turn-attachments.d.ts +91 -80
- package/dist/core/runner/turn-attachments.js +62 -37
- package/dist/core/runner-deps.d.ts +42 -42
- package/dist/core/runtime-caps.d.ts +4 -4
- package/dist/core/safety-axis-vocab.d.ts +6 -4
- package/dist/core/safety-axis-vocab.js +6 -5
- package/dist/core/safety-merge-corpus.js +26 -2
- package/dist/core/same-plain-value.d.ts +40 -0
- package/dist/core/same-plain-value.js +49 -0
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/secret-env.d.ts +26 -3
- package/dist/core/secret-env.js +44 -8
- package/dist/core/select-model.js +3 -3
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +1 -1
- package/dist/core/session-policy-store.d.ts +102 -35
- package/dist/core/session-policy-store.js +210 -48
- package/dist/core/session-reconcile.d.ts +2 -2
- package/dist/core/session-store.d.ts +106 -37
- package/dist/core/session-store.js +165 -91
- package/dist/core/session.d.ts +101 -57
- package/dist/core/session.js +53 -0
- package/dist/core/shared-memory/tools.js +3 -1
- package/dist/core/shared-memory/types.d.ts +1 -1
- package/dist/core/shell-read-silence.d.ts +11 -12
- package/dist/core/shell-read-silence.js +9 -5
- package/dist/core/shell-run-candidates.js +3 -1
- package/dist/core/shell-wrapper-projection.js +1 -1
- package/dist/core/shell-wrapper-table.d.ts +14 -7
- package/dist/core/shell-wrapper-table.js +5 -4
- package/dist/core/side-query.d.ts +10 -0
- package/dist/core/side-query.js +15 -1
- package/dist/core/skill-grant.d.ts +7 -2
- package/dist/core/skill-grant.js +5 -0
- package/dist/core/skills-directory.js +6 -2
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +168 -3
- package/dist/core/store-contracts/file-history-store-contract.js +74 -4
- package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
- package/dist/core/store-contracts/peer-directory-contract.js +14 -2
- package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
- package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
- package/dist/core/store-contracts/session-repo-contract.js +176 -0
- package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
- package/dist/core/store-contracts/session-store-contract.js +361 -51
- package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
- package/dist/core/stub-env.d.ts +2 -0
- package/dist/core/stub-env.js +1 -0
- package/dist/core/surrogate-safe-slice.d.ts +3 -3
- package/dist/core/synthetic-read-verdict.js +3 -3
- package/dist/core/task-event.d.ts +42 -8
- package/dist/core/task-notification.d.ts +19 -15
- package/dist/core/task-registry-agent.d.ts +4 -4
- package/dist/core/task-registry-shared.d.ts +4 -4
- package/dist/core/task-registry-shared.js +1 -0
- package/dist/core/task-registry.d.ts +13 -4
- package/dist/core/task-registry.js +14 -2
- package/dist/core/task-result.d.ts +21 -3
- package/dist/core/task-spec.d.ts +69 -64
- package/dist/core/task-stream.d.ts +6 -6
- package/dist/core/task-tool-shape.d.ts +4 -4
- package/dist/core/tighten-task-spec.d.ts +1 -1
- package/dist/core/tighten-task-spec.js +2 -1
- package/dist/core/tool-catalog-entries.d.ts +36 -2
- package/dist/core/tool-catalog-entries.js +69 -43
- package/dist/core/tool-check-reading.d.ts +11 -0
- package/dist/core/tool-check-reading.js +11 -6
- package/dist/core/tool-conformance.js +1 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-face-reader.js +5 -3
- package/dist/core/tool-face.d.ts +21 -2
- package/dist/core/tool-face.js +1 -1
- package/dist/core/tool-model-gate.d.ts +5 -5
- package/dist/core/tool-name-aliases.d.ts +29 -8
- package/dist/core/tool-name-aliases.js +22 -4
- package/dist/core/tool-name-readings.d.ts +10 -43
- package/dist/core/tool-name-readings.js +2 -11
- package/dist/core/tool-policy.d.ts +85 -196
- package/dist/core/tool-policy.js +150 -175
- package/dist/core/tool-registry.d.ts +14 -7
- package/dist/core/tool-registry.js +17 -7
- package/dist/core/tool-result-store.js +5 -1
- package/dist/core/tool-roster.d.ts +57 -33
- package/dist/core/tool-roster.js +56 -68
- package/dist/core/tool-spec-members.js +8 -3
- package/dist/core/tool-spec.d.ts +53 -31
- package/dist/core/tools.js +51 -10
- package/dist/core/trace.d.ts +6 -2
- package/dist/core/types.d.ts +1 -1
- package/dist/core/untrusted-egress.d.ts +1 -1
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/user-attachment.d.ts +8 -1
- package/dist/core/user-attachment.js +64 -4
- package/dist/core/warm-resume.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +58 -0
- package/dist/core/wiring-manifest.js +14 -5
- package/dist/core/workflow-journal-store.d.ts +62 -0
- package/dist/core/workflow-journal-store.js +78 -2
- package/dist/core/workflow-run-store.d.ts +6 -0
- package/dist/core/workflow-run-store.js +2 -0
- package/dist/engine/compaction/compaction.d.ts +9 -9
- package/dist/engine/compaction/compaction.js +3 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
- package/dist/engine/execution-env/node-execution-env.js +54 -24
- package/dist/engine/harness/agent-harness.d.ts +39 -9
- package/dist/engine/harness/agent-harness.js +87 -33
- package/dist/engine/harness/types.d.ts +58 -9
- package/dist/engine/harness/types.js +12 -1
- package/dist/engine/llm/types.d.ts +36 -19
- package/dist/engine/llm/validation.d.ts +4 -1
- package/dist/engine/llm/validation.js +13 -1
- package/dist/engine/loop/agent-loop.d.ts +23 -1
- package/dist/engine/loop/agent-loop.js +26 -34
- package/dist/engine/loop/types.d.ts +31 -19
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/memory-repo.d.ts +18 -12
- package/dist/engine/session/memory-repo.js +24 -9
- package/dist/engine/session/parent-chain-guard.d.ts +3 -2
- package/dist/engine/session/parent-chain-guard.js +1 -1
- package/dist/engine/session/repo-utils.d.ts +32 -3
- package/dist/engine/session/repo-utils.js +50 -5
- package/dist/index.d.ts +47 -23
- package/dist/index.js +35 -17
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/harness.d.ts +3 -3
- package/dist/internal/harness.js +2 -2
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +8 -6
- package/dist/orchestration/run-workflow-tool.js +10 -6
- package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
- package/dist/orchestration/workflow-types.d.ts +18 -0
- package/dist/orchestration/workflow-types.js +6 -0
- package/dist/orchestration/workflow.d.ts +5 -13
- package/dist/orchestration/workflow.js +57 -49
- package/dist/prompt-assembly/artifact.d.ts +2 -2
- package/dist/prompt-assembly/artifact.js +5 -3
- package/dist/prompt-assembly/assemble.d.ts +3 -2
- package/dist/prompt-assembly/assemble.js +1 -1
- package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
- package/dist/prompt-assembly/catalog/schema.js +34 -2
- package/dist/prompt-assembly/catalog/sections.js +0 -1
- package/dist/prompt-assembly/composer.d.ts +3 -1
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/event-registry.js +2 -0
- package/dist/prompt-assembly/overlay.js +3 -3
- package/dist/prompt-assembly/renderers.d.ts +1 -1
- package/dist/prompt-assembly/renderers.js +0 -3
- package/dist/prompt-assembly/role-base.d.ts +15 -0
- package/dist/prompt-assembly/role-base.js +9 -0
- package/dist/prompt-assembly/select.d.ts +39 -14
- package/dist/prompt-assembly/select.js +47 -16
- package/dist/prompt-assembly/sugar.d.ts +17 -11
- package/dist/prompt-assembly/sugar.js +8 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +39 -2
- package/dist/prompt-assembly/tool-catalog.js +117 -4
- package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
- package/dist/prompt-assembly/turn-snapshot.js +0 -3
- package/dist/prompt-assembly/types.d.ts +0 -7
- package/dist/prompts/default.d.ts +14 -14
- package/dist/scenarios/full-body.d.ts +15 -15
- package/dist/scenarios/full-body.js +4 -3
- package/dist/shell/lex.js +10 -1
- package/dist/stores/file/adoption/adopt.d.ts +4 -3
- package/dist/stores/file/adoption/adopt.js +27 -33
- package/dist/stores/file/adoption/marker.d.ts +6 -13
- package/dist/stores/file/adoption/marker.js +9 -17
- package/dist/stores/file/checkpoint-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.js +45 -7
- package/dist/stores/file/file-history-store.d.ts +20 -19
- package/dist/stores/file/file-history-store.js +157 -141
- package/dist/stores/file/fs-atomic.d.ts +15 -0
- package/dist/stores/file/fs-atomic.js +89 -14
- package/dist/stores/file/index.d.ts +1 -1
- package/dist/stores/file/index.js +2 -1
- package/dist/stores/file/mailbox-store.d.ts +3 -0
- package/dist/stores/file/mailbox-store.js +3 -1
- package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
- package/dist/stores/file/permission-rule-adopt.js +18 -18
- package/dist/stores/file/permission-rule-store.d.ts +18 -2
- package/dist/stores/file/permission-rule-store.js +31 -18
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/stores/file/session-store.d.ts +54 -16
- package/dist/stores/file/session-store.js +114 -85
- package/dist/stores/file/workflow-journal-store.d.ts +10 -4
- package/dist/stores/file/workflow-journal-store.js +28 -13
- package/dist/tools/artifact/artifact-text.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +5 -3
- package/dist/tools/fs/bash-program-position.d.ts +19 -2
- package/dist/tools/fs/bash-program-position.js +56 -9
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
- package/dist/tools/fs/fs-bash.d.ts +2 -2
- package/dist/tools/fs/fs-bash.js +8 -6
- package/dist/tools/fs/fs-glob.d.ts +86 -0
- package/dist/tools/fs/fs-glob.js +226 -0
- package/dist/tools/fs/fs-read.js +14 -14
- package/dist/tools/fs/fs-search-tools.js +7 -7
- package/dist/tools/fs/fs-shared.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/notebook.d.ts +2 -2
- package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
- package/dist/tools/fs/pattern-kill-guard.js +397 -0
- package/dist/tools/fs/pdf.d.ts +9 -6
- package/dist/tools/fs/pdf.js +3 -3
- package/dist/tools/fs/program-read-model.d.ts +57 -7
- package/dist/tools/fs/program-read-model.js +11 -1
- package/dist/tools/fs/program-read-model.rows.js +78 -21
- package/dist/tools/fs/read-deny-home.js +3 -2
- package/dist/tools/fs/read-deny.d.ts +29 -7
- package/dist/tools/fs/read-deny.js +63 -22
- package/dist/tools/fs/removal-targets.d.ts +18 -8
- package/dist/tools/fs/removal-targets.js +47 -20
- package/dist/tools/fs/safety.d.ts +9 -9
- package/dist/tools/fs/search.d.ts +16 -6
- package/dist/tools/fs/search.js +20 -26
- package/dist/tools/fs/shell-read-argv.js +89 -12
- package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
- package/dist/tools/fs/shell-read-bindings.js +41 -0
- package/dist/tools/fs/shell-read-check.js +12 -20
- package/dist/tools/fs/shell-read-environment.d.ts +5 -1
- package/dist/tools/fs/shell-read-environment.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +15 -0
- package/dist/tools/fs/shell-read-establish.js +19 -20
- package/dist/tools/fs/shell-read-judge.d.ts +4 -0
- package/dist/tools/fs/shell-read-judge.js +5 -2
- package/dist/tools/fs/shell-read-plan.js +24 -16
- package/dist/tools/fs/shell-read-start.d.ts +6 -1
- package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
- package/dist/tools/fs/shell-read-write-targets.js +2 -3
- package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
- package/dist/tools/fs/shell-reentry-text.js +40 -2
- package/dist/tools/loop-tick.d.ts +2 -2
- package/dist/tools/scheduler-tools.js +5 -1
- package/dist/tools/task-list.d.ts +7 -7
- package/dist/tools/task-list.js +5 -1
- package/dist/tools/todo.js +65 -64
- package/dist/tools/web.d.ts +20 -15
- package/dist/tools/web.js +55 -69
- package/dist/tools/worktree.d.ts +3 -3
- package/dist/tools/worktree.js +3 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +5894 -5638
- package/wire-changes/core@7.55.0.json +3318 -0
- package/wire-changes/core@7.56.0.json +3891 -0
- package/wire-changes/mods-kernel@7.56.0.json +303 -0
- package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
- package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
package/dist/core/mcp.js
CHANGED
|
@@ -2,15 +2,18 @@ import { egressText } from "./untrusted-egress.js";
|
|
|
2
2
|
import { __resetEnvKnobAnnouncements } from "./env-knob-announce.js";
|
|
3
3
|
import { resolveEnvBudget } from "./env-budget.js";
|
|
4
4
|
import { MCP_NAMESPACE } from "./protocol-table.js";
|
|
5
|
-
import { resolveProtocolHttpHeaders } from "./protocol-http-auth.js";
|
|
5
|
+
import { declaredHeaderValues, resolveProtocolHttpHeaders, scrubRequestEcho } from "./protocol-http-auth.js";
|
|
6
6
|
import { disposeSectionEntry, sectionAnswerWarning } from "./prompt-section-seat.js";
|
|
7
7
|
import { findNamespacePrefixCollision, mintNamespacePrefix, mintNamespacedToolName, normalizeNameSegment } from "./protocol-naming.js";
|
|
8
8
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
9
9
|
import { McpConnectionPool } from "./mcp-connection-pool.js";
|
|
10
|
+
import { SessionEndingTransport, requestSite } from "./mcp-session-end.js";
|
|
11
|
+
import { mcpToolGate, UNPROVEN_GATE } from "./mcp-listing-drift.js";
|
|
12
|
+
import { ConnectionListing, Flights, IDLE_WATCHDOG_ABORT_REASON, Resendable, armMcpIdleWatchdog, callThroughLink, listingRefusal } from "./mcp-server-link.js";
|
|
13
|
+
import { underStartupBound } from "./mcp-startup-request.js";
|
|
10
14
|
import { LIST_MCP_RESOURCES, MCP_RESOURCE_LIST_ALLOW, MCP_RESOURCE_READ_ALLOW, READ_MCP_RESOURCE, READ_MCP_RESOURCE_DIR, retractInstructions, tellInstructions, toldOnDial, unretractInstructions, withdrawInstructionAdds } from "./mounted-mcp.js";
|
|
11
15
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
12
|
-
import {
|
|
13
|
-
import { classifyMcpFailure, describeHttpTransportFailure, livenessOf } from "./mcp-failure.js";
|
|
16
|
+
import { classifyMcpFailure, describeHttpTransportFailure, livenessOf, namingLostSession, sessionGone } from "./mcp-failure.js";
|
|
14
17
|
import { lstat, mkdir, writeFile } from "node:fs/promises";
|
|
15
18
|
import { tmpdir } from "node:os";
|
|
16
19
|
import { join } from "node:path";
|
|
@@ -19,6 +22,7 @@ import { DEFAULT_REQUEST_TIMEOUT_MSEC } from "@modelcontextprotocol/sdk/shared/p
|
|
|
19
22
|
import { MCP_IMAGE_MAX_BASE64, sharpImageResizer } from "./image-downsample.js";
|
|
20
23
|
import { sliceHeadSafe, sliceTailSafe } from "./surrogate-safe-slice.js";
|
|
21
24
|
import { truncateError } from "./tool-errors.js";
|
|
25
|
+
import { peerRequestRefusal } from "./host-floor.js";
|
|
22
26
|
import { delimitUntrusted, inlineUntrusted, sanitizeUntrustedText } from "./untrusted-text.js";
|
|
23
27
|
import { discloseReminderShaped, observeReminderMarkEcho } from "./reminder-disclosure.js";
|
|
24
28
|
import { MARKED_BLOCK_AFTER_DATA } from "./reminder-mint.js";
|
|
@@ -128,33 +132,6 @@ export function mcpIdleTimeoutMs(kind) {
|
|
|
128
132
|
function idleKindOf(kind) {
|
|
129
133
|
return kind === "stdio" ? "stdio" : "http";
|
|
130
134
|
}
|
|
131
|
-
const IDLE_WATCHDOG_ABORT_REASON = Symbol("mcp-idle-watchdog-abort");
|
|
132
|
-
function armMcpIdleWatchdog(health, idleMs, outerSignal) {
|
|
133
|
-
const idleController = new AbortController();
|
|
134
|
-
let timer;
|
|
135
|
-
const rearm = () => {
|
|
136
|
-
if (timer !== undefined)
|
|
137
|
-
clearTimeout(timer);
|
|
138
|
-
const armedAt = Date.now();
|
|
139
|
-
timer = setTimeout(() => {
|
|
140
|
-
if (health.pendingElicitations > 0 || health.lastElicitationClosedAt > armedAt) {
|
|
141
|
-
rearm();
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
idleController.abort(IDLE_WATCHDOG_ABORT_REASON);
|
|
145
|
-
}, idleMs);
|
|
146
|
-
};
|
|
147
|
-
rearm();
|
|
148
|
-
return {
|
|
149
|
-
combinedSignal: outerSignal !== undefined ? AbortSignal.any([outerSignal, idleController.signal]) : idleController.signal,
|
|
150
|
-
idleSignal: idleController.signal,
|
|
151
|
-
rearm,
|
|
152
|
-
dispose: () => {
|
|
153
|
-
if (timer !== undefined)
|
|
154
|
-
clearTimeout(timer);
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
135
|
export function mcpStartupTimeoutMs(server) {
|
|
159
136
|
const fromEnv = parseEnvMs("MCP_TIMEOUT");
|
|
160
137
|
const own = server?.startupTimeoutMs;
|
|
@@ -185,21 +162,24 @@ export function collapseMcpErrorPrefix(message) {
|
|
|
185
162
|
out = out.slice(m[0].length);
|
|
186
163
|
}
|
|
187
164
|
}
|
|
188
|
-
function sanitizeMcpErrorTextInPlace(err) {
|
|
165
|
+
function sanitizeMcpErrorTextInPlace(err, declared) {
|
|
189
166
|
if (!(err instanceof Error))
|
|
190
167
|
return;
|
|
191
|
-
const sanitized =
|
|
168
|
+
const sanitized = mcpRemoteText(err instanceof McpError ? collapseMcpErrorPrefix(err.message) : err.message, declared);
|
|
192
169
|
if (sanitized !== err.message)
|
|
193
170
|
err.message = sanitized;
|
|
194
171
|
}
|
|
195
|
-
function namedMcpFailureText(err) {
|
|
196
|
-
const detail = remoteErrorText(err, { collapse: true });
|
|
172
|
+
function namedMcpFailureText(err, declared) {
|
|
173
|
+
const detail = remoteErrorText(err, declared, { collapse: true });
|
|
197
174
|
const condition = thrownIs(err, McpError) ? describeMcpSpecErrorCode(readMember(err, "code")) : undefined;
|
|
198
175
|
return condition !== undefined ? `${condition}: ${detail}` : detail;
|
|
199
176
|
}
|
|
200
|
-
function remoteErrorText(err, opts) {
|
|
177
|
+
function remoteErrorText(err, declared, opts) {
|
|
201
178
|
const raw = thrownText(err);
|
|
202
|
-
return
|
|
179
|
+
return mcpRemoteText(opts?.collapse === true ? collapseMcpErrorPrefix(raw) : raw, declared);
|
|
180
|
+
}
|
|
181
|
+
function mcpRemoteText(text, declared) {
|
|
182
|
+
return egressText("same-principal", scrubRequestEcho(text, declared));
|
|
203
183
|
}
|
|
204
184
|
function writeEffectWarning(writeEffect) {
|
|
205
185
|
return writeEffect
|
|
@@ -218,7 +198,7 @@ function rethrowHonestMcpError(err, ctx) {
|
|
|
218
198
|
}
|
|
219
199
|
throw e;
|
|
220
200
|
};
|
|
221
|
-
sanitizeMcpErrorTextInPlace(err);
|
|
201
|
+
sanitizeMcpErrorTextInPlace(err, ctx.declared);
|
|
222
202
|
if (ctx.idle?.signal.reason === IDLE_WATCHDOG_ABORT_REASON) {
|
|
223
203
|
ctx.liveness?.observe?.("timeout");
|
|
224
204
|
const serverLabel = inlineUntrusted(ctx.server);
|
|
@@ -231,7 +211,7 @@ function rethrowHonestMcpError(err, ctx) {
|
|
|
231
211
|
finish(err);
|
|
232
212
|
const serverLabel = inlineUntrusted(ctx.server);
|
|
233
213
|
const fenceServerText = (label, raw) => delimitUntrusted(label, truncateMcpErrorText(raw));
|
|
234
|
-
const failure = classifyMcpFailure(err,
|
|
214
|
+
const failure = classifyMcpFailure(err, ctx.site);
|
|
235
215
|
ctx.liveness?.observe?.(failure.kind);
|
|
236
216
|
const details = (extra) => ({ code: failure.kind, delivered: failure.delivered, server: ctx.server, ...extra });
|
|
237
217
|
switch (failure.kind) {
|
|
@@ -248,12 +228,14 @@ function rethrowHonestMcpError(err, ctx) {
|
|
|
248
228
|
case "not_mcp_response":
|
|
249
229
|
case "connect_refused":
|
|
250
230
|
case "connection_failed": {
|
|
251
|
-
const httpFailure = describeHttpTransportFailure(err);
|
|
252
|
-
const detail = remoteErrorText(err);
|
|
231
|
+
const httpFailure = describeHttpTransportFailure(err, ctx.site);
|
|
232
|
+
const detail = remoteErrorText(err, ctx.declared);
|
|
253
233
|
const fenced = `\nThe transport error follows as external/untrusted data:\n${fenceServerText(`${ctx.server} transport error`, detail)}`;
|
|
254
|
-
finish(markMcpFailure(new Error(
|
|
255
|
-
? `${ctx.what}
|
|
256
|
-
:
|
|
234
|
+
finish(markMcpFailure(new Error(sessionGone(err, ctx.site)
|
|
235
|
+
? `${ctx.what} met a lost session on MCP server "${serverLabel}": ${httpFailure.condition}; ${ctx.resent === true ? "the call was sent again once on a fresh session, and the server reported that one gone too — if the server executed it before answering, it ran twice" : "the call was not sent again — if the server executed it before answering, it ran"}. The outcome is unknown.${writeEffectWarning(ctx.writeEffect)}${fenced}`
|
|
236
|
+
: failure.delivered === "no"
|
|
237
|
+
? `${ctx.what} could not reach MCP server "${serverLabel}": ${httpFailure.condition}. The request was not delivered, so the server did not execute it. This server's tools and resources will keep failing until its endpoint is reachable again — do not retry them; use an alternative if one exists.${fenced}`
|
|
238
|
+
: `${ctx.what} failed at the transport layer of MCP server "${serverLabel}": ${httpFailure.condition}. The request may or may not have executed on the server — the outcome is unknown.${writeEffectWarning(ctx.writeEffect)}${fenced}`, { cause: err }), details(failure.httpStatus !== undefined ? { httpStatus: failure.httpStatus } : undefined)));
|
|
257
239
|
}
|
|
258
240
|
case "protocol": {
|
|
259
241
|
const code = err.code;
|
|
@@ -262,7 +244,7 @@ function rethrowHonestMcpError(err, ctx) {
|
|
|
262
244
|
finish(markMcpFailure(new Error(`${ctx.what} on MCP server "${serverLabel}" was rejected with MCP protocol error ${code} — ${condition}. The server's error text follows as external/untrusted data:\n${fenceServerText(`${ctx.server} error`, err.message)}`, { cause: err }), details({ specErrorCode: code })));
|
|
263
245
|
}
|
|
264
246
|
if (ctx.attributeServer) {
|
|
265
|
-
finish(markMcpFailure(new Error(`${ctx.what} on MCP server "${serverLabel}" failed. The server's error text follows as external/untrusted data:\n${fenceServerText(`${ctx.server} error`, remoteErrorText(err))}`, { cause: err }), details()));
|
|
247
|
+
finish(markMcpFailure(new Error(`${ctx.what} on MCP server "${serverLabel}" failed. The server's error text follows as external/untrusted data:\n${fenceServerText(`${ctx.server} error`, remoteErrorText(err, ctx.declared))}`, { cause: err }), details()));
|
|
266
248
|
}
|
|
267
249
|
finish(markMcpFailure(err, details()));
|
|
268
250
|
}
|
|
@@ -270,7 +252,7 @@ function rethrowHonestMcpError(err, ctx) {
|
|
|
270
252
|
case "invalid_config":
|
|
271
253
|
case "unknown": {
|
|
272
254
|
if (ctx.attributeServer) {
|
|
273
|
-
finish(markMcpFailure(new Error(`${ctx.what} on MCP server "${serverLabel}" failed. The server's error text follows as external/untrusted data:\n${fenceServerText(`${ctx.server} error`, remoteErrorText(err))}`, { cause: err }), details()));
|
|
255
|
+
finish(markMcpFailure(new Error(`${ctx.what} on MCP server "${serverLabel}" failed. The server's error text follows as external/untrusted data:\n${fenceServerText(`${ctx.server} error`, remoteErrorText(err, ctx.declared))}`, { cause: err }), details()));
|
|
274
256
|
}
|
|
275
257
|
if (err instanceof Error)
|
|
276
258
|
finish(markMcpFailure(err, details()));
|
|
@@ -396,7 +378,7 @@ function buildTransport(spec, principal, kind) {
|
|
|
396
378
|
if (!("url" in t))
|
|
397
379
|
throw new Error(`MCP server "${spec.name}": transport kind "${String(kind)}" carries no url`);
|
|
398
380
|
const headers = resolveProtocolHttpHeaders(MCP_NAMESPACE.id, t, principal);
|
|
399
|
-
return new
|
|
381
|
+
return new SessionEndingTransport(new URL(t.url), {
|
|
400
382
|
requestInit: headers ? { headers } : undefined,
|
|
401
383
|
fetch: declaredEndpointFetch,
|
|
402
384
|
});
|
|
@@ -663,7 +645,7 @@ export function mcpToolSchemaProblem(schema) {
|
|
|
663
645
|
}
|
|
664
646
|
return undefined;
|
|
665
647
|
}
|
|
666
|
-
export async function materializeMcpTools(specs, principal, onElicit, imageResizer, reminderDisclosure, mcpRevocations, poolOpts, promptSections, dialable) {
|
|
648
|
+
export async function materializeMcpTools(specs, principal, onElicit, imageResizer, reminderDisclosure, mcpRevocations, poolOpts, promptSections, dialable, signal, hostFloor) {
|
|
667
649
|
const snapshot = snapshotMcpEntries(specs);
|
|
668
650
|
const axesRefused = new WeakMap();
|
|
669
651
|
const entries = snapshot.map((spec) => {
|
|
@@ -722,11 +704,10 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
|
|
|
722
704
|
const droppedTools = [];
|
|
723
705
|
let disposing = false;
|
|
724
706
|
const serverHandles = [];
|
|
725
|
-
const redialsInFlight = new Set();
|
|
726
707
|
const commitConnectedServer = (spec, s, transportKind) => {
|
|
727
708
|
const raised = [];
|
|
728
709
|
connections.push({ client: s.client, close: s.close });
|
|
729
|
-
const handle = { name: spec.name, spec, client: s.client, openListing: s.openListing, health: s.health, tools: s.tools,
|
|
710
|
+
const handle = { name: spec.name, spec, client: s.client, openListing: s.openListing, health: s.health, tools: s.tools, listing: s.listing, gatesAt: s.gatesAt, gates: () => gatesNow(handle), transportKind, announce: s.announce, instructions: s.instructions };
|
|
730
711
|
const hIdx = serverHandles.findIndex((h) => h.name === spec.name);
|
|
731
712
|
if (hIdx === -1)
|
|
732
713
|
serverHandles.push(handle);
|
|
@@ -786,11 +767,37 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
|
|
|
786
767
|
}
|
|
787
768
|
};
|
|
788
769
|
const dialKinds = entries.map(readDialKind);
|
|
770
|
+
const liveOf = (server) => serverHandles.find((h) => h.name === server);
|
|
771
|
+
const gatesNow = (h) => {
|
|
772
|
+
const latest = h.listing.latest();
|
|
773
|
+
if (latest.at !== h.gatesAt.at)
|
|
774
|
+
h.gatesAt = { at: latest.at, gates: intakeListedTools({ tools: [...latest.entries], unproven: latest.unproven }, h.spec, linkOf(h.name), echoOf(h.spec), imageResizer, mcpDisclosure, isServerRevoked, h.transportKind).gates };
|
|
775
|
+
return h.gatesAt.gates;
|
|
776
|
+
};
|
|
777
|
+
const linkOf = (server) => ({
|
|
778
|
+
live: () => liveOf(server),
|
|
779
|
+
recover: (lost) => redialFlights.running(server) ?? (liveOf(server) === lost ? redialFlights.start(server, () => redialDial(server)) : Promise.resolve()),
|
|
780
|
+
});
|
|
781
|
+
const endpointRefusal = (spec, dialKind) => {
|
|
782
|
+
const transport = spec.transport;
|
|
783
|
+
const raw = dialKind !== "stdio" && typeof transport === "object" && transport !== null && "url" in transport ? transport.url : undefined;
|
|
784
|
+
let url;
|
|
785
|
+
try {
|
|
786
|
+
if (typeof raw !== "string")
|
|
787
|
+
return undefined;
|
|
788
|
+
url = new URL(raw);
|
|
789
|
+
}
|
|
790
|
+
catch {
|
|
791
|
+
return undefined;
|
|
792
|
+
}
|
|
793
|
+
return peerRequestRefusal(`mcp: server "${inlineUntrusted(spec.name, 120)}"`, url, hostFloor);
|
|
794
|
+
};
|
|
789
795
|
const dialServer = (spec, dialKind, dialOpts) => {
|
|
790
|
-
const refusal = axesRefused.get(spec);
|
|
791
|
-
return refusal !== undefined ? Promise.reject(refusal) : connectServer(spec, principal, onElicit, imageResizer, mcpDisclosure, isServerRevoked, dialKind, poolOpts?.pool, dialOpts);
|
|
796
|
+
const refusal = axesRefused.get(spec) ?? endpointRefusal(spec, dialKind);
|
|
797
|
+
return refusal !== undefined ? Promise.reject(refusal) : connectServer(spec, principal, onElicit, imageResizer, mcpDisclosure, isServerRevoked, dialKind, poolOpts?.pool, { ...dialOpts, link: linkOf(spec.name), ...(signal !== undefined ? { signal } : {}) });
|
|
792
798
|
};
|
|
793
799
|
const prefixOf = (name) => mintNamespacePrefix(MCP_NAMESPACE, name);
|
|
800
|
+
const echoOf = (spec) => declaredHeaderValues(spec.transport, principal);
|
|
794
801
|
const heldCount = (name) => serverHandles.find((h) => h.name === name)?.tools.length ?? 0;
|
|
795
802
|
const reconcileInstructions = (name, after, connected) => {
|
|
796
803
|
if (!connected)
|
|
@@ -820,10 +827,11 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
|
|
|
820
827
|
commitConnectedServer(spec, s, dialKinds[i]);
|
|
821
828
|
}
|
|
822
829
|
else {
|
|
823
|
-
|
|
830
|
+
const declared = echoOf(spec);
|
|
831
|
+
warnings.push(asServerWarning(spec, r.reason, declared));
|
|
824
832
|
const { kind, delivered, httpStatus } = classifyMcpFailure(r.reason, { phase: "connect", transport: dialKinds[i] });
|
|
825
833
|
const liveness = livenessOf(kind, Date.now());
|
|
826
|
-
statuses.push({ name: spec.name, status: "failed", errorCode: kind, delivered, ...(httpStatus !== undefined ? { httpStatus } : {}), error: namedMcpFailureText(r.reason), ...(liveness !== undefined ? { liveness } : {}) });
|
|
834
|
+
statuses.push({ name: spec.name, status: "failed", errorCode: kind, delivered, ...(httpStatus !== undefined ? { httpStatus } : {}), error: namedMcpFailureText(r.reason, declared), ...(liveness !== undefined ? { liveness } : {}) });
|
|
827
835
|
}
|
|
828
836
|
}
|
|
829
837
|
const resourceTools = buildResourceTools(resourceServers, isServerRevoked);
|
|
@@ -834,89 +842,89 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
|
|
|
834
842
|
await Promise.allSettled(settled.map((r) => (r.status === "fulfilled" && r.value !== null ? r.value.close() : Promise.resolve())));
|
|
835
843
|
throw mergeErr;
|
|
836
844
|
}
|
|
837
|
-
const
|
|
845
|
+
const declineRedial = (server, outcome, reason) => ({ server, prefix: prefixOf(server), outcome, reason, toolCount: heldCount(server), added: [], removed: [] });
|
|
846
|
+
const redialFlights = new Flights();
|
|
847
|
+
const ownerStopped = () => (disposing ? "this materialization is being disposed — the task is tearing down" : signal?.aborted === true ? "the run was aborted" : undefined);
|
|
848
|
+
const redialDial = async (server) => {
|
|
838
849
|
const prefix = prefixOf(server);
|
|
839
|
-
const declined = (outcome, reason) => (
|
|
840
|
-
|
|
841
|
-
|
|
850
|
+
const declined = (outcome, reason) => declineRedial(server, outcome, reason);
|
|
851
|
+
const stopped = ownerStopped();
|
|
852
|
+
if (stopped !== undefined)
|
|
853
|
+
return declined("refused", stopped);
|
|
842
854
|
const spec = entries.find((e) => e.name === server);
|
|
843
855
|
if (spec === undefined)
|
|
844
856
|
return declined("not_declared", `no MCP server named ${inlineUntrusted(server, 120)} is declared for this task`);
|
|
845
857
|
if (isServerRevoked(server))
|
|
846
858
|
return declined("refused", "server revoked by the operator — the re-dial did not contact it");
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
prefix,
|
|
882
|
-
outcome: "refused",
|
|
883
|
-
reason: inlineUntrusted(namedMcpFailureText(err), 240),
|
|
884
|
-
toolCount: 0,
|
|
885
|
-
added: [],
|
|
886
|
-
removed: priorNames,
|
|
887
|
-
tools: [],
|
|
888
|
-
axes: [],
|
|
889
|
-
dropped: [],
|
|
890
|
-
warnings: [raised.message],
|
|
891
|
-
status,
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
if (disposing) {
|
|
895
|
-
await connected.close().catch(() => undefined);
|
|
896
|
-
return declined("refused", "this materialization was disposed while the re-dial was in flight — the new connection was closed");
|
|
897
|
-
}
|
|
898
|
-
const raised = commitConnectedServer(spec, connected, dialKind);
|
|
899
|
-
reconcileInstructions(server, connected.instructions, true);
|
|
900
|
-
const newNames = connected.tools.map((t) => t.name);
|
|
859
|
+
const hIdx = serverHandles.findIndex((h) => h.name === server);
|
|
860
|
+
const prior = hIdx === -1 ? undefined : serverHandles[hIdx];
|
|
861
|
+
const priorNames = prior ? prior.tools.map((t) => t.name) : [];
|
|
862
|
+
if (prior) {
|
|
863
|
+
prior.announce.fn = undefined;
|
|
864
|
+
prior.health.observe = undefined;
|
|
865
|
+
serverHandles.splice(hIdx, 1);
|
|
866
|
+
const cIdx = connections.findIndex((c) => c.client === prior.client);
|
|
867
|
+
const priorConnection = cIdx === -1 ? undefined : connections.splice(cIdx, 1)[0];
|
|
868
|
+
await (priorConnection?.close() ?? prior.client.close()).catch(() => undefined);
|
|
869
|
+
}
|
|
870
|
+
const dialKind = readDialKind(spec);
|
|
871
|
+
const dialed = await dialServer(spec, dialKind, { fresh: true, sections: promptSections, ...(prior !== undefined ? { carried: prior.listing.latest().entries } : {}) }).then((connected) => ({ connected }), (err) => ({ err }));
|
|
872
|
+
const stoppedLate = ownerStopped();
|
|
873
|
+
if (stoppedLate !== undefined) {
|
|
874
|
+
if ("connected" in dialed)
|
|
875
|
+
await dialed.connected.close().catch(() => undefined);
|
|
876
|
+
return declined("refused", `${stoppedLate} while the re-dial was in flight — nothing new was kept or recorded`);
|
|
877
|
+
}
|
|
878
|
+
if ("err" in dialed) {
|
|
879
|
+
const err = dialed.err;
|
|
880
|
+
const { kind, delivered, httpStatus } = classifyMcpFailure(err, { phase: "connect", transport: dialKind });
|
|
881
|
+
const redialLiveness = livenessOf(kind, Date.now());
|
|
882
|
+
const declared = echoOf(spec);
|
|
883
|
+
const failure = namedMcpFailureText(err, declared);
|
|
884
|
+
const status = { name: server, status: "failed", errorCode: kind, delivered, ...(httpStatus !== undefined ? { httpStatus } : {}), error: failure, ...(redialLiveness !== undefined ? { liveness: redialLiveness } : {}) };
|
|
885
|
+
const sIdx = statuses.findIndex((st) => st.name === server);
|
|
886
|
+
if (sIdx === -1)
|
|
887
|
+
statuses.push(status);
|
|
888
|
+
else
|
|
889
|
+
statuses[sIdx] = status;
|
|
890
|
+
const raised = asServerWarning(spec, err, declared);
|
|
891
|
+
warnings.push(raised);
|
|
892
|
+
reconcileInstructions(server, undefined, false);
|
|
901
893
|
return {
|
|
902
894
|
server,
|
|
903
895
|
prefix,
|
|
904
|
-
outcome: "
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
896
|
+
outcome: "refused",
|
|
897
|
+
reason: inlineUntrusted(failure, 240),
|
|
898
|
+
toolCount: 0,
|
|
899
|
+
added: [],
|
|
900
|
+
removed: priorNames,
|
|
901
|
+
tools: [],
|
|
902
|
+
axes: [],
|
|
903
|
+
dropped: [],
|
|
904
|
+
warnings: [raised.message],
|
|
905
|
+
status,
|
|
914
906
|
};
|
|
915
907
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
908
|
+
const { connected } = dialed;
|
|
909
|
+
const raised = commitConnectedServer(spec, connected, dialKind);
|
|
910
|
+
reconcileInstructions(server, connected.instructions, true);
|
|
911
|
+
const newNames = connected.tools.map((t) => t.name);
|
|
912
|
+
return {
|
|
913
|
+
server,
|
|
914
|
+
prefix,
|
|
915
|
+
outcome: "reconnected",
|
|
916
|
+
toolCount: newNames.length,
|
|
917
|
+
added: newNames.filter((n) => !priorNames.includes(n)),
|
|
918
|
+
removed: priorNames.filter((n) => !newNames.includes(n)),
|
|
919
|
+
tools: connected.tools,
|
|
920
|
+
axes: connected.axes,
|
|
921
|
+
dropped: connected.dropped.map((d) => ({ server: inlineUntrusted(server, 160), ...d })),
|
|
922
|
+
...(raised.length > 0 ? { warnings: raised.map((w) => w.message) } : {}),
|
|
923
|
+
status: connected.status,
|
|
924
|
+
...(connected.listingIncomplete !== undefined ? { listingIncomplete: connected.listingIncomplete } : {}),
|
|
925
|
+
};
|
|
919
926
|
};
|
|
927
|
+
const redialOnce = (server) => (redialFlights.running(server) === undefined ? redialFlights.start(server, () => redialDial(server)) : Promise.resolve(declineRedial(server, "refused", "a re-dial of this server is already in flight — wait for it to settle")));
|
|
920
928
|
return {
|
|
921
929
|
tools,
|
|
922
930
|
toolAxes,
|
|
@@ -940,20 +948,25 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
|
|
|
940
948
|
results.push({ server: h.name, prefix: prefixOf(h.name), status: "revoked", toolCount: h.tools.length, added: [], removed: [], error: "server revoked by the operator — the refresh did not contact it" });
|
|
941
949
|
continue;
|
|
942
950
|
}
|
|
951
|
+
const site = requestSite(h.client);
|
|
943
952
|
try {
|
|
953
|
+
const at = h.listing.open();
|
|
944
954
|
const cacheTools = h.openListing();
|
|
945
|
-
const listed = await listToolsLenient(h.client);
|
|
946
|
-
const
|
|
947
|
-
const
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
955
|
+
const listed = await listToolsLenient(h.client, undefined, echoOf(h.spec));
|
|
956
|
+
const answered = h.listing.answer(at, listed.tools, listed.incomplete !== undefined);
|
|
957
|
+
const mergedRaw = answered.view;
|
|
958
|
+
if (!answered.recorded) {
|
|
959
|
+
results.push({ server: h.name, prefix: prefixOf(h.name), status: "failed", toolCount: h.tools.length, added: [], removed: [], error: "a later listing of this server was opened and applied while this one was in the air — this one was discarded" });
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
const { serverTools, serverAxes, gates, dropped, accepted } = intakeListedTools({ tools: [...mergedRaw], unproven: answered.unproven }, h.spec, linkOf(h.name), echoOf(h.spec), imageResizer, mcpDisclosure, isServerRevoked, h.transportKind);
|
|
963
|
+
cacheTools(accepted, answered.kept);
|
|
951
964
|
const priorNames = h.tools.map((t) => t.name);
|
|
952
965
|
const newNames = serverTools.map((t) => t.name);
|
|
953
966
|
const added = newNames.filter((n) => !priorNames.includes(n));
|
|
954
967
|
const removed = priorNames.filter((n) => !newNames.includes(n));
|
|
955
968
|
h.tools = serverTools;
|
|
956
|
-
h.
|
|
969
|
+
h.gatesAt = { at, gates };
|
|
957
970
|
results.push({
|
|
958
971
|
server: h.name,
|
|
959
972
|
prefix: prefixOf(h.name),
|
|
@@ -971,7 +984,7 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
|
|
|
971
984
|
});
|
|
972
985
|
}
|
|
973
986
|
catch (err) {
|
|
974
|
-
h.health.observe?.(classifyMcpFailure(err,
|
|
987
|
+
h.health.observe?.(classifyMcpFailure(err, site).kind);
|
|
975
988
|
results.push({
|
|
976
989
|
server: h.name,
|
|
977
990
|
prefix: prefixOf(h.name),
|
|
@@ -979,7 +992,7 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
|
|
|
979
992
|
toolCount: h.tools.length,
|
|
980
993
|
added: [],
|
|
981
994
|
removed: [],
|
|
982
|
-
error: inlineUntrusted(namedMcpFailureText(err), 240),
|
|
995
|
+
error: inlineUntrusted(namingLostSession(err, site, namedMcpFailureText(err, echoOf(h.spec))), 240),
|
|
983
996
|
});
|
|
984
997
|
}
|
|
985
998
|
}
|
|
@@ -1094,7 +1107,7 @@ export async function walkMcpListPages(fetchPage, opts) {
|
|
|
1094
1107
|
catch (err) {
|
|
1095
1108
|
if (pages === 0 || opts.signal?.aborted)
|
|
1096
1109
|
throw err;
|
|
1097
|
-
return { items, incomplete: { reason: "page_error", pages, error: remoteErrorText(err) } };
|
|
1110
|
+
return { items, incomplete: { reason: "page_error", pages, error: remoteErrorText(err, opts.declared ?? []) } };
|
|
1098
1111
|
}
|
|
1099
1112
|
opts.onPage?.();
|
|
1100
1113
|
const pageStart = items.length;
|
|
@@ -1177,13 +1190,13 @@ async function readDirViaExtension(rs, uri, signal, timeoutMs, watchdog) {
|
|
|
1177
1190
|
if (err instanceof McpError && err.code === ErrorCode.InvalidParams) {
|
|
1178
1191
|
if (pages > 0)
|
|
1179
1192
|
return { kind: "ok", resources, cursorInvalid: true };
|
|
1180
|
-
const detail = remoteErrorText(err, { collapse: true });
|
|
1193
|
+
const detail = remoteErrorText(err, rs.declared, { collapse: true });
|
|
1181
1194
|
return { kind: classifyDirReadInvalidParams(detail), detail };
|
|
1182
1195
|
}
|
|
1183
1196
|
if (err instanceof McpError && err.code === ErrorCode.MethodNotFound)
|
|
1184
1197
|
return { kind: "unsupported" };
|
|
1185
1198
|
if (pages > 0 && !signal?.aborted) {
|
|
1186
|
-
return { kind: "ok", resources, incomplete: remoteErrorText(err) };
|
|
1199
|
+
return { kind: "ok", resources, incomplete: remoteErrorText(err, rs.declared) };
|
|
1187
1200
|
}
|
|
1188
1201
|
throw err;
|
|
1189
1202
|
}
|
|
@@ -1266,6 +1279,7 @@ function buildResourceTools(resourceServers, isServerRevoked = () => false) {
|
|
|
1266
1279
|
}
|
|
1267
1280
|
const idleMs = mcpIdleTimeoutMs(rs.transportKind);
|
|
1268
1281
|
const watchdog = armMcpIdleWatchdog(rs.health, idleMs, signal);
|
|
1282
|
+
const site = requestSite(rs.client);
|
|
1269
1283
|
try {
|
|
1270
1284
|
const walk = await walkMcpListPages(async (cursor, remainingMs) => {
|
|
1271
1285
|
const page = await rs.client
|
|
@@ -1274,7 +1288,7 @@ function buildResourceTools(resourceServers, isServerRevoked = () => false) {
|
|
|
1274
1288
|
throw watchdog.idleSignal.reason === IDLE_WATCHDOG_ABORT_REASON ? new Error(idleWatchdogTripText(idleMs)) : err;
|
|
1275
1289
|
});
|
|
1276
1290
|
return { items: page.resources, ...(page.nextCursor !== undefined ? { nextCursor: page.nextCursor } : {}) };
|
|
1277
|
-
}, { budgetMs: mcpToolTimeoutMs(), onPage: () => watchdog.rearm(), fingerprintOf: listEntryFingerprint, ...(signal !== undefined ? { signal } : {}) });
|
|
1291
|
+
}, { budgetMs: mcpToolTimeoutMs(), onPage: () => watchdog.rearm(), fingerprintOf: listEntryFingerprint, declared: rs.declared, ...(signal !== undefined ? { signal } : {}) });
|
|
1278
1292
|
all.push(...walk.items.map((r) => ({ server: rs.server, ...r })));
|
|
1279
1293
|
const lines = walk.items.map((r) => resourceLine(r));
|
|
1280
1294
|
const body = lines.length ? lines.join("\n") : "(no resources)";
|
|
@@ -1287,11 +1301,12 @@ function buildResourceTools(resourceServers, isServerRevoked = () => false) {
|
|
|
1287
1301
|
}
|
|
1288
1302
|
}
|
|
1289
1303
|
catch (err) {
|
|
1304
|
+
sanitizeMcpErrorTextInPlace(err, rs.declared);
|
|
1290
1305
|
if (signal?.aborted)
|
|
1291
1306
|
throw err;
|
|
1292
1307
|
const msg = watchdog.idleSignal.reason === IDLE_WATCHDOG_ABORT_REASON
|
|
1293
1308
|
? idleWatchdogTripText(idleMs)
|
|
1294
|
-
: remoteErrorText(err);
|
|
1309
|
+
: namingLostSession(err, site, remoteErrorText(err, rs.declared));
|
|
1295
1310
|
errors.push({ server: rs.server, error: msg });
|
|
1296
1311
|
sections.push(`[${rs.server}] Error: could not list resources: ${inlineUntrusted(msg)}`);
|
|
1297
1312
|
}
|
|
@@ -1345,11 +1360,12 @@ function buildResourceTools(resourceServers, isServerRevoked = () => false) {
|
|
|
1345
1360
|
const timeoutMs = mcpToolTimeoutMs();
|
|
1346
1361
|
const idleMs = mcpIdleTimeoutMs(rs.transportKind);
|
|
1347
1362
|
const watchdog = armMcpIdleWatchdog(rs.health, idleMs, signal);
|
|
1363
|
+
const site = requestSite(rs.client);
|
|
1348
1364
|
let res;
|
|
1349
1365
|
try {
|
|
1350
1366
|
res = await rs.client
|
|
1351
1367
|
.readResource({ uri }, { signal: watchdog.combinedSignal, timeout: timeoutMs })
|
|
1352
|
-
.catch((err) => rethrowHonestMcpError(err, { server, what, timeoutMs, writeEffect: false, signal, attributeServer: true, idle: { signal: watchdog.idleSignal, idleMs }, liveness: rs.health }));
|
|
1368
|
+
.catch((err) => rethrowHonestMcpError(err, { server, declared: rs.declared, what, timeoutMs, writeEffect: false, signal, attributeServer: true, site, idle: { signal: watchdog.idleSignal, idleMs }, liveness: rs.health }));
|
|
1353
1369
|
rs.health.observe?.("completed");
|
|
1354
1370
|
}
|
|
1355
1371
|
finally {
|
|
@@ -1406,10 +1422,11 @@ function buildResourceTools(resourceServers, isServerRevoked = () => false) {
|
|
|
1406
1422
|
const timeoutMs = mcpToolTimeoutMs();
|
|
1407
1423
|
const idleMs = mcpIdleTimeoutMs(rs.transportKind);
|
|
1408
1424
|
const watchdog = armMcpIdleWatchdog(rs.health, idleMs, signal);
|
|
1425
|
+
const site = requestSite(rs.client);
|
|
1409
1426
|
try {
|
|
1410
1427
|
const ext = rs.client.getServerCapabilities()?.extensions?.[MCP_SKILLS_EXTENSION];
|
|
1411
1428
|
if (ext?.directoryRead === true) {
|
|
1412
|
-
const r = await readDirViaExtension(rs, uri, signal, timeoutMs, watchdog).catch((err) => rethrowHonestMcpError(err, { server, what, timeoutMs, writeEffect: false, signal, attributeServer: true, idle: { signal: watchdog.idleSignal, idleMs }, liveness: rs.health }));
|
|
1429
|
+
const r = await readDirViaExtension(rs, uri, signal, timeoutMs, watchdog).catch((err) => rethrowHonestMcpError(err, { server, declared: rs.declared, what, timeoutMs, writeEffect: false, signal, attributeServer: true, site, idle: { signal: watchdog.idleSignal, idleMs }, liveness: rs.health }));
|
|
1413
1430
|
const serverSaid = (detail) => `\nThe server's error text follows as external/untrusted data:\n${delimitUntrusted(`${server} error`, truncateMcpErrorText(detail))}`;
|
|
1414
1431
|
if (r.kind === "not_found") {
|
|
1415
1432
|
return {
|
|
@@ -1437,10 +1454,10 @@ function buildResourceTools(resourceServers, isServerRevoked = () => false) {
|
|
|
1437
1454
|
const walk = await walkMcpListPages(async (cursor, remainingMs) => {
|
|
1438
1455
|
const page = await rs.client
|
|
1439
1456
|
.listResources(cursor === undefined ? undefined : { cursor }, { signal: watchdog.combinedSignal, timeout: remainingMs })
|
|
1440
|
-
.catch((err) => rethrowHonestMcpError(err, { server, what, timeoutMs: remainingMs, writeEffect: false, signal, attributeServer: true, idle: { signal: watchdog.idleSignal, idleMs }, liveness: rs.health }));
|
|
1457
|
+
.catch((err) => rethrowHonestMcpError(err, { server, declared: rs.declared, what, timeoutMs: remainingMs, writeEffect: false, signal, attributeServer: true, site, idle: { signal: watchdog.idleSignal, idleMs }, liveness: rs.health }));
|
|
1441
1458
|
rs.health.observe?.("completed");
|
|
1442
1459
|
return { items: page.resources, ...(page.nextCursor !== undefined ? { nextCursor: page.nextCursor } : {}) };
|
|
1443
|
-
}, { budgetMs: timeoutMs, onPage: () => watchdog.rearm(), fingerprintOf: listEntryFingerprint, ...(signal !== undefined ? { signal } : {}) });
|
|
1460
|
+
}, { budgetMs: timeoutMs, onPage: () => watchdog.rearm(), fingerprintOf: listEntryFingerprint, declared: rs.declared, ...(signal !== undefined ? { signal } : {}) });
|
|
1444
1461
|
const dirPrefix = uri.endsWith("/") ? uri : `${uri}/`;
|
|
1445
1462
|
const children = walk.items.filter((r) => typeof r.uri === "string" && r.uri !== uri && r.uri.startsWith(dirPrefix));
|
|
1446
1463
|
return renderDirChildren(server, uri, children, walk.incomplete ? { listing: walk.incomplete } : undefined);
|
|
@@ -1505,7 +1522,7 @@ export function parseCallToolResultLenient(data) {
|
|
|
1505
1522
|
return { success: true, data: { ...parsed.data, structuredContent } };
|
|
1506
1523
|
}
|
|
1507
1524
|
const LENIENT_CALL_TOOL_RESULT_SCHEMA = { safeParse: parseCallToolResultLenient };
|
|
1508
|
-
async function listToolsLenient(client, options) {
|
|
1525
|
+
async function listToolsLenient(client, options, declared) {
|
|
1509
1526
|
if (!client.getServerCapabilities()?.tools)
|
|
1510
1527
|
return { tools: [], toolsCapabilityAbsent: true };
|
|
1511
1528
|
const walk = await walkMcpListPages(async (cursor, remainingMs) => {
|
|
@@ -1518,6 +1535,7 @@ async function listToolsLenient(client, options) {
|
|
|
1518
1535
|
}, {
|
|
1519
1536
|
budgetMs: options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC,
|
|
1520
1537
|
fingerprintOf: listEntryFingerprint,
|
|
1538
|
+
declared,
|
|
1521
1539
|
...(options?.signal !== undefined ? { signal: options.signal } : {}),
|
|
1522
1540
|
});
|
|
1523
1541
|
return { tools: walk.items, ...(walk.incomplete !== undefined ? { incomplete: walk.incomplete } : {}) };
|
|
@@ -1532,7 +1550,8 @@ async function connectServer(spec, principal, onElicit, imageResizer, reminderDi
|
|
|
1532
1550
|
const announce = {};
|
|
1533
1551
|
const startupMs = mcpStartupTimeoutMs(spec);
|
|
1534
1552
|
const startupOpts = startupMs !== undefined ? { timeout: startupMs } : undefined;
|
|
1535
|
-
const dialClient = async () => {
|
|
1553
|
+
const dialClient = async (stop = dialOpts?.signal) => {
|
|
1554
|
+
stop?.throwIfAborted();
|
|
1536
1555
|
const client = new Client({ name: `sema-core/${spec.name}`, version: "0.1.0" }, { capabilities: elicitOn ? { elicitation: { form: {} } } : {} });
|
|
1537
1556
|
if (elicitOn) {
|
|
1538
1557
|
client.setRequestHandler(ElicitRequestSchema, async (request, extra) => {
|
|
@@ -1555,12 +1574,17 @@ async function connectServer(spec, principal, onElicit, imageResizer, reminderDi
|
|
|
1555
1574
|
});
|
|
1556
1575
|
}
|
|
1557
1576
|
const transport = buildTransport(spec, principal, transportKind);
|
|
1577
|
+
const hangUp = () => void client.close().catch(() => undefined);
|
|
1578
|
+
stop?.addEventListener("abort", hangUp, { once: true });
|
|
1558
1579
|
try {
|
|
1559
1580
|
await client.connect(transport, startupOpts);
|
|
1560
1581
|
}
|
|
1561
1582
|
catch (err) {
|
|
1562
1583
|
await client.close().catch(() => undefined);
|
|
1563
|
-
throw err;
|
|
1584
|
+
throw stop?.aborted === true ? stop.reason : err;
|
|
1585
|
+
}
|
|
1586
|
+
finally {
|
|
1587
|
+
stop?.removeEventListener("abort", hangUp);
|
|
1564
1588
|
}
|
|
1565
1589
|
return client;
|
|
1566
1590
|
};
|
|
@@ -1580,10 +1604,14 @@ async function connectServer(spec, principal, onElicit, imageResizer, reminderDi
|
|
|
1580
1604
|
lease.onClose(onClosed);
|
|
1581
1605
|
else
|
|
1582
1606
|
client.onclose = onClosed;
|
|
1607
|
+
const listing = lease?.listing ?? new ConnectionListing();
|
|
1608
|
+
const at = listing.open();
|
|
1583
1609
|
const cacheTools = openListing();
|
|
1584
|
-
const
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1610
|
+
const declared = declaredHeaderValues(spec.transport, principal);
|
|
1611
|
+
const listed = await underStartupBound(startupMs, dialOpts?.signal, (options) => listToolsLenient(client, options, declared));
|
|
1612
|
+
const answered = listing.answer(at, listed.tools, listed.incomplete !== undefined, dialOpts.carried);
|
|
1613
|
+
const { serverTools, serverAxes, gates, dropped, advisories, accepted } = intakeListedTools({ tools: [...answered.view], unproven: answered.unproven }, spec, dialOpts.link, declared, imageResizer, reminderDisclosure, isServerRevoked, transportKind);
|
|
1614
|
+
cacheTools(accepted, answered.kept);
|
|
1587
1615
|
const caps = client.getServerCapabilities();
|
|
1588
1616
|
const resourceInfo = caps?.resources
|
|
1589
1617
|
? {
|
|
@@ -1612,14 +1640,15 @@ async function connectServer(spec, principal, onElicit, imageResizer, reminderDi
|
|
|
1612
1640
|
announce,
|
|
1613
1641
|
tools: serverTools,
|
|
1614
1642
|
axes: serverAxes,
|
|
1643
|
+
listing,
|
|
1644
|
+
gatesAt: { at, gates },
|
|
1615
1645
|
dropped,
|
|
1616
1646
|
schemaAdvisories: advisories,
|
|
1617
1647
|
...(listed.toolsCapabilityAbsent === true ? { toolsCapabilityAbsent: true } : {}),
|
|
1618
|
-
listedTools: listed.tools,
|
|
1619
1648
|
...(instructions ? { instructions } : {}),
|
|
1620
1649
|
...(disposed?.defect !== undefined ? { instructionsDefect: disposed.defect } : {}),
|
|
1621
1650
|
...(listed.incomplete !== undefined ? { listingIncomplete: listed.incomplete } : {}),
|
|
1622
|
-
...(resourceInfo && (resourceInfo.listAllowed || resourceInfo.readAllowed) ? { resourceServer: { server: spec.name, client, health, transportKind: idleKindOf(transportKind), ...resourceInfo } } : {}),
|
|
1651
|
+
...(resourceInfo && (resourceInfo.listAllowed || resourceInfo.readAllowed) ? { resourceServer: { server: spec.name, client, health, transportKind: idleKindOf(transportKind), declared, ...resourceInfo } } : {}),
|
|
1623
1652
|
};
|
|
1624
1653
|
}
|
|
1625
1654
|
catch (err) {
|
|
@@ -1627,10 +1656,11 @@ async function connectServer(spec, principal, onElicit, imageResizer, reminderDi
|
|
|
1627
1656
|
throw err;
|
|
1628
1657
|
}
|
|
1629
1658
|
}
|
|
1630
|
-
function intakeListedTools(listed, spec,
|
|
1659
|
+
function intakeListedTools(listed, spec, link, declared, imageResizer, reminderDisclosure, isServerRevoked, transportKind) {
|
|
1631
1660
|
const declaredContentOrigin = spec.contentOrigin;
|
|
1632
1661
|
const serverTools = [];
|
|
1633
1662
|
const serverAxes = [];
|
|
1663
|
+
const gates = new Map();
|
|
1634
1664
|
const dropped = [];
|
|
1635
1665
|
const accepted = [];
|
|
1636
1666
|
const advisories = [];
|
|
@@ -1697,6 +1727,9 @@ function intakeListedTools(listed, spec, client, health, imageResizer, reminderD
|
|
|
1697
1727
|
if (interaction.advisory !== undefined)
|
|
1698
1728
|
advisories.push({ tool: inlineUntrusted(t.name), reason: interaction.advisory });
|
|
1699
1729
|
const mcpAlwaysLoad = mcpToolMeta?.["anthropic/alwaysLoad"] === true;
|
|
1730
|
+
const gateFace = { ...(interaction.declared ? { mcpRequiresUserInteraction: true } : {}), ...(t.annotations?.readOnlyHint === true ? { mcpReadOnlyHint: true } : {}) };
|
|
1731
|
+
const gate = mcpToolGate(remoteName, axis, gateFace, taskRequired);
|
|
1732
|
+
gates.set(namespacedName, listed.unproven?.has(remoteName) === true ? UNPROVEN_GATE : gate);
|
|
1700
1733
|
const mounted = {
|
|
1701
1734
|
name: namespacedName,
|
|
1702
1735
|
description: capMcpToolDescription(effectiveDescription ?? `MCP tool ${inlineUntrusted(sanitizeMcpModelFacingText(remoteName))} from ${spec.name}`),
|
|
@@ -1704,8 +1737,8 @@ function intakeListedTools(listed, spec, client, health, imageResizer, reminderD
|
|
|
1704
1737
|
parameters: (effectiveInputSchema ?? { type: "object" }),
|
|
1705
1738
|
...(mcpMaxResultSizeChars !== undefined ? { mcpMaxResultSizeChars } : {}),
|
|
1706
1739
|
...(mcpAlwaysLoad ? { mcpAlwaysLoad: true } : {}),
|
|
1707
|
-
...
|
|
1708
|
-
mcpRemoteName: remoteName, ...boundaryFlowFace(spec.toolAxes?.[remoteName]),
|
|
1740
|
+
...gateFace,
|
|
1741
|
+
mcpRemoteName: remoteName, ...boundaryFlowFace(spec.toolAxes?.[remoteName]), permissionSeat: "passthrough",
|
|
1709
1742
|
execute: async (_toolCallId, params, signal) => {
|
|
1710
1743
|
const what = `The call to tool ${inlineUntrusted(remoteName)}`;
|
|
1711
1744
|
if (isServerRevoked?.(spec.name) === true) {
|
|
@@ -1724,38 +1757,56 @@ function intakeListedTools(listed, spec, client, health, imageResizer, reminderD
|
|
|
1724
1757
|
isError: true,
|
|
1725
1758
|
};
|
|
1726
1759
|
}
|
|
1727
|
-
if (health.dead)
|
|
1728
|
-
throwDeadServer(spec.name, what);
|
|
1729
1760
|
const timeoutMs = mcpToolTimeoutMs();
|
|
1730
1761
|
const idleMs = mcpIdleTimeoutMs(idleKindOf(transportKind));
|
|
1731
|
-
const
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1762
|
+
const send = async (conn, resent) => {
|
|
1763
|
+
const site = requestSite(conn.client);
|
|
1764
|
+
const watchdog = armMcpIdleWatchdog(conn.health, idleMs, signal);
|
|
1765
|
+
try {
|
|
1766
|
+
const res = await conn.client
|
|
1767
|
+
.callTool({ name: remoteName, arguments: (params ?? {}) }, LENIENT_CALL_TOOL_RESULT_SCHEMA, {
|
|
1768
|
+
signal: watchdog.combinedSignal,
|
|
1769
|
+
timeout: timeoutMs,
|
|
1770
|
+
resetTimeoutOnProgress: true,
|
|
1771
|
+
onprogress: () => watchdog.rearm(),
|
|
1772
|
+
maxTotalTimeout: mcpToolTotalTimeoutMs(timeoutMs),
|
|
1773
|
+
})
|
|
1774
|
+
.catch((err) => {
|
|
1775
|
+
try {
|
|
1776
|
+
return rethrowHonestMcpError(err, {
|
|
1777
|
+
server: spec.name,
|
|
1778
|
+
declared,
|
|
1779
|
+
what,
|
|
1780
|
+
timeoutMs,
|
|
1781
|
+
writeEffect,
|
|
1782
|
+
signal,
|
|
1783
|
+
site,
|
|
1784
|
+
...(resent ? { resent: true } : {}),
|
|
1785
|
+
idle: { signal: watchdog.idleSignal, idleMs },
|
|
1786
|
+
liveness: conn.health,
|
|
1787
|
+
...(reminderDisclosure !== undefined
|
|
1788
|
+
? { reminder: { mark: reminderDisclosure.mark, outlet: "mcp", ...(reminderDisclosure.counts !== undefined ? { counts: reminderDisclosure.counts } : {}) } }
|
|
1789
|
+
: {}),
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
catch (failure) {
|
|
1793
|
+
if (sessionGone(err, site) && signal?.aborted !== true)
|
|
1794
|
+
return new Resendable(conn, failure);
|
|
1795
|
+
throw failure;
|
|
1796
|
+
}
|
|
1797
|
+
});
|
|
1798
|
+
if (res instanceof Resendable)
|
|
1799
|
+
return res;
|
|
1800
|
+
conn.health.observe?.("completed");
|
|
1801
|
+
return res;
|
|
1802
|
+
}
|
|
1803
|
+
finally {
|
|
1804
|
+
watchdog.dispose();
|
|
1805
|
+
}
|
|
1806
|
+
};
|
|
1807
|
+
const res = await callThroughLink(link, namespacedName, gate, signal, send, () => throwDeadServer(spec.name, what));
|
|
1808
|
+
if (typeof res === "string")
|
|
1809
|
+
return listingRefusal(res, remoteName, spec.name);
|
|
1759
1810
|
const mapped = await mapContent(res.content, spec.name, imageResizer);
|
|
1760
1811
|
if (res.isError === true) {
|
|
1761
1812
|
const parts = [];
|
|
@@ -1768,7 +1819,7 @@ function intakeListedTools(listed, spec, client, health, imageResizer, reminderD
|
|
|
1768
1819
|
const errScLine = structuredContentErrorLine(res.structuredContent, parts.join("\n"));
|
|
1769
1820
|
if (errScLine !== undefined)
|
|
1770
1821
|
parts.push(errScLine);
|
|
1771
|
-
const body = truncateMcpErrorText(
|
|
1822
|
+
const body = truncateMcpErrorText(mcpRemoteText(parts.join("\n").trim(), declared));
|
|
1772
1823
|
const msg = body
|
|
1773
1824
|
? `MCP tool ${inlineUntrusted(remoteName)} reported an error. The server's error content follows as external/untrusted data:\n${delimitUntrusted(`${spec.name} tool error`, body)}`
|
|
1774
1825
|
: `MCP tool ${inlineUntrusted(remoteName)} reported an error`;
|
|
@@ -1815,10 +1866,10 @@ function intakeListedTools(listed, spec, client, health, imageResizer, reminderD
|
|
|
1815
1866
|
serverTools.push(declaredContentOrigin !== undefined ? withContentOrigin(mounted, declaredContentOrigin) : mounted);
|
|
1816
1867
|
accepted.push(t);
|
|
1817
1868
|
}
|
|
1818
|
-
return { serverTools, serverAxes, dropped, advisories, accepted };
|
|
1869
|
+
return { serverTools, serverAxes, gates, dropped, advisories, accepted };
|
|
1819
1870
|
}
|
|
1820
|
-
function asServerWarning(spec, err) {
|
|
1821
|
-
const warning = new Error(`mcp: server "${spec.name}" failed to connect — skipped (${namedMcpFailureText(err)})`, { cause: sanitizedCause(err) });
|
|
1871
|
+
function asServerWarning(spec, err, declared) {
|
|
1872
|
+
const warning = new Error(`mcp: server "${spec.name}" failed to connect — skipped (${namedMcpFailureText(err, declared)})`, { cause: sanitizedCause(err, declared) });
|
|
1822
1873
|
warning.code = "mcp.server_unavailable";
|
|
1823
1874
|
return warning;
|
|
1824
1875
|
}
|
|
@@ -1843,8 +1894,8 @@ function dialDecision(dialable, spec) {
|
|
|
1843
1894
|
}
|
|
1844
1895
|
throw Object.assign(new Error(`MCP materialization refused: the dialable seat could not decide whether to dial server "${inlineUntrusted(spec.name, 120)}" — ${inlineUntrusted(why, 240)}. No server was dialed.`, cause), { code: "config.mcp_dialable_failed" });
|
|
1845
1896
|
}
|
|
1846
|
-
function sanitizedCause(err) {
|
|
1847
|
-
const copy = new Error(namedMcpFailureText(err));
|
|
1897
|
+
function sanitizedCause(err, declared) {
|
|
1898
|
+
const copy = new Error(namedMcpFailureText(err, declared));
|
|
1848
1899
|
const name = thrownName(err);
|
|
1849
1900
|
if (name !== undefined) {
|
|
1850
1901
|
if (name !== "")
|