@yielded/agent 0.1.0-beta.173 → 0.1.0-beta.175
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/dist/{Admin-BX9ns28E.d.mts → Admin-Qa3I1oA5.d.mts} +61 -21
- package/dist/{Agent-9aBoIi74.d.mts → Agent-B39jRnFv.d.mts} +2 -2
- package/dist/{Agent-0WvBWWbM.mjs → Agent-BiRbr73L.mjs} +7 -6
- package/dist/Agent-BiRbr73L.mjs.map +1 -0
- package/dist/{AgentRuntime-BfP14534.d.mts → AgentRuntime-CHDyRbSf.d.mts} +12 -12
- package/dist/{AgentRuntime-CQ-qcETl.mjs → AgentRuntime-DaDKMasp.mjs} +290 -273
- package/dist/AgentRuntime-DaDKMasp.mjs.map +1 -0
- package/dist/{Digest-DCuPlhNk.mjs → Digest-C3EODOee.mjs} +42 -15
- package/dist/Digest-C3EODOee.mjs.map +1 -0
- package/dist/{DurableAgentRuntime-BAmSkWYr.mjs → DurableAgentRuntime-CPlw5_7e.mjs} +1557 -1458
- package/dist/DurableAgentRuntime-CPlw5_7e.mjs.map +1 -0
- package/dist/{EventSource-BwliwQz9.d.mts → EventSource-BTu68yDW.d.mts} +2 -2
- package/dist/InMemory.d.mts +2 -2
- package/dist/{MessageDelivery-B943ebI_.d.mts → MessageDelivery-DjAZJ4Fd.d.mts} +42 -42
- package/dist/{Messaging-C_6OOg_s.d.mts → Messaging-SVu6rWV8.d.mts} +12 -6
- package/dist/{MessagingHost-B8oKM7AC.d.mts → MessagingHost-C6SOAcoG.d.mts} +2 -2
- package/dist/{MessagingHost-CRUK4JBi.mjs → MessagingHost-CZCyrnvJ.mjs} +27 -26
- package/dist/MessagingHost-CZCyrnvJ.mjs.map +1 -0
- package/dist/{Output-Dsx6k52t.d.mts → Output-CRamN1Fy.d.mts} +2 -2
- package/dist/{PreparedInputAdmission-CxSJSiTl.d.mts → PreparedInputAdmission-wgY4JMZY.d.mts} +3 -3
- package/dist/{Records-BiuJDWNe.mjs → Records-DzL4Kbtw.mjs} +2 -2
- package/dist/{Records-BiuJDWNe.mjs.map → Records-DzL4Kbtw.mjs.map} +1 -1
- package/dist/{RunContinuation-FHM7XPjq.d.mts → RunContinuation-3jB5pULC.d.mts} +13 -7
- package/dist/{RunContinuation-DHYNAQFi.mjs → RunContinuation-BiyKJK32.mjs} +173 -82
- package/dist/RunContinuation-BiyKJK32.mjs.map +1 -0
- package/dist/{RunJournal-kfKVxJj7.mjs → RunJournal-CPMKcfd0.mjs} +106 -73
- package/dist/RunJournal-CPMKcfd0.mjs.map +1 -0
- package/dist/{RunOptions-D8zxFIrZ.d.mts → RunOptions-Be77lKVZ.d.mts} +2 -2
- package/dist/{RunStorage-uqPxps09.mjs → RunStorage-CzutHJBE.mjs} +10 -6
- package/dist/RunStorage-CzutHJBE.mjs.map +1 -0
- package/dist/{Scheduling-CVyfXlBR.mjs → Scheduling-07_dsGED.mjs} +12 -12
- package/dist/Scheduling-07_dsGED.mjs.map +1 -0
- package/dist/{Subagent-vpffemql.mjs → Subagent-CexndZSp.mjs} +53 -40
- package/dist/Subagent-CexndZSp.mjs.map +1 -0
- package/dist/{Subagent-E6tvd7-k.d.mts → Subagent-xhN_aD1r.d.mts} +20 -9
- package/dist/{SubagentHost-B6w2m-SI.d.mts → SubagentHost-D1xBgn9g.d.mts} +2 -2
- package/dist/{Subscription-DONig54Q.d.mts → Subscription-DmIHlOJK.d.mts} +2 -2
- package/dist/{SubscriptionInput-mJIRxWJM.d.mts → SubscriptionInput-DgcQhvbe.d.mts} +2 -2
- package/dist/{Thread-dk-QiNml.d.mts → Thread-DzdJAY4J.d.mts} +4 -3
- package/dist/{ThreadHistory-ByxS8HU1.d.mts → ThreadHistory-KPPBJLJb.d.mts} +12 -2
- package/dist/{ThreadImport-DckUMEqJ.mjs → ThreadImport-CjlG57vH.mjs} +9 -9
- package/dist/ThreadImport-CjlG57vH.mjs.map +1 -0
- package/dist/{ThreadImport-DpHxjBrA.d.mts → ThreadImport-DP-vOk2F.d.mts} +5 -5
- package/dist/{ThreadStore-CEekRa80.mjs → ThreadStore-EuUilthA.mjs} +162 -85
- package/dist/ThreadStore-EuUilthA.mjs.map +1 -0
- package/dist/{ThreadTransfer-B4gTQLIl.mjs → ThreadTransfer-DB_zsrtJ.mjs} +4 -4
- package/dist/{ThreadTransfer-B4gTQLIl.mjs.map → ThreadTransfer-DB_zsrtJ.mjs.map} +1 -1
- package/dist/{WorkerAdmission-DFVbbVh2.mjs → WorkerAdmission-eBeXt_mu.mjs} +5 -5
- package/dist/{WorkerAdmission-DFVbbVh2.mjs.map → WorkerAdmission-eBeXt_mu.mjs.map} +1 -1
- package/dist/{agent-registration-ByMZ_cK5.mjs → agent-registration-a6QYaG3h.mjs} +70 -57
- package/dist/agent-registration-a6QYaG3h.mjs.map +1 -0
- package/dist/capabilities/Approval.mjs +2 -2
- package/dist/capabilities/Approval.mjs.map +1 -1
- package/dist/capabilities/BrowserUse.d.mts +102 -1867
- package/dist/capabilities/BrowserUse.mjs +74 -798
- package/dist/capabilities/BrowserUse.mjs.map +1 -1
- package/dist/capabilities/Budget.mjs +3 -1
- package/dist/capabilities/Budget.mjs.map +1 -1
- package/dist/capabilities/CodeMode.d.mts +1 -1
- package/dist/capabilities/CodeMode.mjs +16 -9
- package/dist/capabilities/CodeMode.mjs.map +1 -1
- package/dist/capabilities/Commands.d.mts +1 -1
- package/dist/capabilities/McpClient.mjs +1 -1
- package/dist/capabilities/McpClient.mjs.map +1 -1
- package/dist/capabilities/Messaging.d.mts +1 -1
- package/dist/capabilities/Messaging.mjs +5 -5
- package/dist/capabilities/Messaging.mjs.map +1 -1
- package/dist/capabilities/ModelContext.d.mts +1 -1
- package/dist/capabilities/ModelContext.mjs +7 -5
- package/dist/capabilities/ModelContext.mjs.map +1 -1
- package/dist/capabilities/Redaction.mjs +49 -19
- package/dist/capabilities/Redaction.mjs.map +1 -1
- package/dist/capabilities/RunHooks.d.mts +2 -2
- package/dist/capabilities/RunHooks.mjs +1 -1
- package/dist/capabilities/RunHooks.mjs.map +1 -1
- package/dist/capabilities/Subagent.d.mts +1 -1
- package/dist/capabilities/Subagent.mjs +1 -1
- package/dist/capabilities/SubagentReservations.mjs +3 -1
- package/dist/capabilities/SubagentReservations.mjs.map +1 -1
- package/dist/capabilities/WebCapture.mjs.map +1 -1
- package/dist/capabilities/WebSearch.mjs +7 -7
- package/dist/capabilities/WebSearch.mjs.map +1 -1
- package/dist/core/Agent.d.mts +1 -1
- package/dist/core/Agent.mjs +1 -1
- package/dist/core/AgentUpdates.mjs +8 -8
- package/dist/core/AgentUpdates.mjs.map +1 -1
- package/dist/core/Thread.d.mts +2 -2
- package/dist/core/Thread.mjs +6 -4
- package/dist/core/Thread.mjs.map +1 -1
- package/dist/core/Usage.mjs +2 -2
- package/dist/core/Usage.mjs.map +1 -1
- package/dist/durable/ActivityStore.mjs +1 -1
- package/dist/durable/Admin.d.mts +1 -1
- package/dist/durable/Admin.mjs +1 -1
- package/dist/durable/AgentRegistration.d.mts +1 -1
- package/dist/durable/AgentRegistration.mjs +1 -1
- package/dist/durable/Certification.d.mts +1 -1
- package/dist/durable/CommittedActivity.d.mts +1 -1
- package/dist/durable/CommittedActivity.mjs +3 -3
- package/dist/durable/Digest.mjs +1 -1
- package/dist/durable/DurableAgentRuntime.d.mts +1 -1
- package/dist/durable/DurableAgentRuntime.mjs +2 -2
- package/dist/durable/EventSource.d.mts +1 -1
- package/dist/durable/EventSource.mjs +7 -7
- package/dist/durable/EventSource.mjs.map +1 -1
- package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
- package/dist/durable/LifecyclePublication.d.mts +1 -1
- package/dist/durable/LifecyclePublication.mjs +2 -2
- package/dist/durable/MessageDelivery.d.mts +1 -1
- package/dist/durable/MessageDelivery.mjs +2 -2
- package/dist/durable/MessageDeliveryStoreConformance.d.mts +40 -40
- package/dist/durable/MessageDeliveryStoreConformance.mjs +2 -2
- package/dist/durable/PersistentHistory.d.mts +2 -2
- package/dist/durable/PersistentHistory.mjs +4 -4
- package/dist/durable/PreparedInputAdmission.d.mts +1 -1
- package/dist/durable/RecordFormat.mjs +3 -3
- package/dist/durable/RecordFormat.mjs.map +1 -1
- package/dist/durable/Records.mjs +1 -1
- package/dist/durable/Recovery.d.mts +1 -1
- package/dist/durable/Recovery.mjs +1 -1
- package/dist/durable/RunContinuation.d.mts +2 -2
- package/dist/durable/RunContinuation.mjs +3 -3
- package/dist/durable/RunJournal.d.mts +2 -2
- package/dist/durable/RunJournal.mjs +2 -2
- package/dist/durable/RunStorage.d.mts +1 -1
- package/dist/durable/RunStorage.mjs +1 -1
- package/dist/durable/Schedule.mjs +1 -1
- package/dist/durable/ScheduleStoreConformance.mjs +1 -1
- package/dist/durable/ScheduleTransition.mjs +1 -1
- package/dist/durable/Scheduling.d.mts +1 -1
- package/dist/durable/Scheduling.mjs +1 -1
- package/dist/durable/SettlementPublisher.d.mts +1 -1
- package/dist/durable/SettlementPublisher.mjs +3 -3
- package/dist/durable/SqlMemoryStore.mjs +5 -3
- package/dist/durable/SqlMemoryStore.mjs.map +1 -1
- package/dist/durable/SubmissionLedger.d.mts +1 -1
- package/dist/durable/SubmissionLedger.mjs +11 -3
- package/dist/durable/SubmissionLedger.mjs.map +1 -1
- package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
- package/dist/durable/SubmissionLedgerConformance.mjs +6 -6
- package/dist/durable/SubmissionStatus.d.mts +1 -1
- package/dist/durable/Subscription.d.mts +1 -1
- package/dist/durable/Subscription.mjs +2 -2
- package/dist/durable/SubscriptionInput.d.mts +1 -1
- package/dist/durable/SubscriptionInput.mjs +4 -4
- package/dist/durable/SubscriptionInput.mjs.map +1 -1
- package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
- package/dist/durable/SubscriptionStoreConformance.mjs +3 -3
- package/dist/durable/SubscriptionStoreConformance.mjs.map +1 -1
- package/dist/durable/SubscriptionTools.d.mts +2 -2
- package/dist/durable/SubscriptionTransition.d.mts +1 -1
- package/dist/durable/SubscriptionTransition.mjs +1 -1
- package/dist/durable/Subscriptions.d.mts +5 -5
- package/dist/durable/Subscriptions.mjs +3 -3
- package/dist/durable/Subscriptions.mjs.map +1 -1
- package/dist/durable/ThreadArchiveRange.d.mts +1 -1
- package/dist/durable/ThreadArchiveRange.mjs +1 -1
- package/dist/durable/ThreadContextHistory.d.mts +1 -1
- package/dist/durable/ThreadContextHistory.mjs +2 -2
- package/dist/durable/ThreadContextHistoryProjection.mjs +1 -1
- package/dist/durable/ThreadImport.d.mts +1 -1
- package/dist/durable/ThreadImport.mjs +1 -1
- package/dist/durable/ThreadInvariants.d.mts +3 -3
- package/dist/durable/ThreadInvariants.mjs +5 -5
- package/dist/durable/ThreadInvariants.mjs.map +1 -1
- package/dist/durable/ThreadProjection.mjs +1 -1
- package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
- package/dist/durable/ThreadReader.d.mts +1 -1
- package/dist/durable/ThreadReader.mjs +1 -1
- package/dist/durable/ThreadStore.d.mts +1 -1
- package/dist/durable/ThreadStore.mjs +2 -2
- package/dist/durable/ThreadStoreConformance.d.mts +1 -1
- package/dist/durable/ThreadStoreConformance.mjs +4 -4
- package/dist/durable/ThreadTransfer.d.mts +1 -1
- package/dist/durable/ThreadTransfer.mjs +1 -1
- package/dist/durable/ThreadWork.d.mts +2 -2
- package/dist/durable/ThreadWork.mjs +12 -6
- package/dist/durable/ThreadWork.mjs.map +1 -1
- package/dist/durable/ToolReconciler.mjs +1 -1
- package/dist/durable/WakeScheduler.mjs +23 -39
- package/dist/durable/WakeScheduler.mjs.map +1 -1
- package/dist/durable/WorkerAdmission.d.mts +1 -1
- package/dist/durable/WorkerAdmission.mjs +1 -1
- package/dist/durable/WorkerHost.d.mts +2 -2
- package/dist/engine/AgentRuntime.d.mts +1 -1
- package/dist/engine/AgentRuntime.mjs +1 -1
- package/dist/engine/MessagingHost.d.mts +1 -1
- package/dist/engine/MessagingHost.mjs +1 -1
- package/dist/engine/Output.d.mts +1 -1
- package/dist/engine/Output.mjs +1 -1
- package/dist/engine/RunOptions.d.mts +1 -1
- package/dist/engine/SubagentHost.d.mts +1 -1
- package/dist/engine/ThreadHistory.d.mts +1 -1
- package/dist/engine/ThreadHistory.mjs +3 -2
- package/dist/engine/ThreadHistory.mjs.map +1 -1
- package/dist/index.d.mts +21 -21
- package/dist/index.mjs +16 -16
- package/dist/{output-contract-CMIhu4Cw.mjs → output-contract-DCnLYCdp.mjs} +12 -15
- package/dist/{output-contract-CMIhu4Cw.mjs.map → output-contract-DCnLYCdp.mjs.map} +1 -1
- package/dist/{run-context-reader-OcsZr4bk.d.mts → run-context-reader-DVhJZ1Qe.d.mts} +2 -2
- package/package.json +1 -1
- package/src/capabilities/Approval.ts +58 -60
- package/src/capabilities/BrowserUse.ts +89 -944
- package/src/capabilities/Budget.ts +8 -1
- package/src/capabilities/CodeMode.ts +57 -33
- package/src/capabilities/McpClient.ts +2 -2
- package/src/capabilities/Messaging.ts +51 -55
- package/src/capabilities/ModelContext.ts +5 -2
- package/src/capabilities/Redaction.ts +64 -34
- package/src/capabilities/RunHooks.ts +52 -55
- package/src/capabilities/Subagent.ts +33 -33
- package/src/capabilities/SubagentReservations.ts +9 -1
- package/src/capabilities/WebCapture.ts +6 -0
- package/src/capabilities/WebSearch.ts +10 -7
- package/src/capabilities/internal/subagent-background.ts +202 -158
- package/src/core/Agent.ts +11 -6
- package/src/core/AgentUpdates.ts +8 -8
- package/src/core/Thread.ts +142 -146
- package/src/core/Usage.ts +7 -8
- package/src/core/internal/agent-updates.ts +1 -0
- package/src/durable/DurableAgentRuntime.ts +1024 -829
- package/src/durable/EventSource.ts +15 -9
- package/src/durable/RecordFormat.ts +5 -3
- package/src/durable/RunContinuation.ts +316 -113
- package/src/durable/RunJournal.ts +106 -114
- package/src/durable/RunStorage.ts +129 -124
- package/src/durable/Scheduling.ts +639 -651
- package/src/durable/SqlMemoryStore.ts +8 -6
- package/src/durable/SubmissionLedger.ts +11 -0
- package/src/durable/SubscriptionInput.ts +5 -3
- package/src/durable/SubscriptionStoreConformance.ts +23 -23
- package/src/durable/Subscriptions.ts +18 -19
- package/src/durable/ThreadImport.ts +18 -19
- package/src/durable/ThreadInvariants.ts +2 -1
- package/src/durable/ThreadStore.ts +217 -111
- package/src/durable/ThreadWork.ts +11 -2
- package/src/durable/WakeScheduler.ts +34 -66
- package/src/durable/internal/StorageOwner.ts +10 -4
- package/src/durable/internal/agent-registration.ts +96 -89
- package/src/durable/internal/canonical-json.ts +61 -20
- package/src/durable/internal/prompt-history-cache.ts +13 -4
- package/src/durable/internal/record-encoding.ts +120 -64
- package/src/durable/internal/schedule-time.ts +6 -6
- package/src/durable/internal/usage-totals.ts +35 -0
- package/src/durable/internal/worker-host.ts +69 -74
- package/src/engine/MessagingHost.ts +4 -2
- package/src/engine/ThreadHistory.ts +47 -48
- package/src/engine/internal/agent-runtime.ts +1298 -1217
- package/src/engine/internal/output-contract.ts +15 -15
- package/src/engine/internal/primitive-delta.ts +2 -3
- package/src/engine/internal/provisional-text.ts +12 -10
- package/src/engine/internal/tool-exposure.ts +22 -18
- package/src/engine/internal/tool-telemetry.ts +15 -12
- package/dist/Agent-0WvBWWbM.mjs.map +0 -1
- package/dist/AgentRuntime-CQ-qcETl.mjs.map +0 -1
- package/dist/Digest-DCuPlhNk.mjs.map +0 -1
- package/dist/DurableAgentRuntime-BAmSkWYr.mjs.map +0 -1
- package/dist/MessagingHost-CRUK4JBi.mjs.map +0 -1
- package/dist/RunContinuation-DHYNAQFi.mjs.map +0 -1
- package/dist/RunJournal-kfKVxJj7.mjs.map +0 -1
- package/dist/RunStorage-uqPxps09.mjs.map +0 -1
- package/dist/Scheduling-CVyfXlBR.mjs.map +0 -1
- package/dist/Subagent-vpffemql.mjs.map +0 -1
- package/dist/ThreadImport-DckUMEqJ.mjs.map +0 -1
- package/dist/ThreadStore-CEekRa80.mjs.map +0 -1
- package/dist/agent-registration-ByMZ_cK5.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeMode.mjs","names":["ToolExecutionClassAnnotation"],"sources":["../../src/capabilities/CodeMode.ts"],"sourcesContent":["import {\n type Layer,\n Cause,\n Context,\n Duration,\n Effect,\n Exit,\n Option,\n Schema,\n type Scope,\n} from \"effect\";\nimport { Tool, Toolkit } from \"effect/ai\";\n\nimport { utf8ByteLength } from \"../core/internal/utf8.ts\";\nimport { AdditionalToolCatalog, IncludesCatalogDocumentation } from \"../core/ToolExposure.ts\";\nimport {\n type ToolBrokerConfigurationError,\n type ToolBrokerUnavailableError,\n ToolBroker,\n type ProgrammaticCallOutcome,\n type ToolBrokerPass,\n ProgrammaticCallRecord,\n} from \"../engine/ToolBroker.ts\";\nimport { CurrentToolCatalog } from \"../engine/ToolExposure.ts\";\nimport {\n type CodeExecutionError,\n CodeExecutionHost,\n CodeExecutionLimits,\n CodeExecutionNamespace,\n CodeExecutionRequest,\n CodeExecutor,\n JsIdentifier,\n type CodeExecutionResult,\n type CodeHostCall,\n type CodeHostCallResult,\n} from \"../sandbox/CodeExecutor.ts\";\nimport { NetworkDisabled } from \"../sandbox/Sandbox.ts\";\n\n/**\n * Code Mode (D-035, ADR-0017; capability spec §9.1): one native Effect AI\n * Tool whose input is bounded JavaScript source, executed in one isolated\n * `CodeExecutor` pass that may call an explicit construction-time allowlist\n * of existing Tools through typed sandbox globals and the engine-owned\n * `ToolBroker`. The builder follows the Delegation pattern: an explicit\n * record of selected Tools plus namespace mapping fixed at construction,\n * returning an ordinary Tool and a handler Layer, with no ambient registry\n * (CAP-014). Deployment class `E` only.\n */\n\nconst maxFailureTextLength = 4 * 1024;\nconst BoundedFailureText = Schema.String.check(Schema.isMaxLength(maxFailureTextLength));\nconst BoundedErrorTag = Schema.NonEmptyString.check(Schema.isMaxLength(256));\nconst BoundedLogLine = Schema.String.check(Schema.isMaxLength(16 * 1024));\nconst BoundedLogs = Schema.Array(BoundedLogLine).check(Schema.isMaxLength(4_096));\nconst BoundedCode = Schema.NonEmptyString.check(Schema.isMaxLength(512 * 1024));\n\n/** A pass-local report, available to the host even when the caller interrupts execution. */\nexport const CodeModePassReport = Schema.Struct({\n status: Schema.Literals([\"completed\", \"failed\", \"interrupted\", \"defect\"]),\n calls: Schema.Array(ProgrammaticCallRecord),\n});\n\nexport type CodeModePassReport = typeof CodeModePassReport.Type;\n\nconst encodedJsonByteLength = (value: unknown): number | undefined => {\n try {\n const encoded = JSON.stringify(value);\n\n return encoded === undefined ? undefined : utf8ByteLength(encoded);\n } catch {\n return undefined;\n }\n};\n\n/** Model-decoded Code Mode parameters: one async function expression. */\nexport const CodeModeParameters = Schema.Struct({\n code: BoundedCode,\n});\n\n/**\n * The bounded model-visible success: the program's JSON result plus captured\n * logs, both already passed through the aggregate egress budget (CAP-016).\n */\nexport class CodeModeSuccess extends Schema.Class<CodeModeSuccess>(\n \"@effect-agent/capabilities/CodeModeSuccess\",\n)({\n result: Schema.Json,\n logs: BoundedLogs,\n}) {}\n\n/**\n * The bounded model-visible failure envelope. `failureMode: \"return\"` turns\n * it into a failed Tool result, so a model can correct a failing program\n * without a blind retry; it carries the same bounded log capture as success\n * plus the bounded thrown value where one exists, all inside the same\n * aggregate egress budget (CAP-016).\n */\nexport class CodeModeFailure extends Schema.TaggedError<CodeModeFailure>()(\"CodeModeFailure\", {\n errorTag: BoundedErrorTag,\n message: BoundedFailureText,\n logs: BoundedLogs,\n thrown: Schema.optionalKey(Schema.Json),\n /** Invocation-ordered evidence that fits the egress budget. This is not a replay plan. */\n calls: Schema.optionalKey(Schema.Array(ProgrammaticCallRecord)),\n omittedCalls: Schema.optionalKey(Schema.Natural),\n}) {}\n\n/** A selective documentation request is invalid or cannot fit its declared byte budget. */\nexport class CodeModeDescriptionError extends Schema.TaggedError<CodeModeDescriptionError>()(\n \"CodeModeDescriptionError\",\n {\n reason: Schema.Literals([\n \"invalid-selection\",\n \"unknown-method\",\n \"invalid-bound\",\n \"limit-exceeded\",\n ]),\n message: BoundedFailureText,\n },\n) {}\n\nconst DescriptionMethods = Schema.Array(Schema.NonEmptyString.check(Schema.isMaxLength(257))).check(\n Schema.isMinLength(1),\n Schema.isMaxLength(64),\n Schema.isUnique(),\n);\n\nconst DescriptionByteLimit = Schema.Int.check(\n Schema.isBetween({ minimum: 1, maximum: 256 * 1024 }),\n);\n\n/** The namespace-record shape accepted by `CodeMode.make`. */\nexport type CodeModeNamespaces = Record<string, Record<string, Tool.Any>>;\n\n/**\n * Union of every Tool selected across all namespaces, computed distributively\n * per namespace: indexing the namespace union with the INTERSECTION of method\n * keys would erase every Tool once two namespaces have disjoint methods.\n */\nexport type CodeModeSelectedTool<Namespaces extends CodeModeNamespaces> = {\n [Namespace in keyof Namespaces]: Namespaces[Namespace][keyof Namespaces[Namespace]];\n}[keyof Namespaces];\n\n/** The selected Tools re-keyed by their own Tool names. */\nexport type CodeModeSelectedRecord<Namespaces extends CodeModeNamespaces> = {\n readonly [T in CodeModeSelectedTool<Namespaces> as T[\"name\"]]: T;\n};\n\n/**\n * The native Effect AI Tool created by `CodeMode.make` (CAP-014). Its only\n * per-call dependency is the engine-provided `ToolBroker`; the `CodeExecutor`\n * and every selected handler and redaction service are construction requirements of the handler\n * Layer instead, so they stay visible in the composed `R`.\n */\nexport type CodeModeTool<Name extends string> = Tool.Tool<\n Name,\n {\n readonly parameters: typeof CodeModeParameters;\n readonly success: typeof CodeModeSuccess;\n readonly failure: typeof CodeModeFailure;\n readonly failureMode: \"return\";\n },\n ToolBroker\n>;\n\n/** Singleton Tool record provided by one Code Mode handler Layer. */\nexport type CodeModeTools<Name extends string> = {\n readonly [Key in Name]: CodeModeTool<Name>;\n};\n\n/** Construction requirements of the Code Mode handler Layer. */\nexport type CodeModeLayerRequirements<\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n> =\n | CodeExecutor\n | Exclude<RedactionRequirements, Scope.Scope>\n | Tool.HandlersFor<CodeModeSelectedRecord<Namespaces>>\n | Tool.HandlerServices<CodeModeSelectedTool<Namespaces>>;\n\nexport interface CodeModeOptions<\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n> {\n /** Model-visible description; the builder appends the sandbox contract. */\n readonly description: string;\n /** Include all sandbox declarations in the model-facing description. Defaults to true. */\n readonly includeDeclarations?: boolean | undefined;\n /**\n * Explicit allowlist: namespace name → method name → native Effect AI\n * Tool. Reads and mutations are allowed; calls requiring additional approval fail closed.\n */\n readonly tools: Namespaces;\n /** Executor limits for one pass; a bounded default applies when omitted. */\n readonly limits?: CodeExecutionLimits | undefined;\n /**\n * Aggregate model-visible egress budget in UTF-8 bytes across the final\n * result, captured logs, and any thrown value (CAP-016). Default 65536.\n */\n readonly maxEgressBytes?: number | undefined;\n /**\n * Host-only ephemeral report after executor resources and invocation fibers close, including\n * failure, defect, and interruption. It contains no arguments/results and is never a checkpoint.\n * Keep this total callback bounded; its services are captured with the handler Layer.\n */\n readonly onPassExit?:\n | ((report: CodeModePassReport) => Effect.Effect<void, never, RedactionRequirements>)\n | undefined;\n /**\n * Optional aggregate redaction pass applied to the model-visible egress\n * before the byte budget. Its services are acquired with the handler Layer;\n * temporary resources close with each redaction invocation.\n * It must be total; a defect stays a defect.\n */\n readonly redactEgress?:\n | ((egress: {\n readonly result: Schema.Json;\n readonly logs: ReadonlyArray<string>;\n }) => Effect.Effect<\n {\n readonly result: Schema.Json;\n readonly logs: ReadonlyArray<string>;\n },\n never,\n RedactionRequirements\n >)\n | undefined;\n}\n\n/**\n * An immutable Code Mode definition: one model-facing Tool over an explicit\n * allowlist, plus the handler Layer that runs generated programs through the\n * `CodeExecutor` port and the engine-owned broker. It owns no acquired\n * resources.\n */\nexport interface CodeModeDefinition<\n Name extends string,\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n> {\n readonly name: Name;\n /** The assembled model-facing description, optionally including all declarations. */\n readonly description: string;\n /** Rendered TypeScript declarations of the sandbox globals (documentation only). */\n readonly declarations: string;\n /**\n * Render complete encoded-schema declarations for 1–64 unique, exact namespace.method names.\n * The UTF-8 byte limit defaults to 16384 and must be an integer from 1 through 262144.\n * Oversized documentation fails rather than truncating a declaration. This host operation\n * does not authorize a model to see the selected methods; filter selections by current\n * visibility and inherited grants before returning its output to a model.\n */\n readonly describe: (\n methods: ReadonlyArray<string>,\n options?: { readonly maxBytes?: number | undefined },\n ) => Effect.Effect<string, CodeModeDescriptionError>;\n /** The executor-facing namespace catalog derived from the allowlist. */\n readonly namespaces: ReadonlyArray<CodeExecutionNamespace>;\n readonly limits: CodeExecutionLimits;\n readonly maxEgressBytes: number;\n /** The ordinary Effect AI Tool to include in the model-facing Toolkit. */\n readonly tool: CodeModeTool<Name>;\n /** Handler Layer; selected handler requirements stay visible in `R`. */\n readonly handlers: Layer.Layer<\n Tool.HandlersFor<CodeModeTools<Name>>,\n never,\n CodeModeLayerRequirements<Namespaces, RedactionRequirements>\n >;\n}\n\nconst defaultLimits = CodeExecutionLimits.make({\n maxSourceBytes: 256 * 1024,\n maxWallTime: Duration.seconds(30),\n maxLogBytes: 256 * 1024,\n maxResultBytes: 1024 * 1024,\n maxHostCalls: 64,\n maxHostCallArgumentBytes: 256 * 1024,\n maxHostCallResultBytes: 1024 * 1024,\n});\n\nconst defaultMaxEgressBytes = 64 * 1024;\n\n// ---------------------------------------------------------------------------\n// Declaration rendering (capability spec §9.1): the encoded side of each\n// Schema — the JSON that actually crosses the sandbox boundary — rendered as\n// TypeScript documentation via the same JSON-schema derivation Effect AI\n// applies to Tool parameters. A schema the renderer cannot express fails Tool\n// construction closed rather than degrading to `unknown`.\n// ---------------------------------------------------------------------------\n\nconst MAX_RENDER_DEPTH = 24;\n\nconst isJsonSchemaRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst renderJsonSchemaType = (\n schema: unknown,\n defs: Record<string, unknown>,\n depth: number,\n indent: string,\n): string => {\n if (depth > MAX_RENDER_DEPTH) {\n throw new Error(\"Code Mode declaration rendering exceeded its depth bound\");\n }\n if (!isJsonSchemaRecord(schema)) {\n throw new Error(`Code Mode cannot render the JSON schema fragment ${JSON.stringify(schema)}`);\n }\n const reference = schema.$ref;\n\n if (typeof reference === \"string\") {\n const match = /^#\\/\\$defs\\/(.+)$/.exec(reference);\n // JSON-pointer tokens escape `/` as `~1` and `~` as `~0`.\n const key = match === null ? undefined : match[1].replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n const resolved = key === undefined ? undefined : defs[key];\n\n if (resolved === undefined) {\n throw new Error(`Code Mode cannot resolve the JSON schema reference ${reference}`);\n }\n\n return renderJsonSchemaType(resolved, defs, depth + 1, indent);\n }\n if (Array.isArray(schema.enum)) {\n return schema.enum.map((value) => JSON.stringify(value)).join(\" | \");\n }\n if (\"const\" in schema) {\n return JSON.stringify(schema.const);\n }\n const union = schema.anyOf ?? schema.oneOf;\n\n if (Array.isArray(union)) {\n return union.map((member) => renderJsonSchemaType(member, defs, depth + 1, indent)).join(\" | \");\n }\n const type = schema.type;\n\n if (Array.isArray(type)) {\n return type\n .map((member) => renderJsonSchemaType({ ...schema, type: member }, defs, depth + 1, indent))\n .join(\" | \");\n }\n switch (type) {\n case \"string\": {\n return \"string\";\n }\n case \"number\":\n case \"integer\": {\n return \"number\";\n }\n case \"boolean\": {\n return \"boolean\";\n }\n case \"null\": {\n return \"null\";\n }\n case \"array\": {\n if (!(\"items\" in schema)) {\n throw new Error(\"Code Mode cannot render an array schema without items\");\n }\n\n return `ReadonlyArray<${renderJsonSchemaType(schema.items, defs, depth + 1, indent)}>`;\n }\n case \"object\":\n case undefined: {\n if (isJsonSchemaRecord(schema.properties)) {\n const required = Array.isArray(schema.required) ? schema.required : [];\n const inner = `${indent} `;\n\n const fields = Object.entries(schema.properties).map(([key, property]) => {\n const optional = required.includes(key) ? \"\" : \"?\";\n // A JSON property name need not be a TypeScript identifier.\n const rendered = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\n\n return `${inner}readonly ${rendered}${optional}: ${renderJsonSchemaType(property, defs, depth + 1, inner)};`;\n });\n\n return fields.length === 0 ? \"{}\" : `{\\n${fields.join(\"\\n\")}\\n${indent}}`;\n }\n if (isJsonSchemaRecord(schema.additionalProperties)) {\n return `Record<string, ${renderJsonSchemaType(schema.additionalProperties, defs, depth + 1, indent)}>`;\n }\n // Schema.Record(Schema.String, Schema.Never) accepts only an empty object.\n if (\n type === \"object\" &&\n !(\"properties\" in schema) &&\n !(\"patternProperties\" in schema) &&\n schema.additionalProperties === false\n ) {\n return \"Record<string, never>\";\n }\n // A bare `{ \"type\": \"object\" }` states \"any JSON object\" (Schema.Json's\n // object member derives to exactly this); rendering it as an\n // unconstrained record is faithful, not a deriver degradation.\n if (type === \"object\" && !(\"properties\" in schema) && !(\"additionalProperties\" in schema)) {\n return \"Record<string, unknown>\";\n }\n break;\n }\n default: {\n break;\n }\n }\n throw new Error(\n `Code Mode cannot render the JSON schema fragment ${JSON.stringify(schema).slice(0, 200)}; fix or simplify the Tool's Schema`,\n );\n};\n\nconst renderTopLevel = (jsonSchema: unknown, indent: string): string => {\n const defs =\n isJsonSchemaRecord(jsonSchema) && isJsonSchemaRecord(jsonSchema.$defs)\n ? jsonSchema.$defs\n : ({} as Record<string, unknown>);\n\n return renderJsonSchemaType(jsonSchema, defs, 0, indent);\n};\n\nconst decodeIdentifier = Schema.decodeUnknownOption(JsIdentifier);\n\ninterface ResolvedMethod {\n readonly namespace: string;\n readonly method: string;\n readonly tool: Tool.Any;\n}\n\nconst renderDeclarations = (methods: ReadonlyArray<ResolvedMethod>): string => {\n const namespaces = new Map<string, Array<ResolvedMethod>>();\n\n for (const method of methods) {\n const existing = namespaces.get(method.namespace) ?? [];\n\n existing.push(method);\n namespaces.set(method.namespace, existing);\n }\n\n const blocks = [...namespaces.entries()].map(([namespace, members]) => {\n const lines = members.map((member) => {\n const parameters = renderTopLevel(Tool.getJsonSchema(member.tool), \" \");\n const success = renderTopLevel(Tool.getJsonSchemaFromSchema(member.tool.successSchema), \" \");\n\n // A description is arbitrary text: newlines and comment terminators\n // must not be able to break out of the documentation comment.\n const safeDescription = member.tool.description\n ?.replaceAll(\"*/\", \"*\\\\/\")\n .replaceAll(/\\s*\\n\\s*/g, \" \");\n\n const description = safeDescription === undefined ? \"\" : ` /** ${safeDescription} */\\n`;\n\n return `${description} ${member.method}(input: ${parameters}): Promise<${success}>;`;\n });\n\n return `declare const ${namespace}: {\\n${lines.join(\"\\n\")}\\n};`;\n });\n\n return blocks.join(\"\\n\\n\");\n};\n\n// ---------------------------------------------------------------------------\n// Aggregate model-visible egress (CAP-016): the final result, captured logs,\n// and any thrown value share one byte budget. Logs are truncated line-by-line\n// with an explicit marker; a result that alone exceeds the budget is a typed\n// failure rather than silent truncation.\n// ---------------------------------------------------------------------------\n\nconst truncationMarker = \"… logs truncated by the egress budget\";\nconst MAX_EGRESS_LOG_LINE_CHARACTERS = 16_000;\n\n/**\n * Budget charge of one log line as it actually crosses to the model: the\n * JSON-encoded string (quotes, escapes) plus one array separator. Charging\n * raw UTF-8 would undercount model-visible bytes for escape-heavy content.\n */\nconst encodedLogLineBytes = (line: string): number => {\n try {\n return utf8ByteLength(JSON.stringify(line)) + 1;\n } catch {\n return Number.MAX_SAFE_INTEGER;\n }\n};\n\nconst budgetedLogs = (\n logs: ReadonlyArray<string>,\n remainingBytes: number,\n): ReadonlyArray<string> => {\n const kept: Array<string> = [];\n let used = 0;\n let truncated = false;\n\n for (const raw of logs) {\n // Per-line cap keeps every kept line inside the BoundedLogLine schema.\n const line =\n raw.length > MAX_EGRESS_LOG_LINE_CHARACTERS\n ? `${raw.slice(0, MAX_EGRESS_LOG_LINE_CHARACTERS - 1)}…`\n : raw;\n\n const bytes = encodedLogLineBytes(line);\n\n if (kept.length >= 4_096 || used + bytes > remainingBytes) {\n truncated = true;\n break;\n }\n kept.push(line);\n used += bytes;\n }\n if (truncated) {\n // Truncation is never silent: drop kept lines from the end until the\n // marker itself fits inside the budget.\n const markerBytes = encodedLogLineBytes(truncationMarker);\n\n while (kept.length > 0 && used + markerBytes > remainingBytes) {\n used -= encodedLogLineBytes(kept.pop() ?? \"\");\n }\n if (markerBytes <= remainingBytes) {\n kept.push(truncationMarker);\n }\n }\n\n return kept;\n};\n\nconst boundedMessage = (message: string): string => message.slice(0, maxFailureTextLength);\n\nconst executionFailureMessage = (error: CodeExecutionError): string => {\n switch (error._tag) {\n case \"CodeExecutionTimeoutError\": {\n return `The program exceeded its ${Duration.format(error.maxWallTime)} ${error.kind} budget`;\n }\n case \"CodeOutputLimitError\": {\n return `The ${error.surface} limit of ${error.limit} bytes was exceeded (${error.observed} bytes observed)`;\n }\n case \"CodeHostCallLimitError\": {\n return `The pass exceeded its executor cap of ${error.limit} host calls`;\n }\n default: {\n return error.message;\n }\n }\n};\n\n/** UTF-8-aware truncation so a message can never exceed the aggregate budget. */\nconst truncateToUtf8Bytes = (value: string, maxBytes: number): string => {\n if (utf8ByteLength(value) <= maxBytes) {\n return value;\n }\n let output = \"\";\n let used = 0;\n\n for (const character of value) {\n const bytes = utf8ByteLength(character);\n\n if (used + bytes + 3 > maxBytes) {\n break;\n }\n output += character;\n used += bytes;\n }\n\n return `${output}…`;\n};\n\ntype EgressRedactor<Requirements = never> = NonNullable<\n CodeModeOptions<CodeModeNamespaces, Requirements>[\"redactEgress\"]\n>;\n\n// ---------------------------------------------------------------------------\n// Builder\n// ---------------------------------------------------------------------------\n\nconst make = <\n const Name extends string,\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n>(\n name: Name,\n options: CodeModeOptions<Namespaces, RedactionRequirements>,\n): CodeModeDefinition<Name, Namespaces, RedactionRequirements> => {\n const limits = options.limits ?? defaultLimits;\n const maxEgressBytes = options.maxEgressBytes ?? defaultMaxEgressBytes;\n\n // Fail closed on an invalid egress bound: NaN would make every size\n // comparison false and Infinity would remove the bound entirely.\n if (\n !Number.isSafeInteger(maxEgressBytes) ||\n maxEgressBytes < 256 ||\n maxEgressBytes > 4 * 1024 * 1024\n ) {\n throw new Error(\n `Code Mode maxEgressBytes must be an integer between 256 and ${4 * 1024 * 1024}; received ${String(maxEgressBytes)}`,\n );\n }\n\n // Construction-time fail-closed validation (CAP-014).\n const methods: Array<ResolvedMethod> = [];\n const toolsByName = new Map<string, Tool.Any>();\n const methodToTool = new Map<string, string>();\n\n for (const [namespace, namespaceMethods] of Object.entries(options.tools)) {\n if (Option.isNone(decodeIdentifier(namespace))) {\n throw new Error(`Code Mode namespace ${namespace} is not a valid JavaScript identifier`);\n }\n const entries = Object.entries(namespaceMethods);\n\n if (entries.length === 0) {\n throw new Error(`Code Mode namespace ${namespace} declares no methods`);\n }\n for (const [method, tool] of entries) {\n if (Option.isNone(decodeIdentifier(method))) {\n throw new Error(\n `Code Mode method ${namespace}.${method} is not a valid JavaScript identifier`,\n );\n }\n const approval = tool.needsApproval;\n\n if (approval !== undefined && approval !== false) {\n throw new Error(\n `Code Mode rejects Tool ${tool.name} (${namespace}.${method}): approval-requiring Tools cannot be invoked programmatically in the ephemeral slice`,\n );\n }\n const existing = toolsByName.get(tool.name);\n\n if (existing !== undefined && existing !== tool) {\n throw new Error(\n `Code Mode selected two different Tools named ${tool.name}; Tool names must identify one Tool`,\n );\n }\n toolsByName.set(tool.name, tool);\n methodToTool.set(`${namespace}.${method}`, tool.name);\n methods.push({ namespace, method, tool });\n }\n }\n if (methods.length === 0) {\n throw new Error(\"Code Mode requires at least one allowlisted Tool\");\n }\n\n // Declarations derive from the encoded Schemas and fail construction closed\n // on anything the renderer cannot express.\n const declarations = renderDeclarations(methods);\n\n const methodsByPath = new Map(\n methods.map((method) => [`${method.namespace}.${method.method}`, method]),\n );\n\n const describe = Effect.fnUntraced(function* (\n selected: ReadonlyArray<string>,\n options?: { readonly maxBytes?: number | undefined },\n ) {\n const paths = yield* Schema.decodeEffect(DescriptionMethods)(selected).pipe(\n Effect.mapError(() =>\n CodeModeDescriptionError.make({\n reason: \"invalid-selection\",\n message:\n \"Select between 1 and 64 unique namespace.method names, each at most 257 characters\",\n }),\n ),\n );\n\n const maxBytes = yield* Schema.decodeEffect(DescriptionByteLimit)(\n options?.maxBytes ?? 16 * 1024,\n ).pipe(\n Effect.mapError(() =>\n CodeModeDescriptionError.make({\n reason: \"invalid-bound\",\n message: \"The documentation byte limit must be an integer between 1 and 262144\",\n }),\n ),\n );\n\n const selectedMethods: Array<ResolvedMethod> = [];\n\n for (const path of paths) {\n const method = methodsByPath.get(path);\n\n if (method === undefined) {\n return yield* CodeModeDescriptionError.make({\n reason: \"unknown-method\",\n message: \"The selection contains a method outside this Code Mode allowlist\",\n });\n }\n selectedMethods.push(method);\n }\n\n const documentation = renderDeclarations(selectedMethods);\n\n if (utf8ByteLength(documentation) > maxBytes) {\n return yield* CodeModeDescriptionError.make({\n reason: \"limit-exceeded\",\n message: `The selected declarations exceed the ${maxBytes}-byte documentation limit; select fewer methods or raise the limit`,\n });\n }\n\n return documentation;\n });\n\n const namespaces = [...new Set(methods.map((method) => method.namespace))].map((namespace) =>\n CodeExecutionNamespace.make({\n name: namespace,\n methods: methods\n .filter((method) => method.namespace === namespace)\n .map((method) => method.method),\n }),\n );\n\n const description = [\n options.description,\n \"\",\n \"The `code` argument must be one JavaScript async function expression; the sandbox invokes it exactly once with no arguments. It runs isolated with no ambient network, filesystem, environment, or secrets. Return one JSON value. `console.log` output is captured within a bounded budget and returned alongside the result.\",\n \"Namespace methods return Promises. An expected Tool failure rejects with a JSON envelope carrying a stable `_tag`; catch it to branch. Use Promise.all for independent calls; the host bounds concurrency. Await every call you need. Writes may complete before a failure: inspect call outcomes and never blindly retry a program.\",\n ...(options.includeDeclarations === false\n ? []\n : [\"\", \"Sandbox globals:\", \"```ts\", declarations, \"```\"]),\n ].join(\"\\n\");\n\n const tool = Tool.make(name, {\n description,\n parameters: CodeModeParameters,\n success: CodeModeSuccess,\n failure: CodeModeFailure,\n failureMode: \"return\",\n })\n .annotate(Tool.Readonly, false)\n .annotate(ToolExecutionClassAnnotation, \"uncertain\")\n .annotate(IncludesCatalogDocumentation, options.includeDeclarations !== false)\n .annotate(\n AdditionalToolCatalog,\n Object.freeze(methods.map((method) => Object.freeze({ ...method }))),\n )\n .addDependency(ToolBroker) as CodeModeTool<Name>;\n\n const outerToolkit = Toolkit.make(tool);\n\n /**\n * The nested namespace record collapses into one Toolkit keyed by exact\n * Tool names. The assertion restores the name-keyed record type TypeScript\n * cannot compute from `Map` iteration; construction above guarantees the\n * name uniqueness the type states.\n */\n const selectedToolkit = Toolkit.make(...toolsByName.values()) as unknown as Toolkit.Toolkit<\n CodeModeSelectedRecord<Namespaces>\n >;\n\n const executionRequest = (\n code: string,\n visibleNamespaces: ReadonlyArray<CodeExecutionNamespace>,\n ): CodeExecutionRequest =>\n CodeExecutionRequest.make({\n language: \"javascript\",\n source: code,\n namespaces: visibleNamespaces,\n network: NetworkDisabled.make({}),\n limits,\n });\n\n const routeHostCall = (\n pass: ToolBrokerPass,\n hostCall: CodeHostCall,\n visiblePaths: ReadonlySet<string> | undefined,\n ): Effect.Effect<CodeHostCallResult> =>\n Effect.gen(function* () {\n const path = `${hostCall.namespace}.${hostCall.method}`;\n\n const toolName =\n visiblePaths === undefined || visiblePaths.has(path) ? methodToTool.get(path) : undefined;\n\n if (toolName === undefined) {\n return {\n _tag: \"CodeHostCallFailure\",\n error: {\n _tag: \"UnknownCodeModeMethod\",\n message: \"The requested method is not available in this pass\",\n },\n } as const;\n }\n\n const outcome: ProgrammaticCallOutcome = yield* pass.invoke({\n toolName,\n encodedArguments: hostCall.argument,\n });\n\n switch (outcome._tag) {\n case \"ProgrammaticCallSuccess\": {\n const value = decodeBrokerJson(outcome.encodedResult);\n\n return Option.isSome(value)\n ? ({ _tag: \"CodeHostCallSuccess\", value: value.value } as const)\n : ({ _tag: \"CodeHostCallFailure\", error: brokerProtocolEnvelope } as const);\n }\n case \"ProgrammaticCallFailure\": {\n const value = decodeBrokerJson(outcome.encodedResult);\n\n return {\n _tag: \"CodeHostCallFailure\",\n error: Option.isSome(value) ? value.value : brokerProtocolEnvelope,\n } as const;\n }\n case \"ProgrammaticCallError\": {\n return {\n _tag: \"CodeHostCallFailure\",\n error: { _tag: outcome.errorTag, message: outcome.message },\n } as const;\n }\n }\n });\n\n const build = Effect.gen(function* () {\n const captured = yield* Effect.context<never>();\n const redactionServices = yield* Effect.context<Exclude<RedactionRequirements, Scope.Scope>>();\n const configuredRedactor = options.redactEgress;\n\n const redact: EgressRedactor | undefined =\n configuredRedactor === undefined\n ? undefined\n : (egress) =>\n Effect.scoped(configuredRedactor(egress)).pipe(\n // Merge invocation-local services before opening the redaction Scope.\n // The inner Scope shadows any Scope retained in the construction context.\n Effect.updateContext((current: Context.Context<never>) =>\n Context.merge(current, redactionServices),\n ),\n );\n\n const withHandler = yield* selectedToolkit;\n const executor = yield* CodeExecutor;\n\n const successEgress = (\n execution: CodeExecutionResult,\n ): Effect.Effect<CodeModeSuccess, CodeModeFailure> =>\n Effect.gen(function* () {\n let egress: { readonly result: Schema.Json; readonly logs: ReadonlyArray<string> } = {\n result: execution.value,\n logs: execution.logs,\n };\n\n if (redact !== undefined) {\n egress = yield* redact(egress);\n }\n const resultBytes = encodedJsonByteLength(egress.result);\n\n if (resultBytes === undefined || resultBytes > maxEgressBytes) {\n return yield* CodeModeFailure.make({\n errorTag: \"CodeModeEgressExceeded\",\n message: `The program result of ${resultBytes ?? \"unencodable\"} bytes exceeds the ${maxEgressBytes}-byte model-visible egress budget; return a smaller value`,\n logs: budgetedLogs(egress.logs, Math.max(0, maxEgressBytes - 256)),\n });\n }\n\n return CodeModeSuccess.make({\n result: egress.result,\n logs: budgetedLogs(egress.logs, maxEgressBytes - resultBytes),\n });\n });\n\n /**\n * The failure half of the aggregate egress policy (CAP-016): the configured\n * redaction pass covers failure logs and thrown values exactly like success\n * egress — a program cannot leak by logging and then throwing — and the\n * message itself is bounded by the budget, not only by its own schema cap.\n */\n const failureEgress = (\n error: CodeExecutionError | ToolBrokerUnavailableError | ToolBrokerConfigurationError,\n ): Effect.Effect<CodeModeFailure> =>\n Effect.gen(function* () {\n if (\n error._tag === \"ToolBrokerUnavailableError\" ||\n error._tag === \"ToolBrokerConfigurationError\"\n ) {\n return CodeModeFailure.make({\n errorTag: error._tag,\n message: truncateToUtf8Bytes(boundedMessage(error.message), maxEgressBytes),\n logs: [],\n });\n }\n let logs: ReadonlyArray<string> = \"logs\" in error ? error.logs : [];\n let candidateThrown = error._tag === \"CodeProgramFailedError\" ? error.thrown : undefined;\n\n if (redact !== undefined) {\n const redacted = yield* redact({ result: candidateThrown ?? null, logs });\n\n logs = redacted.logs;\n candidateThrown = candidateThrown === undefined ? undefined : redacted.result;\n }\n\n const message = truncateToUtf8Bytes(\n boundedMessage(executionFailureMessage(error)),\n maxEgressBytes,\n );\n\n const messageBytes = utf8ByteLength(message);\n\n // `thrown` is included only when it fits TOGETHER with the message inside\n // the aggregate budget, and it reduces the log allowance only when it is\n // actually included.\n const candidateBytes =\n candidateThrown === undefined ? undefined : encodedJsonByteLength(candidateThrown);\n\n const includeThrown =\n candidateThrown !== undefined &&\n candidateBytes !== undefined &&\n messageBytes + candidateBytes <= maxEgressBytes;\n\n const remaining = Math.max(\n 0,\n maxEgressBytes - messageBytes - (includeThrown ? (candidateBytes ?? 0) : 0),\n );\n\n return CodeModeFailure.make({\n errorTag: error._tag,\n message,\n logs: budgetedLogs(logs, remaining),\n ...(includeThrown ? { thrown: candidateThrown } : {}),\n });\n });\n\n const invoke = Effect.fnUntraced(function* (parameters: { readonly code: string }) {\n const broker = yield* ToolBroker;\n // Resolve invocation authority before restoring captured construction services. A Layer\n // built under an older Run must not restore that Run's catalogue or hidden method names.\n const catalogue = yield* Effect.serviceOption(CurrentToolCatalog);\n\n const visiblePaths = Option.isNone(catalogue)\n ? undefined\n : new Set(\n catalogue.value.entries.flatMap((entry) =>\n entry.kind === \"code-mode\" &&\n entry.nativeToolName === name &&\n methodsByPath.get(`${entry.namespace}.${entry.method}`)?.tool.name === entry.tool.name\n ? [`${entry.namespace}.${entry.method}`]\n : [],\n ),\n );\n\n const visibleNamespaces =\n visiblePaths === undefined\n ? namespaces\n : namespaces.flatMap((namespace) => {\n const allowed = namespace.methods.filter((method) =>\n visiblePaths.has(`${namespace.name}.${method}`),\n );\n\n return allowed.length === 0\n ? []\n : [CodeExecutionNamespace.make({ name: namespace.name, methods: allowed })];\n });\n\n let calls: ReadonlyArray<ProgrammaticCallRecord> = [];\n\n const execution = Effect.gen(function* () {\n const pass = yield* broker.openPass(withHandler, {\n maxResultBytes: limits.maxHostCallResultBytes,\n concurrency: limits.maxHostCallConcurrency ?? 4,\n });\n\n const host = CodeExecutionHost.of({\n call: (hostCall) => routeHostCall(pass, hostCall, visiblePaths),\n });\n\n return yield* executor.execute(executionRequest(parameters.code, visibleNamespaces)).pipe(\n Effect.provideService(CodeExecutionHost, host),\n Effect.scoped,\n Effect.onExit((exit) =>\n Effect.gen(function* () {\n calls = yield* pass.snapshot;\n if (options.onPassExit !== undefined) {\n yield* Effect.scoped(\n options.onPassExit({\n status: Exit.isSuccess(exit)\n ? \"completed\"\n : Cause.hasInterrupts(exit.cause)\n ? \"interrupted\"\n : Cause.hasDies(exit.cause)\n ? \"defect\"\n : \"failed\",\n calls,\n }),\n ).pipe(Effect.provideContext(redactionServices));\n }\n }),\n ),\n );\n }).pipe(\n Effect.scoped,\n // The live engine broker is re-provided innermost so a Layer built\n // inside another Run can never shadow it; the captured construction\n // context supplies the selected handlers' services (same idiom as\n // Subagent.layer). TypeScript cannot reduce the deferred Exclude\n // over the generic namespace record, so the same private-assertion\n // contract as the engine's provideHookServices pins the identity\n // that providing the captured Context leaves no requirements; it\n // never bypasses validation.\n Effect.provideService(ToolBroker, broker),\n Effect.provideContext(captured),\n ) as Effect.Effect<\n CodeExecutionResult,\n CodeExecutionError | ToolBrokerUnavailableError | ToolBrokerConfigurationError\n >;\n\n return yield* execution.pipe(\n Effect.catch((error) => failureEgress(error).pipe(Effect.flatMap(Effect.fail))),\n Effect.flatMap(successEgress),\n Effect.mapError((failure) => {\n if (calls.length === 0) return failure;\n\n const complete = CodeModeFailure.make({\n errorTag: failure.errorTag,\n message: failure.message,\n logs: failure.logs,\n ...(failure.thrown === undefined ? {} : { thrown: failure.thrown }),\n calls,\n omittedCalls: 0,\n });\n\n if ((encodedJsonByteLength(complete) ?? Infinity) <= maxEgressBytes) return complete;\n\n // Evidence takes priority over logs and thrown values. Never silently omit calls.\n const base = {\n errorTag: failure.errorTag,\n message: truncateToUtf8Bytes(failure.message, Math.min(256, maxEgressBytes / 4)),\n logs: [],\n };\n\n const kept: Array<ProgrammaticCallRecord> = [];\n\n for (const call of calls) {\n const candidate = CodeModeFailure.make({\n ...base,\n calls: [...kept, call],\n omittedCalls: calls.length - kept.length - 1,\n });\n\n if ((encodedJsonByteLength(candidate) ?? Infinity) > maxEgressBytes) break;\n kept.push(call);\n }\n\n return CodeModeFailure.make({\n ...base,\n calls: kept,\n omittedCalls: calls.length - kept.length,\n });\n }),\n );\n });\n\n return { [name]: invoke } as unknown as Toolkit.HandlersFrom<CodeModeTools<Name>>;\n });\n\n /**\n * TypeScript cannot unify the two spellings of the singleton Tool record\n * (`CodeModeTools<Name>` versus the toolkit's name-remapped form) over a\n * generic `Name`, nor reduce the deferred `Exclude` when `toLayer`\n * subtracts what `build` consumed; the assertions pin the layer to its\n * documented requirement surface and never bypass validation.\n */\n const handlers = outerToolkit.toLayer(\n build as unknown as Effect.Effect<\n Toolkit.HandlersFrom<Toolkit.ToolsByName<readonly [CodeModeTool<Name>]>>,\n never,\n | CodeExecutor\n | Tool.HandlersFor<CodeModeSelectedRecord<Namespaces>>\n | Exclude<RedactionRequirements, Scope.Scope>\n >,\n ) as unknown as Layer.Layer<\n Tool.HandlersFor<CodeModeTools<Name>>,\n never,\n CodeModeLayerRequirements<Namespaces, RedactionRequirements>\n >;\n\n return Object.freeze({\n name,\n description,\n declarations,\n describe,\n namespaces,\n limits,\n maxEgressBytes,\n tool,\n handlers,\n });\n};\n\n/**\n * Fail-closed JSON boundary for broker outcomes: hostile values can throw\n * from trap getters during decode, and a value outside the JSON surface must\n * become a typed failure envelope — never a fabricated success.\n */\nconst decodeBrokerJson = (value: unknown): Option.Option<Schema.Json> => {\n try {\n return Schema.decodeUnknownOption(Schema.Json)(value);\n } catch {\n return Option.none();\n }\n};\n\nconst brokerProtocolEnvelope: Schema.Json = {\n _tag: \"CodeModeProtocolError\",\n message: \"The broker returned a value outside the JSON surface\",\n};\n\n// The engine annotation is imported under a local alias to keep the builder\n// readable next to Effect AI's own `Tool.Readonly` annotation.\nimport { ToolExecutionClass as ToolExecutionClassAnnotation } from \"../engine/DurableStep.ts\";\n\n/** Code Mode builder namespace (capability spec §9.1). */\nexport { make };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeMode.mjs","names":["ToolExecutionClassAnnotation"],"sources":["../../src/capabilities/CodeMode.ts"],"sourcesContent":["import {\n type Layer,\n Cause,\n Context,\n Duration,\n Effect,\n Exit,\n Option,\n Schema,\n type Scope,\n} from \"effect\";\nimport { Tool, Toolkit } from \"effect/ai\";\n\nimport { utf8ByteLength } from \"../core/internal/utf8.ts\";\nimport { AdditionalToolCatalog, IncludesCatalogDocumentation } from \"../core/ToolExposure.ts\";\nimport {\n type ToolBrokerConfigurationError,\n type ToolBrokerUnavailableError,\n ToolBroker,\n type ProgrammaticCallOutcome,\n type ToolBrokerPass,\n ProgrammaticCallRecord,\n} from \"../engine/ToolBroker.ts\";\nimport { CurrentToolCatalog } from \"../engine/ToolExposure.ts\";\nimport {\n type CodeExecutionError,\n CodeExecutionHost,\n CodeExecutionLimits,\n CodeExecutionNamespace,\n CodeExecutionRequest,\n CodeExecutor,\n JsIdentifier,\n type CodeExecutionResult,\n type CodeHostCall,\n type CodeHostCallResult,\n} from \"../sandbox/CodeExecutor.ts\";\nimport { NetworkDisabled } from \"../sandbox/Sandbox.ts\";\n\n/**\n * Code Mode (D-035, ADR-0017; capability spec §9.1): one native Effect AI\n * Tool whose input is bounded JavaScript source, executed in one isolated\n * `CodeExecutor` pass that may call an explicit construction-time allowlist\n * of existing Tools through typed sandbox globals and the engine-owned\n * `ToolBroker`. The builder follows the Delegation pattern: an explicit\n * record of selected Tools plus namespace mapping fixed at construction,\n * returning an ordinary Tool and a handler Layer, with no ambient registry\n * (CAP-014). Deployment class `E` only.\n */\n\nconst maxFailureTextLength = 4 * 1024;\nconst BoundedFailureText = Schema.String.check(Schema.isMaxLength(maxFailureTextLength));\nconst BoundedErrorTag = Schema.NonEmptyString.check(Schema.isMaxLength(256));\nconst BoundedLogLine = Schema.String.check(Schema.isMaxLength(16 * 1024));\nconst BoundedLogs = Schema.Array(BoundedLogLine).check(Schema.isMaxLength(4_096));\nconst BoundedCode = Schema.NonEmptyString.check(Schema.isMaxLength(512 * 1024));\n\n/** A pass-local report, available to the host even when the caller interrupts execution. */\nexport const CodeModePassReport = Schema.Struct({\n status: Schema.Literals([\"completed\", \"failed\", \"interrupted\", \"defect\"]),\n calls: Schema.Array(ProgrammaticCallRecord),\n});\n\nexport type CodeModePassReport = typeof CodeModePassReport.Type;\n\nconst encodedJsonByteLength = (value: unknown): number | undefined => {\n try {\n const encoded = JSON.stringify(value);\n\n return encoded === undefined ? undefined : utf8ByteLength(encoded);\n } catch {\n return undefined;\n }\n};\n\n/** Model-decoded Code Mode parameters: one async function expression. */\nexport const CodeModeParameters = Schema.Struct({\n code: BoundedCode,\n});\n\n/**\n * The bounded model-visible success: the program's JSON result plus captured\n * logs, both already passed through the aggregate egress budget (CAP-016).\n */\nexport class CodeModeSuccess extends Schema.Class<CodeModeSuccess>(\n \"@effect-agent/capabilities/CodeModeSuccess\",\n)({\n result: Schema.Json,\n logs: BoundedLogs,\n}) {}\n\n/**\n * The bounded model-visible failure envelope. `failureMode: \"return\"` turns\n * it into a failed Tool result, so a model can correct a failing program\n * without a blind retry; it carries the same bounded log capture as success\n * plus the bounded thrown value where one exists, all inside the same\n * aggregate egress budget (CAP-016).\n */\nexport class CodeModeFailure extends Schema.TaggedError<CodeModeFailure>()(\"CodeModeFailure\", {\n errorTag: BoundedErrorTag,\n message: BoundedFailureText,\n logs: BoundedLogs,\n thrown: Schema.optionalKey(Schema.Json),\n /** Invocation-ordered evidence that fits the egress budget. This is not a replay plan. */\n calls: Schema.optionalKey(Schema.Array(ProgrammaticCallRecord)),\n omittedCalls: Schema.optionalKey(Schema.Natural),\n}) {}\n\n/** A selective documentation request is invalid or cannot fit its declared byte budget. */\nexport class CodeModeDescriptionError extends Schema.TaggedError<CodeModeDescriptionError>()(\n \"CodeModeDescriptionError\",\n {\n reason: Schema.Literals([\n \"invalid-selection\",\n \"unknown-method\",\n \"invalid-bound\",\n \"limit-exceeded\",\n ]),\n message: BoundedFailureText,\n },\n) {}\n\nconst DescriptionMethods = Schema.Array(Schema.NonEmptyString.check(Schema.isMaxLength(257))).check(\n Schema.isMinLength(1),\n Schema.isMaxLength(64),\n Schema.isUnique(),\n);\n\nconst DescriptionByteLimit = Schema.Int.check(\n Schema.isBetween({ minimum: 1, maximum: 256 * 1024 }),\n);\n\n/** The namespace-record shape accepted by `CodeMode.make`. */\nexport type CodeModeNamespaces = Record<string, Record<string, Tool.Any>>;\n\n/**\n * Union of every Tool selected across all namespaces, computed distributively\n * per namespace: indexing the namespace union with the INTERSECTION of method\n * keys would erase every Tool once two namespaces have disjoint methods.\n */\nexport type CodeModeSelectedTool<Namespaces extends CodeModeNamespaces> = {\n [Namespace in keyof Namespaces]: Namespaces[Namespace][keyof Namespaces[Namespace]];\n}[keyof Namespaces];\n\n/** The selected Tools re-keyed by their own Tool names. */\nexport type CodeModeSelectedRecord<Namespaces extends CodeModeNamespaces> = {\n readonly [T in CodeModeSelectedTool<Namespaces> as T[\"name\"]]: T;\n};\n\n/**\n * The native Effect AI Tool created by `CodeMode.make` (CAP-014). Its only\n * per-call dependency is the engine-provided `ToolBroker`; the `CodeExecutor`\n * and every selected handler and redaction service are construction requirements of the handler\n * Layer instead, so they stay visible in the composed `R`.\n */\nexport type CodeModeTool<Name extends string> = Tool.Tool<\n Name,\n {\n readonly parameters: typeof CodeModeParameters;\n readonly success: typeof CodeModeSuccess;\n readonly failure: typeof CodeModeFailure;\n readonly failureMode: \"return\";\n },\n ToolBroker\n>;\n\n/** Singleton Tool record provided by one Code Mode handler Layer. */\nexport type CodeModeTools<Name extends string> = {\n readonly [Key in Name]: CodeModeTool<Name>;\n};\n\n/** Construction requirements of the Code Mode handler Layer. */\nexport type CodeModeLayerRequirements<\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n> =\n | CodeExecutor\n | Exclude<RedactionRequirements, Scope.Scope>\n | Tool.HandlersFor<CodeModeSelectedRecord<Namespaces>>\n | Tool.HandlerServices<CodeModeSelectedTool<Namespaces>>;\n\nexport interface CodeModeOptions<\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n> {\n /** Model-visible description; the builder appends the sandbox contract. */\n readonly description: string;\n /** Include all sandbox declarations in the model-facing description. Defaults to true. */\n readonly includeDeclarations?: boolean | undefined;\n /**\n * Explicit allowlist: namespace name → method name → native Effect AI\n * Tool. Reads and mutations are allowed; calls requiring additional approval fail closed.\n */\n readonly tools: Namespaces;\n /** Executor limits for one pass; a bounded default applies when omitted. */\n readonly limits?: CodeExecutionLimits | undefined;\n /**\n * Aggregate model-visible egress budget in UTF-8 bytes across the final\n * result, captured logs, and any thrown value (CAP-016). Default 65536.\n */\n readonly maxEgressBytes?: number | undefined;\n /**\n * Host-only ephemeral report after executor resources and invocation fibers close, including\n * failure, defect, and interruption. It contains no arguments/results and is never a checkpoint.\n * Keep this total callback bounded; its services are captured with the handler Layer.\n */\n readonly onPassExit?:\n | ((report: CodeModePassReport) => Effect.Effect<void, never, RedactionRequirements>)\n | undefined;\n /**\n * Optional aggregate redaction pass applied to the model-visible egress\n * before the byte budget. Its services are acquired with the handler Layer;\n * temporary resources close with each redaction invocation.\n * It must be total; a defect stays a defect.\n */\n readonly redactEgress?:\n | ((egress: {\n readonly result: Schema.Json;\n readonly logs: ReadonlyArray<string>;\n }) => Effect.Effect<\n {\n readonly result: Schema.Json;\n readonly logs: ReadonlyArray<string>;\n },\n never,\n RedactionRequirements\n >)\n | undefined;\n}\n\n/**\n * An immutable Code Mode definition: one model-facing Tool over an explicit\n * allowlist, plus the handler Layer that runs generated programs through the\n * `CodeExecutor` port and the engine-owned broker. It owns no acquired\n * resources.\n */\nexport interface CodeModeDefinition<\n Name extends string,\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n> {\n readonly name: Name;\n /** The assembled model-facing description, optionally including all declarations. */\n readonly description: string;\n /** Rendered TypeScript declarations of the sandbox globals (documentation only). */\n readonly declarations: string;\n /**\n * Render complete encoded-schema declarations for 1–64 unique, exact namespace.method names.\n * The UTF-8 byte limit defaults to 16384 and must be an integer from 1 through 262144.\n * Oversized documentation fails rather than truncating a declaration. This host operation\n * does not authorize a model to see the selected methods; filter selections by current\n * visibility and inherited grants before returning its output to a model.\n */\n readonly describe: (\n methods: ReadonlyArray<string>,\n options?: { readonly maxBytes?: number | undefined },\n ) => Effect.Effect<string, CodeModeDescriptionError>;\n /** The executor-facing namespace catalog derived from the allowlist. */\n readonly namespaces: ReadonlyArray<CodeExecutionNamespace>;\n readonly limits: CodeExecutionLimits;\n readonly maxEgressBytes: number;\n /** The ordinary Effect AI Tool to include in the model-facing Toolkit. */\n readonly tool: CodeModeTool<Name>;\n /** Handler Layer; selected handler requirements stay visible in `R`. */\n readonly handlers: Layer.Layer<\n Tool.HandlersFor<CodeModeTools<Name>>,\n never,\n CodeModeLayerRequirements<Namespaces, RedactionRequirements>\n >;\n}\n\nconst defaultLimits = CodeExecutionLimits.make({\n maxSourceBytes: 256 * 1024,\n maxWallTime: Duration.seconds(30),\n maxLogBytes: 256 * 1024,\n maxResultBytes: 1024 * 1024,\n maxHostCalls: 64,\n maxHostCallArgumentBytes: 256 * 1024,\n maxHostCallResultBytes: 1024 * 1024,\n});\n\nconst defaultMaxEgressBytes = 64 * 1024;\n\n// ---------------------------------------------------------------------------\n// Declaration rendering (capability spec §9.1): the encoded side of each\n// Schema — the JSON that actually crosses the sandbox boundary — rendered as\n// TypeScript documentation via the same JSON-schema derivation Effect AI\n// applies to Tool parameters. A schema the renderer cannot express fails Tool\n// construction closed rather than degrading to `unknown`.\n// ---------------------------------------------------------------------------\n\nconst MAX_RENDER_DEPTH = 24;\n\nconst isJsonSchemaRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst renderJsonSchemaType = (\n schema: unknown,\n defs: Record<string, unknown>,\n depth: number,\n indent: string,\n): string => {\n if (depth > MAX_RENDER_DEPTH) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously bounds recursive Schema declaration rendering before creating the Tool.\n throw new Error(\"Code Mode declaration rendering exceeded its depth bound\");\n }\n if (!isJsonSchemaRecord(schema)) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects unsupported JSON Schema declaration fragments.\n throw new Error(`Code Mode cannot render the JSON schema fragment ${JSON.stringify(schema)}`);\n }\n // An empty schema is explicitly unconstrained, including Schema.Json's array items.\n // This is a faithful declaration; unrecognized nonempty fragments still fail below.\n if (Object.keys(schema).length === 0) return \"unknown\";\n const reference = schema.$ref;\n\n if (typeof reference === \"string\") {\n const match = /^#\\/\\$defs\\/(.+)$/.exec(reference);\n // JSON-pointer tokens escape `/` as `~1` and `~` as `~0`.\n const key = match === null ? undefined : match[1].replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n const resolved = key === undefined ? undefined : defs[key];\n\n if (resolved === undefined) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects unresolved declaration references.\n throw new Error(`Code Mode cannot resolve the JSON schema reference ${reference}`);\n }\n\n return renderJsonSchemaType(resolved, defs, depth + 1, indent);\n }\n if (Array.isArray(schema.enum)) {\n return schema.enum.map((value) => JSON.stringify(value)).join(\" | \");\n }\n if (\"const\" in schema) {\n return JSON.stringify(schema.const);\n }\n const union = schema.anyOf ?? schema.oneOf;\n\n if (Array.isArray(union)) {\n return union.map((member) => renderJsonSchemaType(member, defs, depth + 1, indent)).join(\" | \");\n }\n const type = schema.type;\n\n if (Array.isArray(type)) {\n return type\n .map((member) => renderJsonSchemaType({ ...schema, type: member }, defs, depth + 1, indent))\n .join(\" | \");\n }\n switch (type) {\n case \"string\": {\n return \"string\";\n }\n case \"number\":\n case \"integer\": {\n return \"number\";\n }\n case \"boolean\": {\n return \"boolean\";\n }\n case \"null\": {\n return \"null\";\n }\n case \"array\": {\n if (!(\"items\" in schema)) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires item schemas for array declarations.\n throw new Error(\"Code Mode cannot render an array schema without items\");\n }\n\n return `ReadonlyArray<${renderJsonSchemaType(schema.items, defs, depth + 1, indent)}>`;\n }\n case \"object\":\n case undefined: {\n if (isJsonSchemaRecord(schema.properties)) {\n const required = Array.isArray(schema.required) ? schema.required : [];\n const inner = `${indent} `;\n\n const fields = Object.entries(schema.properties).map(([key, property]) => {\n const optional = required.includes(key) ? \"\" : \"?\";\n // A JSON property name need not be a TypeScript identifier.\n const rendered = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\n\n return `${inner}readonly ${rendered}${optional}: ${renderJsonSchemaType(property, defs, depth + 1, inner)};`;\n });\n\n return fields.length === 0 ? \"{}\" : `{\\n${fields.join(\"\\n\")}\\n${indent}}`;\n }\n if (isJsonSchemaRecord(schema.additionalProperties)) {\n return `Record<string, ${renderJsonSchemaType(schema.additionalProperties, defs, depth + 1, indent)}>`;\n }\n // Schema.Record(Schema.String, Schema.Never) accepts only an empty object.\n if (\n type === \"object\" &&\n !(\"properties\" in schema) &&\n !(\"patternProperties\" in schema) &&\n schema.additionalProperties === false\n ) {\n return \"Record<string, never>\";\n }\n // A bare `{ \"type\": \"object\" }` states \"any JSON object\" (Schema.Json's\n // object member derives to exactly this); rendering it as an\n // unconstrained record is faithful, not a deriver degradation.\n if (type === \"object\" && !(\"properties\" in schema) && !(\"additionalProperties\" in schema)) {\n return \"Record<string, unknown>\";\n }\n break;\n }\n default: {\n break;\n }\n }\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects declaration schemas it cannot faithfully render.\n throw new Error(\n `Code Mode cannot render the JSON schema fragment ${JSON.stringify(schema).slice(0, 200)}; fix or simplify the Tool's Schema`,\n );\n};\n\nconst renderTopLevel = (jsonSchema: unknown, indent: string): string => {\n const defs =\n isJsonSchemaRecord(jsonSchema) && isJsonSchemaRecord(jsonSchema.$defs)\n ? jsonSchema.$defs\n : ({} as Record<string, unknown>);\n\n return renderJsonSchemaType(jsonSchema, defs, 0, indent);\n};\n\nconst decodeIdentifier = Schema.decodeUnknownOption(JsIdentifier);\n\ninterface ResolvedMethod {\n readonly namespace: string;\n readonly method: string;\n readonly tool: Tool.Any;\n}\n\ninterface RenderedMethod extends ResolvedMethod {\n readonly declaration: string;\n}\n\n/** Render once at the synchronous construction boundary; describe only selects frozen declarations. */\nconst renderMethodDeclaration = (method: string, tool: Tool.Any): string => {\n const parameters = renderTopLevel(Tool.getJsonSchema(tool), \" \");\n const success = renderTopLevel(Tool.getJsonSchemaFromSchema(tool.successSchema), \" \");\n\n // A description is arbitrary text: newlines and comment terminators\n // must not be able to break out of the documentation comment.\n const safeDescription = tool.description?.replaceAll(\"*/\", \"*\\\\/\").replaceAll(/\\s*\\n\\s*/g, \" \");\n\n const description = safeDescription === undefined ? \"\" : ` /** ${safeDescription} */\\n`;\n\n return `${description} ${method}(input: ${parameters}): Promise<${success}>;`;\n};\n\nconst renderDeclarations = (methods: ReadonlyArray<RenderedMethod>): string => {\n const namespaces = new Map<string, Array<RenderedMethod>>();\n\n for (const method of methods) {\n const existing = namespaces.get(method.namespace) ?? [];\n\n existing.push(method);\n namespaces.set(method.namespace, existing);\n }\n\n const blocks = [...namespaces.entries()].map(([namespace, members]) => {\n const lines = members.map((member) => member.declaration);\n\n return `declare const ${namespace}: {\\n${lines.join(\"\\n\")}\\n};`;\n });\n\n return blocks.join(\"\\n\\n\");\n};\n\n// ---------------------------------------------------------------------------\n// Aggregate model-visible egress (CAP-016): the final result, captured logs,\n// and any thrown value share one byte budget. Logs are truncated line-by-line\n// with an explicit marker; a result that alone exceeds the budget is a typed\n// failure rather than silent truncation.\n// ---------------------------------------------------------------------------\n\nconst truncationMarker = \"… logs truncated by the egress budget\";\nconst MAX_EGRESS_LOG_LINE_CHARACTERS = 16_000;\n\n/**\n * Budget charge of one log line as it actually crosses to the model: the\n * JSON-encoded string (quotes, escapes) plus one array separator. Charging\n * raw UTF-8 would undercount model-visible bytes for escape-heavy content.\n */\nconst encodedLogLineBytes = (line: string): number => {\n try {\n return utf8ByteLength(JSON.stringify(line)) + 1;\n } catch {\n return Number.MAX_SAFE_INTEGER;\n }\n};\n\nconst budgetedLogs = (\n logs: ReadonlyArray<string>,\n remainingBytes: number,\n): ReadonlyArray<string> => {\n const kept: Array<string> = [];\n let used = 0;\n let truncated = false;\n\n for (const raw of logs) {\n // Per-line cap keeps every kept line inside the BoundedLogLine schema.\n const line =\n raw.length > MAX_EGRESS_LOG_LINE_CHARACTERS\n ? `${raw.slice(0, MAX_EGRESS_LOG_LINE_CHARACTERS - 1)}…`\n : raw;\n\n const bytes = encodedLogLineBytes(line);\n\n if (kept.length >= 4_096 || used + bytes > remainingBytes) {\n truncated = true;\n break;\n }\n kept.push(line);\n used += bytes;\n }\n if (truncated) {\n // Truncation is never silent: drop kept lines from the end until the\n // marker itself fits inside the budget.\n const markerBytes = encodedLogLineBytes(truncationMarker);\n\n while (kept.length > 0 && used + markerBytes > remainingBytes) {\n used -= encodedLogLineBytes(kept.pop() ?? \"\");\n }\n if (markerBytes <= remainingBytes) {\n kept.push(truncationMarker);\n }\n }\n\n return kept;\n};\n\nconst boundedMessage = (message: string): string => message.slice(0, maxFailureTextLength);\n\nconst executionFailureMessage = (error: CodeExecutionError): string => {\n switch (error._tag) {\n case \"CodeExecutionTimeoutError\": {\n return `The program exceeded its ${Duration.format(error.maxWallTime)} ${error.kind} budget`;\n }\n case \"CodeOutputLimitError\": {\n return `The ${error.surface} limit of ${error.limit} bytes was exceeded (${error.observed} bytes observed)`;\n }\n case \"CodeHostCallLimitError\": {\n return `The pass exceeded its executor cap of ${error.limit} host calls`;\n }\n default: {\n return error.message;\n }\n }\n};\n\n/** UTF-8-aware truncation so a message can never exceed the aggregate budget. */\nconst truncateToUtf8Bytes = (value: string, maxBytes: number): string => {\n if (utf8ByteLength(value) <= maxBytes) {\n return value;\n }\n let output = \"\";\n let used = 0;\n\n for (const character of value) {\n const bytes = utf8ByteLength(character);\n\n if (used + bytes + 3 > maxBytes) {\n break;\n }\n output += character;\n used += bytes;\n }\n\n return `${output}…`;\n};\n\ntype EgressRedactor<Requirements = never> = NonNullable<\n CodeModeOptions<CodeModeNamespaces, Requirements>[\"redactEgress\"]\n>;\n\n// ---------------------------------------------------------------------------\n// Builder\n// ---------------------------------------------------------------------------\n\nconst make = <\n const Name extends string,\n Namespaces extends CodeModeNamespaces,\n RedactionRequirements = never,\n>(\n name: Name,\n options: CodeModeOptions<Namespaces, RedactionRequirements>,\n): CodeModeDefinition<Name, Namespaces, RedactionRequirements> => {\n const limits = options.limits ?? defaultLimits;\n const maxEgressBytes = options.maxEgressBytes ?? defaultMaxEgressBytes;\n\n // Fail closed on an invalid egress bound: NaN would make every size\n // comparison false and Infinity would remove the bound entirely.\n if (\n !Number.isSafeInteger(maxEgressBytes) ||\n maxEgressBytes < 256 ||\n maxEgressBytes > 4 * 1024 * 1024\n ) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects invalid egress bounds before creating the Tool.\n throw new Error(\n `Code Mode maxEgressBytes must be an integer between 256 and ${4 * 1024 * 1024}; received ${String(maxEgressBytes)}`,\n );\n }\n\n // Construction-time fail-closed validation (CAP-014).\n const methods: Array<ResolvedMethod> = [];\n const toolsByName = new Map<string, Tool.Any>();\n const methodToTool = new Map<string, string>();\n\n for (const [namespace, namespaceMethods] of Object.entries(options.tools)) {\n if (Option.isNone(decodeIdentifier(namespace))) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires valid JavaScript namespace identifiers.\n throw new Error(`Code Mode namespace ${namespace} is not a valid JavaScript identifier`);\n }\n const entries = Object.entries(namespaceMethods);\n\n if (entries.length === 0) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects namespaces without callable methods.\n throw new Error(`Code Mode namespace ${namespace} declares no methods`);\n }\n for (const [method, tool] of entries) {\n if (Option.isNone(decodeIdentifier(method))) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires valid JavaScript method identifiers.\n throw new Error(\n `Code Mode method ${namespace}.${method} is not a valid JavaScript identifier`,\n );\n }\n const approval = tool.needsApproval;\n\n if (approval !== undefined && approval !== false) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects approval-requiring Tools from its programmatic allowlist.\n throw new Error(\n `Code Mode rejects Tool ${tool.name} (${namespace}.${method}): approval-requiring Tools cannot be invoked programmatically in the ephemeral slice`,\n );\n }\n const existing = toolsByName.get(tool.name);\n\n if (existing !== undefined && existing !== tool) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects conflicting Tools sharing one name.\n throw new Error(\n `Code Mode selected two different Tools named ${tool.name}; Tool names must identify one Tool`,\n );\n }\n toolsByName.set(tool.name, tool);\n methodToTool.set(`${namespace}.${method}`, tool.name);\n methods.push({ namespace, method, tool });\n }\n }\n if (methods.length === 0) {\n // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires a nonempty Tool allowlist.\n throw new Error(\"Code Mode requires at least one allowlisted Tool\");\n }\n\n // Declarations derive from the encoded Schemas and fail construction closed\n // on anything the renderer cannot express.\n const renderedMethods = methods.map((method): RenderedMethod => ({\n ...method,\n declaration: renderMethodDeclaration(method.method, method.tool),\n }));\n\n const declarations = renderDeclarations(renderedMethods);\n\n const methodsByPath = new Map(\n renderedMethods.map((method) => [`${method.namespace}.${method.method}`, method]),\n );\n\n const describe = Effect.fnUntraced(function* (\n selected: ReadonlyArray<string>,\n options?: { readonly maxBytes?: number | undefined },\n ) {\n const paths = yield* Schema.decodeEffect(DescriptionMethods)(selected).pipe(\n Effect.mapError(() =>\n CodeModeDescriptionError.make({\n reason: \"invalid-selection\",\n message:\n \"Select between 1 and 64 unique namespace.method names, each at most 257 characters\",\n }),\n ),\n );\n\n const maxBytes = yield* Schema.decodeEffect(DescriptionByteLimit)(\n options?.maxBytes ?? 16 * 1024,\n ).pipe(\n Effect.mapError(() =>\n CodeModeDescriptionError.make({\n reason: \"invalid-bound\",\n message: \"The documentation byte limit must be an integer between 1 and 262144\",\n }),\n ),\n );\n\n const selectedMethods: Array<RenderedMethod> = [];\n\n for (const path of paths) {\n const method = methodsByPath.get(path);\n\n if (method === undefined) {\n return yield* CodeModeDescriptionError.make({\n reason: \"unknown-method\",\n message: \"The selection contains a method outside this Code Mode allowlist\",\n });\n }\n selectedMethods.push(method);\n }\n\n const documentation = renderDeclarations(selectedMethods);\n\n if (utf8ByteLength(documentation) > maxBytes) {\n return yield* CodeModeDescriptionError.make({\n reason: \"limit-exceeded\",\n message: `The selected declarations exceed the ${maxBytes}-byte documentation limit; select fewer methods or raise the limit`,\n });\n }\n\n return documentation;\n });\n\n const namespaces = [...new Set(methods.map((method) => method.namespace))].map((namespace) =>\n CodeExecutionNamespace.make({\n name: namespace,\n methods: methods\n .filter((method) => method.namespace === namespace)\n .map((method) => method.method),\n }),\n );\n\n const description = [\n options.description,\n \"\",\n \"The `code` argument must be one JavaScript async function expression; the sandbox invokes it exactly once with no arguments. It runs isolated with no ambient network, filesystem, environment, or secrets. Return one JSON value. `console.log` output is captured within a bounded budget and returned alongside the result.\",\n \"Namespace methods return Promises. An expected Tool failure rejects with a JSON envelope carrying a stable `_tag`; catch it to branch. Use Promise.all for independent calls; the host bounds concurrency. Await every call you need. Writes may complete before a failure: inspect call outcomes and never blindly retry a program.\",\n ...(options.includeDeclarations === false\n ? []\n : [\"\", \"Sandbox globals:\", \"```ts\", declarations, \"```\"]),\n ].join(\"\\n\");\n\n const tool = Tool.make(name, {\n description,\n parameters: CodeModeParameters,\n success: CodeModeSuccess,\n failure: CodeModeFailure,\n failureMode: \"return\",\n })\n .annotate(Tool.Readonly, false)\n .annotate(ToolExecutionClassAnnotation, \"uncertain\")\n .annotate(IncludesCatalogDocumentation, options.includeDeclarations !== false)\n .annotate(\n AdditionalToolCatalog,\n Object.freeze(methods.map((method) => Object.freeze({ ...method }))),\n )\n .addDependency(ToolBroker) as CodeModeTool<Name>;\n\n const outerToolkit = Toolkit.make(tool);\n\n /**\n * The nested namespace record collapses into one Toolkit keyed by exact\n * Tool names. The assertion restores the name-keyed record type TypeScript\n * cannot compute from `Map` iteration; construction above guarantees the\n * name uniqueness the type states.\n */\n const selectedToolkit = Toolkit.make(...toolsByName.values()) as unknown as Toolkit.Toolkit<\n CodeModeSelectedRecord<Namespaces>\n >;\n\n const executionRequest = (\n code: string,\n visibleNamespaces: ReadonlyArray<CodeExecutionNamespace>,\n ): CodeExecutionRequest =>\n CodeExecutionRequest.make({\n language: \"javascript\",\n source: code,\n namespaces: visibleNamespaces,\n network: NetworkDisabled.make({}),\n limits,\n });\n\n const routeHostCall = (\n pass: ToolBrokerPass,\n hostCall: CodeHostCall,\n visiblePaths: ReadonlySet<string> | undefined,\n ): Effect.Effect<CodeHostCallResult> =>\n Effect.gen(function* () {\n const path = `${hostCall.namespace}.${hostCall.method}`;\n\n const toolName =\n visiblePaths === undefined || visiblePaths.has(path) ? methodToTool.get(path) : undefined;\n\n if (toolName === undefined) {\n return {\n _tag: \"CodeHostCallFailure\",\n error: {\n _tag: \"UnknownCodeModeMethod\",\n message: \"The requested method is not available in this pass\",\n },\n } as const;\n }\n\n const outcome: ProgrammaticCallOutcome = yield* pass.invoke({\n toolName,\n encodedArguments: hostCall.argument,\n });\n\n switch (outcome._tag) {\n case \"ProgrammaticCallSuccess\": {\n const value = decodeBrokerJson(outcome.encodedResult);\n\n return Option.isSome(value)\n ? ({ _tag: \"CodeHostCallSuccess\", value: value.value } as const)\n : ({ _tag: \"CodeHostCallFailure\", error: brokerProtocolEnvelope } as const);\n }\n case \"ProgrammaticCallFailure\": {\n const value = decodeBrokerJson(outcome.encodedResult);\n\n return {\n _tag: \"CodeHostCallFailure\",\n error: Option.isSome(value) ? value.value : brokerProtocolEnvelope,\n } as const;\n }\n case \"ProgrammaticCallError\": {\n return {\n _tag: \"CodeHostCallFailure\",\n error: { _tag: outcome.errorTag, message: outcome.message },\n } as const;\n }\n }\n });\n\n const build = Effect.gen(function* () {\n const captured =\n yield* Effect.context<\n Tool.HandlerServices<\n CodeModeSelectedRecord<Namespaces>[keyof CodeModeSelectedRecord<Namespaces>]\n >\n >();\n\n const redactionServices = yield* Effect.context<Exclude<RedactionRequirements, Scope.Scope>>();\n const configuredRedactor = options.redactEgress;\n\n const redact: EgressRedactor | undefined =\n configuredRedactor === undefined\n ? undefined\n : (egress) =>\n Effect.scoped(configuredRedactor(egress)).pipe(\n // Merge invocation-local services before opening the redaction Scope.\n // The inner Scope shadows any Scope retained in the construction context.\n Effect.updateContext((current: Context.Context<never>) =>\n Context.merge(current, redactionServices),\n ),\n );\n\n const withHandler = yield* selectedToolkit;\n const executor = yield* CodeExecutor;\n\n const successEgress = (\n execution: CodeExecutionResult,\n ): Effect.Effect<CodeModeSuccess, CodeModeFailure> =>\n Effect.gen(function* () {\n let egress: { readonly result: Schema.Json; readonly logs: ReadonlyArray<string> } = {\n result: execution.value,\n logs: execution.logs,\n };\n\n if (redact !== undefined) {\n egress = yield* redact(egress);\n }\n const resultBytes = encodedJsonByteLength(egress.result);\n\n if (resultBytes === undefined || resultBytes > maxEgressBytes) {\n return yield* CodeModeFailure.make({\n errorTag: \"CodeModeEgressExceeded\",\n message: `The program result of ${resultBytes ?? \"unencodable\"} bytes exceeds the ${maxEgressBytes}-byte model-visible egress budget; return a smaller value`,\n logs: budgetedLogs(egress.logs, Math.max(0, maxEgressBytes - 256)),\n });\n }\n\n return CodeModeSuccess.make({\n result: egress.result,\n logs: budgetedLogs(egress.logs, maxEgressBytes - resultBytes),\n });\n });\n\n /**\n * The failure half of the aggregate egress policy (CAP-016): the configured\n * redaction pass covers failure logs and thrown values exactly like success\n * egress — a program cannot leak by logging and then throwing — and the\n * message itself is bounded by the budget, not only by its own schema cap.\n */\n const failureEgress = (\n error: CodeExecutionError | ToolBrokerUnavailableError | ToolBrokerConfigurationError,\n ): Effect.Effect<CodeModeFailure> =>\n Effect.gen(function* () {\n if (\n error._tag === \"ToolBrokerUnavailableError\" ||\n error._tag === \"ToolBrokerConfigurationError\"\n ) {\n return CodeModeFailure.make({\n errorTag: error._tag,\n message: truncateToUtf8Bytes(boundedMessage(error.message), maxEgressBytes),\n logs: [],\n });\n }\n let logs: ReadonlyArray<string> = \"logs\" in error ? error.logs : [];\n let candidateThrown = error._tag === \"CodeProgramFailedError\" ? error.thrown : undefined;\n\n if (redact !== undefined) {\n const redacted = yield* redact({ result: candidateThrown ?? null, logs });\n\n logs = redacted.logs;\n candidateThrown = candidateThrown === undefined ? undefined : redacted.result;\n }\n\n const message = truncateToUtf8Bytes(\n boundedMessage(executionFailureMessage(error)),\n maxEgressBytes,\n );\n\n const messageBytes = utf8ByteLength(message);\n\n // `thrown` is included only when it fits TOGETHER with the message inside\n // the aggregate budget, and it reduces the log allowance only when it is\n // actually included.\n const candidateBytes =\n candidateThrown === undefined ? undefined : encodedJsonByteLength(candidateThrown);\n\n const includeThrown =\n candidateThrown !== undefined &&\n candidateBytes !== undefined &&\n messageBytes + candidateBytes <= maxEgressBytes;\n\n const remaining = Math.max(\n 0,\n maxEgressBytes - messageBytes - (includeThrown ? (candidateBytes ?? 0) : 0),\n );\n\n return CodeModeFailure.make({\n errorTag: error._tag,\n message,\n logs: budgetedLogs(logs, remaining),\n ...(includeThrown ? { thrown: candidateThrown } : {}),\n });\n });\n\n const invoke = Effect.fnUntraced(function* (parameters: { readonly code: string }) {\n const broker = yield* ToolBroker;\n // Resolve invocation authority before restoring captured construction services. A Layer\n // built under an older Run must not restore that Run's catalogue or hidden method names.\n const catalogue = yield* Effect.serviceOption(CurrentToolCatalog);\n\n const visiblePaths = Option.isNone(catalogue)\n ? undefined\n : new Set(\n catalogue.value.entries.flatMap((entry) =>\n entry.kind === \"code-mode\" &&\n entry.nativeToolName === name &&\n methodsByPath.get(`${entry.namespace}.${entry.method}`)?.tool.name === entry.tool.name\n ? [`${entry.namespace}.${entry.method}`]\n : [],\n ),\n );\n\n const visibleNamespaces =\n visiblePaths === undefined\n ? namespaces\n : namespaces.flatMap((namespace) => {\n const allowed = namespace.methods.filter((method) =>\n visiblePaths.has(`${namespace.name}.${method}`),\n );\n\n return allowed.length === 0\n ? []\n : [CodeExecutionNamespace.make({ name: namespace.name, methods: allowed })];\n });\n\n let calls: ReadonlyArray<ProgrammaticCallRecord> = [];\n\n const execution = Effect.gen(function* () {\n const pass = yield* broker.openPass(withHandler, {\n maxResultBytes: limits.maxHostCallResultBytes,\n concurrency: limits.maxHostCallConcurrency ?? 4,\n });\n\n const host = CodeExecutionHost.of({\n call: (hostCall) => routeHostCall(pass, hostCall, visiblePaths),\n });\n\n return yield* executor.execute(executionRequest(parameters.code, visibleNamespaces)).pipe(\n Effect.provideService(CodeExecutionHost, host),\n Effect.scoped,\n Effect.onExit((exit) =>\n Effect.gen(function* () {\n calls = yield* pass.snapshot;\n if (options.onPassExit !== undefined) {\n yield* Effect.scoped(\n options.onPassExit({\n status: Exit.isSuccess(exit)\n ? \"completed\"\n : Cause.hasInterrupts(exit.cause)\n ? \"interrupted\"\n : Cause.hasDies(exit.cause)\n ? \"defect\"\n : \"failed\",\n calls,\n }),\n ).pipe(Effect.provideContext(redactionServices));\n }\n }),\n ),\n );\n }).pipe(\n Effect.scoped,\n // Keep invocation authority innermost while restoring the declared handler services.\n Effect.provideService(ToolBroker, broker),\n Effect.updateContext((current: Context.Context<never>) => Context.merge(current, captured)),\n );\n\n return yield* execution.pipe(\n Effect.catch((error) => failureEgress(error).pipe(Effect.flatMap(Effect.fail))),\n Effect.flatMap(successEgress),\n Effect.mapError((failure) => {\n if (calls.length === 0) return failure;\n\n const complete = CodeModeFailure.make({\n errorTag: failure.errorTag,\n message: failure.message,\n logs: failure.logs,\n ...(failure.thrown === undefined ? {} : { thrown: failure.thrown }),\n calls,\n omittedCalls: 0,\n });\n\n if ((encodedJsonByteLength(complete) ?? Infinity) <= maxEgressBytes) return complete;\n\n // Evidence takes priority over logs and thrown values. Never silently omit calls.\n const base = {\n errorTag: failure.errorTag,\n message: truncateToUtf8Bytes(failure.message, Math.min(256, maxEgressBytes / 4)),\n logs: [],\n };\n\n const kept: Array<ProgrammaticCallRecord> = [];\n\n for (const call of calls) {\n const candidate = CodeModeFailure.make({\n ...base,\n calls: [...kept, call],\n omittedCalls: calls.length - kept.length - 1,\n });\n\n if ((encodedJsonByteLength(candidate) ?? Infinity) > maxEgressBytes) break;\n kept.push(call);\n }\n\n return CodeModeFailure.make({\n ...base,\n calls: kept,\n omittedCalls: calls.length - kept.length,\n });\n }),\n );\n });\n\n return { [name]: invoke } as unknown as Toolkit.HandlersFrom<CodeModeTools<Name>>;\n });\n\n /**\n * TypeScript cannot unify the two spellings of the singleton Tool record\n * (`CodeModeTools<Name>` versus the toolkit's name-remapped form) over a\n * generic `Name`, nor reduce the deferred `Exclude` when `toLayer`\n * subtracts what `build` consumed; the assertions pin the layer to its\n * documented requirement surface and never bypass validation.\n */\n const handlers = outerToolkit.toLayer(\n build as unknown as Effect.Effect<\n Toolkit.HandlersFrom<Toolkit.ToolsByName<readonly [CodeModeTool<Name>]>>,\n never,\n | CodeExecutor\n | Tool.HandlersFor<CodeModeSelectedRecord<Namespaces>>\n | Tool.HandlerServices<\n CodeModeSelectedRecord<Namespaces>[keyof CodeModeSelectedRecord<Namespaces>]\n >\n | Exclude<RedactionRequirements, Scope.Scope>\n >,\n ) as unknown as Layer.Layer<\n Tool.HandlersFor<CodeModeTools<Name>>,\n never,\n CodeModeLayerRequirements<Namespaces, RedactionRequirements>\n >;\n\n return Object.freeze({\n name,\n description,\n declarations,\n describe,\n namespaces,\n limits,\n maxEgressBytes,\n tool,\n handlers,\n });\n};\n\n/**\n * Fail-closed JSON boundary for broker outcomes: hostile values can throw\n * from trap getters during decode, and a value outside the JSON surface must\n * become a typed failure envelope — never a fabricated success.\n */\nconst decodeBrokerJson = (value: unknown): Option.Option<Schema.Json> => {\n try {\n return Schema.decodeUnknownOption(Schema.Json)(value);\n } catch {\n return Option.none();\n }\n};\n\nconst brokerProtocolEnvelope: Schema.Json = {\n _tag: \"CodeModeProtocolError\",\n message: \"The broker returned a value outside the JSON surface\",\n};\n\n// The engine annotation is imported under a local alias to keep the builder\n// readable next to Effect AI's own `Tool.Readonly` annotation.\nimport { ToolExecutionClass as ToolExecutionClassAnnotation } from \"../engine/DurableStep.ts\";\n\n/** Code Mode builder namespace (capability spec §9.1). */\nexport { make };\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as CommandDrainPolicy } from "../RunOptions-
|
|
1
|
+
import { o as CommandDrainPolicy } from "../RunOptions-Be77lKVZ.mjs";
|
|
2
2
|
import { Effect, Schema } from "effect";
|
|
3
3
|
declare namespace Commands_d_exports {
|
|
4
4
|
export { FollowUpCommand, RunCommand, RunCommandQueue, RunCommandQueueClosed, RunCommandQueueConfig, SteeringCommand, makeRunCommandQueue };
|
|
@@ -71,7 +71,7 @@ var McpToolCallFailed = class extends Schema.TaggedError()("McpToolCallFailed",
|
|
|
71
71
|
}) {};
|
|
72
72
|
const isNotificationTag = (tag) => tag.startsWith("notifications/");
|
|
73
73
|
const isRpcClientError = Schema.is(RpcClientError.RpcClientError);
|
|
74
|
-
const protocolDefect = (message, cause) =>
|
|
74
|
+
const protocolDefect = (message, cause) => RpcClientError.RpcClientError.make({ reason: RpcClientError.RpcClientDefect.make({
|
|
75
75
|
message,
|
|
76
76
|
cause
|
|
77
77
|
}) });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpClient.mjs","names":[],"sources":["../../src/capabilities/McpClient.ts"],"sourcesContent":["import {\n Cause,\n Context,\n Effect,\n Layer,\n Option,\n Predicate,\n Queue,\n Schema,\n Scope,\n Stream,\n} from \"effect\";\nimport { Tool, Toolkit } from \"effect/ai\";\nimport * as McpProtocol from \"effect/ai/McpProtocol\";\nimport * as McpSchema from \"effect/ai/McpSchema\";\nimport { Headers, HttpClient, HttpClientRequest, type HttpClientResponse } from \"effect/http\";\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\";\nimport { RpcClient, RpcClientError, type RpcMessage, RpcSerialization } from \"effect/rpc\";\n\nimport { utf8ByteLength } from \"../core/internal/utf8.ts\";\nimport { ToolExecutionClass, type ToolExecutionClassValue } from \"../engine/DurableStep.ts\";\nimport {\n McpConnectionError,\n McpConnector,\n type McpConnectedServer,\n type McpConnectionRequest,\n McpServerIdentity,\n McpToolOutputSchema,\n} from \"./Mcp.ts\";\n\n// ---------------------------------------------------------------------------\n// MCP client: native Effect AI MCP schemas and protocol adapters, the Effect\n// RPC client, and Effect HTTP / child-process services connect an Agent to a\n// remote MCP server. Discovered tools become dynamic Effect AI Tools whose\n// handlers forward `tools/call`; `connectMcp` still applies every discovery\n// bound before the Toolkit reaches Agent context.\n// ---------------------------------------------------------------------------\n\n/** Largest single JSON-RPC message a transport accepts from a server by default. */\nconst DEFAULT_MAX_MESSAGE_BYTES = 4 * 1024 * 1024;\n/** Bounded `tools/list` pagination: a server cannot keep a client walking cursors forever. */\nconst MAX_TOOL_LIST_PAGES = 64;\nconst MCP_SESSION_ID_HEADER = \"mcp-session-id\";\nconst MCP_PROTOCOL_VERSION_HEADER = \"mcp-protocol-version\";\nconst JSON_RPC_METHOD_NOT_FOUND = -32601;\n\n/**\n * The protocol revisions this client negotiates, as implemented by Effect AI's\n * native MCP protocol adapters. The newest revision is offered first; a server\n * answering with any other listed revision is accepted, anything else fails.\n */\nexport const McpClientProtocolVersion = Schema.Literals([\n McpProtocol.v2025_11_25.protocolVersion,\n McpProtocol.v2025_06_18.protocolVersion,\n McpProtocol.v2025_03_26.protocolVersion,\n McpProtocol.v2024_11_05.protocolVersion,\n]);\n\nexport type McpClientProtocolVersion = typeof McpClientProtocolVersion.Type;\n\nconst OFFERED_PROTOCOL_VERSION: McpClientProtocolVersion = McpProtocol.v2025_11_25.protocolVersion;\n\n/** Identity this client presents to servers during `initialize`. */\nexport const defaultMcpClientInfo = McpSchema.Implementation.make({\n name: \"effect-agent\",\n version: \"1.0.0\",\n});\n\n/**\n * The model-visible result of a remote MCP tool call: the server's content\n * blocks and, when the tool declares an `outputSchema`, its structured result.\n * A result with `isError` never becomes this value; it fails the Tool Call.\n */\nexport class McpToolResult extends Schema.Class<McpToolResult>(\n \"@effect-agent/capabilities/McpToolResult\",\n)({\n content: Schema.Array(McpSchema.ContentBlock),\n structuredContent: Schema.optionalKey(Schema.Json),\n}) {}\n\n/**\n * Typed failure of one remote MCP tool call. `tool-error` carries the server's\n * error content; the other reasons describe why no trustworthy result exists.\n * None of them claims the remote effect did not happen.\n */\nexport class McpToolCallFailed extends Schema.TaggedError<McpToolCallFailed>()(\n \"McpToolCallFailed\",\n {\n serverId: Schema.NonEmptyString,\n tool: Schema.NonEmptyString,\n reason: Schema.Literals([\"tool-error\", \"invalid-arguments\", \"protocol-error\", \"transport\"]),\n message: Schema.String,\n content: Schema.optionalKey(Schema.Array(McpSchema.ContentBlock)),\n },\n) {}\n\n/**\n * One reachable MCP server. `protocol` acquires a JSON-RPC transport in the\n * caller's Scope; `R` names the platform services that transport needs so the\n * connector Layer keeps them in its requirements.\n */\nexport interface McpServerTransport<R = never> {\n readonly serverId: string;\n /**\n * Whether the server's `readOnlyHint`, `idempotentHint`, and\n * `destructiveHint` may set the framework execution class of its tools.\n * Hints are server-declared and untrusted, so the default leaves every\n * remote tool `uncertain`.\n */\n readonly trustToolAnnotations: boolean;\n readonly protocol: Effect.Effect<\n RpcClient.Protocol[\"Service\"],\n McpConnectionError,\n Scope.Scope | R\n >;\n}\n\n/** Streamable HTTP server address. Header values may carry credentials the application owns. */\nexport interface McpHttpTransportOptions {\n readonly serverId: string;\n readonly url: string;\n readonly headers?: Headers.Input | undefined;\n /** Largest accepted response message. Defaults to 4 MiB. */\n readonly maxMessageBytes?: number | undefined;\n readonly trustToolAnnotations?: boolean | undefined;\n}\n\n/** A local MCP server process speaking newline-delimited JSON-RPC on stdio. */\nexport interface McpStdioTransportOptions {\n readonly serverId: string;\n readonly command: string;\n readonly args?: ReadonlyArray<string> | undefined;\n readonly cwd?: string | undefined;\n readonly env?: Readonly<Record<string, string>> | undefined;\n /** Largest accepted stdout frame. Defaults to 4 MiB. */\n readonly maxMessageBytes?: number | undefined;\n readonly trustToolAnnotations?: boolean | undefined;\n}\n\nconst isNotificationTag = (tag: string): boolean => tag.startsWith(\"notifications/\");\nconst isRpcClientError = Schema.is(RpcClientError.RpcClientError);\n\nconst protocolDefect = (message: string, cause?: unknown): RpcClientError.RpcClientError =>\n new RpcClientError.RpcClientError({\n reason: new RpcClientError.RpcClientDefect({ message, cause }),\n });\n\nconst InitializeProtocolVersion = Schema.Struct({ protocolVersion: Schema.String });\nconst decodeInitializeProtocolVersion = Schema.decodeUnknownOption(InitializeProtocolVersion);\n\nconst ServerRequest = Schema.Struct({ _tag: Schema.Literal(\"Request\"), tag: Schema.String });\nconst isServerRequest = Schema.is(ServerRequest);\n\nconst isJsonRpcRequest = (message: unknown): message is RpcMessage.RequestEncoded =>\n isServerRequest(message);\n\n/** Effect RPC's tracing extensions are not part of MCP's strict JSON-RPC request shape. */\nconst mcpWireMessage = (message: unknown): unknown => {\n if (!Predicate.hasProperty(message, \"_tag\") || message._tag !== \"Request\") return message;\n const payload = Predicate.hasProperty(message, \"payload\") ? message.payload : undefined;\n\n return {\n ...message,\n payload: payload === null ? undefined : payload,\n traceId: undefined,\n spanId: undefined,\n sampled: undefined,\n headers: [],\n };\n};\n\n/** JSON-RPC error a client returns for a server-initiated request it does not serve. */\nconst declineServerRequest = (\n request: RpcMessage.RequestEncoded,\n): RpcMessage.ResponseExitEncoded => ({\n _tag: \"Exit\",\n requestId: request.id,\n exit: {\n _tag: \"Failure\",\n cause: [\n {\n _tag: \"Fail\",\n error: {\n code: JSON_RPC_METHOD_NOT_FOUND,\n message: `Client does not serve ${request.tag}`,\n },\n },\n ],\n },\n});\n\n/**\n * Routes one decoded JSON-RPC message. Responses reach the RPC client; server\n * notifications are logged; server requests (sampling, elicitation, roots)\n * are declined fail-closed through `respond` because this client serves none.\n */\nconst routeMessage = (\n message: unknown,\n options: {\n readonly clientId: number;\n readonly writeResponse: (\n clientId: number,\n response: RpcMessage.FromServerEncoded,\n ) => Effect.Effect<void>;\n readonly respond: (response: RpcMessage.ResponseExitEncoded) => Effect.Effect<void>;\n readonly onExit: (exit: RpcMessage.ResponseExitEncoded) => void;\n },\n): Effect.Effect<void> => {\n if (isJsonRpcRequest(message)) {\n if (message.isNotification === true) {\n return Effect.logDebug(\"Ignoring MCP server notification\").pipe(\n Effect.annotateLogs({ method: message.tag }),\n );\n }\n\n return options.respond(declineServerRequest(message));\n }\n if (Predicate.hasProperty(message, \"_tag\") && message._tag === \"Exit\") {\n options.onExit(message as RpcMessage.ResponseExitEncoded);\n }\n\n return options.writeResponse(options.clientId, message as RpcMessage.FromServerEncoded);\n};\n\n/** Reads a response body as text while refusing bodies above `maxBytes`. */\nconst readBoundedText = Effect.fnUntraced(function* (\n response: HttpClientResponse.HttpClientResponse,\n maxBytes: number,\n) {\n const declared = Number(response.headers[\"content-length\"]);\n\n if (Number.isFinite(declared) && declared > maxBytes) {\n return yield* protocolDefect(\n `MCP response of ${declared} bytes exceeds the ${maxBytes} byte message bound`,\n );\n }\n const chunks: Array<string> = [];\n let received = 0;\n\n yield* response.stream.pipe(\n Stream.decodeText(),\n Stream.runForEach((chunk) => {\n received += utf8ByteLength(chunk);\n if (received > maxBytes) {\n return Effect.fail(\n protocolDefect(`MCP response exceeds the ${maxBytes} byte message bound`),\n );\n }\n chunks.push(chunk);\n\n return Effect.void;\n }),\n Effect.mapError((error) =>\n isRpcClientError(error)\n ? error\n : protocolDefect(\"Could not read the MCP HTTP response\", error),\n ),\n );\n\n return chunks.join(\"\");\n});\n\n/**\n * Delivers the `data` of each `text/event-stream` event as it arrives. Only\n * `data` fields carry JSON-RPC messages; `event`, `id`, `retry`, and comment\n * lines are ignored because this client never resumes a stream, so a server\n * retry directive neither ends the stream nor fails the request. At most\n * `maxBytes` of an unterminated event stays buffered.\n */\nconst consumeEventStream = Effect.fnUntraced(function* (\n response: HttpClientResponse.HttpClientResponse,\n maxBytes: number,\n deliver: (data: string) => Effect.Effect<void>,\n) {\n let buffer = \"\";\n let pendingBytes = 0;\n\n const dispatchEvent = (block: string): Effect.Effect<void> => {\n const data = block\n .split(/\\r?\\n/)\n .filter((line) => line.startsWith(\"data:\"))\n .map((line) => line.slice(\"data:\".length).replace(/^ /, \"\"))\n .join(\"\\n\");\n\n return data.length === 0 ? Effect.void : deliver(data);\n };\n\n const drain = (final: boolean): Effect.Effect<void> =>\n Effect.suspend(() => {\n const blocks: Array<string> = [];\n\n while (true) {\n const match = /\\r?\\n\\r?\\n/.exec(buffer);\n\n if (match === null) break;\n blocks.push(buffer.slice(0, match.index));\n buffer = buffer.slice(match.index + match[0].length);\n }\n if (final && buffer.length > 0) {\n blocks.push(buffer);\n buffer = \"\";\n }\n pendingBytes = utf8ByteLength(buffer);\n\n return Effect.forEach(blocks, dispatchEvent, { discard: true });\n });\n\n yield* response.stream.pipe(\n Stream.decodeText(),\n Stream.runForEach((chunk) => {\n buffer += chunk;\n pendingBytes += utf8ByteLength(chunk);\n if (pendingBytes > maxBytes) {\n return Effect.fail(protocolDefect(`MCP event stream buffered more than ${maxBytes} bytes`));\n }\n\n return drain(false);\n }),\n Effect.mapError((error) =>\n isRpcClientError(error)\n ? error\n : protocolDefect(\"Could not read the MCP event stream\", error),\n ),\n );\n yield* drain(true);\n});\n\nconst makeHttpProtocol = Effect.fnUntraced(function* (options: McpHttpTransportOptions) {\n const client = yield* HttpClient.HttpClient;\n const serialization = RpcSerialization.jsonRpc();\n const parser = serialization.makeUnsafe();\n const maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;\n const configuredHeaders = Headers.fromInput(options.headers);\n const url = options.url;\n let sessionId: string | undefined;\n let protocolVersion: string | undefined;\n let initializeRequestId: string | number | undefined;\n /** Request ids whose JSON-RPC response has been delivered. */\n const answered = new Set<string | number>();\n\n const transportHeaders = (): Headers.Headers =>\n Headers.merge(\n configuredHeaders,\n Headers.fromInput({\n accept: \"application/json, text/event-stream\",\n ...(sessionId === undefined ? {} : { [MCP_SESSION_ID_HEADER]: sessionId }),\n ...(protocolVersion === undefined\n ? {}\n : { [MCP_PROTOCOL_VERSION_HEADER]: protocolVersion }),\n }),\n );\n\n const post = (body: string) =>\n client\n .execute(\n HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeaders(transportHeaders()),\n HttpClientRequest.bodyText(body, \"application/json\"),\n ),\n )\n .pipe(\n Effect.mapError((error) =>\n protocolDefect(`MCP HTTP request to ${options.serverId} failed`, error),\n ),\n );\n\n // Ending the session is a courtesy to the server; the Scope owns the client.\n yield* Effect.addFinalizer(() =>\n sessionId === undefined\n ? Effect.void\n : client\n .execute(\n HttpClientRequest.delete(url).pipe(HttpClientRequest.setHeaders(transportHeaders())),\n )\n .pipe(Effect.ignore),\n );\n\n return yield* RpcClient.Protocol.make((writeResponse) =>\n Effect.sync(() => {\n const encode = (message: unknown): Effect.Effect<string, RpcClientError.RpcClientError> =>\n Effect.suspend(() => {\n const encoded = parser.encode(mcpWireMessage(message));\n\n return typeof encoded === \"string\"\n ? Effect.succeed(encoded)\n : Effect.fail(protocolDefect(\"Could not encode an MCP JSON-RPC message\"));\n });\n\n const deliver = (clientId: number, data: string): Effect.Effect<void> =>\n Effect.suspend(() => {\n let messages: ReadonlyArray<unknown>;\n\n try {\n messages = parser.decode(data);\n } catch (cause) {\n return writeResponse(clientId, {\n _tag: \"ClientProtocolError\",\n error: protocolDefect(\"Could not decode an MCP JSON-RPC message\", cause),\n });\n }\n\n return Effect.forEach(\n messages,\n (message) =>\n routeMessage(message, {\n clientId,\n writeResponse,\n respond: (response) => encode(response).pipe(Effect.flatMap(post), Effect.ignore),\n onExit: (exit) => {\n answered.add(exit.requestId);\n if (exit.requestId !== initializeRequestId || exit.exit._tag !== \"Success\") {\n return;\n }\n const decoded = decodeInitializeProtocolVersion(exit.exit.value);\n\n if (Option.isSome(decoded)) protocolVersion = decoded.value.protocolVersion;\n },\n }),\n { discard: true },\n );\n });\n\n /**\n * Posts one message and delivers whatever the server answers. A request\n * whose HTTP exchange completes without a JSON-RPC response for its id\n * (for example a `202`, an `id: null` error, or a stream that ends\n * early) fails that request instead of leaving its caller waiting.\n */\n const dispatch = Effect.fnUntraced(function* (\n clientId: number,\n message: unknown,\n requestId?: string | number,\n ) {\n const response = yield* post(yield* encode(message));\n const responseSession = response.headers[MCP_SESSION_ID_HEADER];\n\n if (responseSession !== undefined) sessionId = responseSession;\n if (response.status < 200 || response.status >= 300) {\n return yield* protocolDefect(\n `MCP server ${options.serverId} answered HTTP ${response.status}`,\n );\n }\n const contentType = response.headers[\"content-type\"] ?? \"\";\n\n if (response.status !== 202 && response.status !== 204) {\n if (contentType.startsWith(\"text/event-stream\")) {\n yield* consumeEventStream(response, maxMessageBytes, (data) => deliver(clientId, data));\n } else {\n const text = yield* readBoundedText(response, maxMessageBytes);\n\n if (text.length > 0) yield* deliver(clientId, text);\n }\n }\n if (requestId !== undefined && !answered.has(requestId)) {\n yield* writeResponse(clientId, {\n _tag: \"Exit\",\n requestId,\n exit: {\n _tag: \"Failure\",\n cause: [\n {\n _tag: \"Die\",\n defect: `MCP server ${options.serverId} closed the HTTP exchange without answering request ${String(requestId)}`,\n },\n ],\n },\n });\n }\n answered.delete(requestId ?? \"\");\n });\n\n const send: RpcClient.Protocol[\"Service\"][\"send\"] = (clientId, request) => {\n switch (request._tag) {\n case \"Request\": {\n if (isNotificationTag(request.tag)) {\n return dispatch(clientId, { ...request, isNotification: true });\n }\n if (request.tag === \"initialize\") initializeRequestId = request.id;\n\n return dispatch(clientId, request, request.id);\n }\n case \"Interrupt\": {\n return dispatch(clientId, {\n _tag: \"Request\",\n id: request.requestId,\n tag: \"notifications/cancelled\",\n payload: { requestId: request.requestId },\n headers: [],\n isNotification: true,\n } satisfies RpcMessage.RequestEncoded);\n }\n case \"Ack\":\n case \"Ping\":\n case \"Eof\": {\n return Effect.void;\n }\n }\n };\n\n return {\n send,\n supportsAck: false,\n supportsTransferables: false,\n codecFor: serialization.codecFor,\n };\n }),\n );\n});\n\nconst makeStdioProtocol = Effect.fnUntraced(function* (options: McpStdioTransportOptions) {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n const maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;\n const serialization = RpcSerialization.ndJsonRpc({ maxBufferSize: maxMessageBytes });\n const parser = serialization.makeUnsafe();\n\n const handle = yield* spawner\n .spawn(\n ChildProcess.make(options.command, [...(options.args ?? [])], {\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n ...(options.env === undefined ? {} : { env: options.env, extendEnv: true }),\n }),\n )\n .pipe(\n Effect.mapError((cause) =>\n McpConnectionError.make({\n serverId: options.serverId,\n message: `Could not start the MCP server process for ${options.serverId}`,\n cause,\n }),\n ),\n );\n\n const outbound = yield* Queue.unbounded<string>();\n // Once the process is gone every later send fails immediately instead of\n // queueing behind a writer that no longer exists.\n let closed: RpcClientError.RpcClientError | undefined;\n\n const closedWith = (message: string, cause?: unknown): RpcClientError.RpcClientError =>\n (closed ??= protocolDefect(message, cause));\n\n yield* Stream.fromQueue(outbound).pipe(\n Stream.encodeText,\n Stream.run(handle.stdin),\n Effect.matchCauseEffect({\n onSuccess: () =>\n Effect.sync(() => closedWith(`MCP server process ${options.serverId} closed stdin`)),\n onFailure: (cause) =>\n Cause.hasInterruptsOnly(cause)\n ? Effect.void\n : Effect.sync(() =>\n closedWith(\n `Writing to MCP server process ${options.serverId} failed`,\n Cause.squash(cause),\n ),\n ),\n }),\n Effect.forkScoped,\n );\n yield* handle.stderr.pipe(\n Stream.decodeText(),\n Stream.splitLines,\n Stream.runForEach((line) => Effect.logDebug(line)),\n Effect.ignore,\n Effect.annotateLogs({ mcpServerId: options.serverId, stream: \"stderr\" }),\n Effect.forkScoped,\n );\n\n return yield* RpcClient.Protocol.make(\n Effect.fnUntraced(function* (writeResponse, clientIds) {\n const broadcast = (error: RpcClientError.RpcClientError) =>\n Effect.forEach(\n clientIds,\n (clientId) => writeResponse(clientId, { _tag: \"ClientProtocolError\", error }),\n { discard: true },\n );\n\n const deliver = (chunk: Uint8Array): Effect.Effect<void> =>\n Effect.suspend(() => {\n let messages: ReadonlyArray<unknown>;\n\n try {\n messages = parser.decode(chunk);\n } catch (cause) {\n return broadcast(protocolDefect(\"Could not decode an MCP stdio frame\", cause));\n }\n\n return Effect.forEach(\n messages,\n (message) =>\n Effect.forEach(\n clientIds,\n (clientId) =>\n routeMessage(message, {\n clientId,\n writeResponse,\n respond: (response) => enqueue(response).pipe(Effect.ignore),\n onExit: () => {},\n }),\n { discard: true },\n ),\n { discard: true },\n );\n });\n\n const enqueue = (message: unknown): Effect.Effect<void, RpcClientError.RpcClientError> =>\n Effect.suspend(() => {\n if (closed !== undefined) return Effect.fail(closed);\n const encoded = parser.encode(mcpWireMessage(message));\n\n if (typeof encoded !== \"string\") {\n return Effect.fail(protocolDefect(\"Could not encode an MCP JSON-RPC message\"));\n }\n\n return Queue.offer(outbound, encoded).pipe(Effect.asVoid);\n });\n\n yield* handle.stdout.pipe(\n Stream.runForEach(deliver),\n Effect.matchCauseEffect({\n onSuccess: () =>\n broadcast(closedWith(`MCP server process ${options.serverId} closed stdout`)),\n onFailure: (cause) =>\n Cause.hasInterruptsOnly(cause)\n ? Effect.void\n : broadcast(\n closedWith(\n `Reading MCP server process ${options.serverId} failed`,\n Cause.squash(cause),\n ),\n ),\n }),\n Effect.forkScoped,\n );\n\n const send: RpcClient.Protocol[\"Service\"][\"send\"] = (_clientId, request) => {\n switch (request._tag) {\n case \"Request\": {\n return enqueue(\n isNotificationTag(request.tag) ? { ...request, isNotification: true } : request,\n );\n }\n case \"Interrupt\": {\n return enqueue({\n _tag: \"Request\",\n id: request.requestId,\n tag: \"notifications/cancelled\",\n payload: { requestId: request.requestId },\n headers: [],\n isNotification: true,\n } satisfies RpcMessage.RequestEncoded);\n }\n case \"Ack\":\n case \"Ping\":\n case \"Eof\": {\n return Effect.void;\n }\n }\n };\n\n return {\n send,\n supportsAck: false,\n supportsTransferables: false,\n codecFor: serialization.codecFor,\n };\n }),\n );\n});\n\n/** Streamable HTTP transport for one remote MCP server; requires `HttpClient`. */\nexport const McpHttpTransport = {\n make: (options: McpHttpTransportOptions): McpServerTransport<HttpClient.HttpClient> => ({\n serverId: options.serverId,\n trustToolAnnotations: options.trustToolAnnotations ?? false,\n protocol: makeHttpProtocol(options),\n }),\n} as const;\n\n/** stdio transport for one local MCP server process; requires `ChildProcessSpawner`. */\nexport const McpStdioTransport = {\n make: (\n options: McpStdioTransportOptions,\n ): McpServerTransport<ChildProcessSpawner.ChildProcessSpawner> => ({\n serverId: options.serverId,\n trustToolAnnotations: options.trustToolAnnotations ?? false,\n protocol: makeStdioProtocol(options),\n }),\n} as const;\n\n/**\n * Effect AI Tool derived from one discovered MCP tool. Its parameters are the\n * server's JSON Schema, so handlers receive `unknown` and the server validates\n * arguments; `Tool.getJsonSchema` still advertises the discovered schema. A\n * failed call returns `McpToolCallFailed` to the model as a failed tool result.\n */\nexport type McpTool = Tool.Tool<\n string,\n {\n readonly parameters: typeof Schema.Unknown;\n readonly success: typeof McpToolResult;\n readonly failure: typeof McpToolCallFailed;\n readonly failureMode: \"return\";\n }\n>;\n\n/** Toolkit of discovered MCP tools; every member forwards `tools/call` to its server. */\nexport type McpToolkit = Toolkit.Toolkit<Record<string, McpTool>>;\n\nconst executionClassFor = (\n annotations: McpSchema.ToolAnnotations | undefined,\n): ToolExecutionClassValue => {\n if (annotations === undefined) return \"uncertain\";\n if (annotations.readOnlyHint) return \"readonly\";\n if (annotations.idempotentHint && !annotations.destructiveHint) return \"idempotent\";\n\n return \"uncertain\";\n};\n\nconst makeMcpTool = (tool: McpSchema.Tool, trustToolAnnotations: boolean): McpTool => {\n // MCP servers may advertise valid JSON Schemas outside a model provider's strict subset.\n let dynamic: McpTool = Tool.dynamic(tool.name, {\n ...(tool.description === undefined ? {} : { description: tool.description }),\n parameters: tool.inputSchema,\n success: McpToolResult,\n failure: McpToolCallFailed,\n // MCP reports tool errors inside results so the model can self-correct;\n // `return` hands the typed failure to the model the same way.\n failureMode: \"return\",\n }).annotate(Tool.Strict, false);\n\n const title = tool.title ?? tool.annotations?.title;\n\n if (title !== undefined) dynamic = dynamic.annotate(Tool.Title, title);\n dynamic = dynamic.annotate(McpToolOutputSchema, Option.fromNullishOr(tool.outputSchema));\n if (tool.annotations !== undefined) {\n dynamic = dynamic\n .annotate(Tool.Readonly, tool.annotations.readOnlyHint)\n .annotate(Tool.Destructive, tool.annotations.destructiveHint)\n .annotate(Tool.Idempotent, tool.annotations.idempotentHint)\n .annotate(Tool.OpenWorld, tool.annotations.openWorldHint);\n }\n if (trustToolAnnotations) {\n dynamic = dynamic.annotate(ToolExecutionClass, executionClassFor(tool.annotations));\n }\n\n return dynamic;\n};\n\nconst ToolArguments = Schema.Record(Schema.String, Schema.Json);\nconst decodeToolArguments = Schema.decodeUnknownEffect(ToolArguments);\n\nconst errorText = (content: ReadonlyArray<typeof McpSchema.ContentBlock.Type>): string =>\n content\n .flatMap((block) => (block.type === \"text\" ? [block.text] : []))\n .join(\"\\n\")\n .slice(0, 4 * 1024);\n\nconst describeDefect = (defect: unknown): string =>\n (Predicate.hasProperty(defect, \"message\") && Predicate.isString(defect.message)\n ? defect.message\n : String(defect)\n ).slice(0, 4 * 1024);\n\nconst connectionError = (serverId: string, message: string) => (cause: unknown) =>\n McpConnectionError.make({ serverId, message, cause });\n\n/**\n * Keeps every non-interrupt outcome of one protocol step typed: expected\n * failures and defects (such as an undecodable server reply) both become the\n * connection error, so a misbehaving server cannot crash the connector.\n */\nconst failClosed =\n (serverId: string, message: string) =>\n <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, McpConnectionError, R> =>\n self.pipe(\n Effect.mapError(connectionError(serverId, message)),\n Effect.catchDefect((defect) => Effect.fail(connectionError(serverId, message)(defect))),\n );\n\nconst connectServer = Effect.fnUntraced(function* <R>(\n transport: McpServerTransport<R>,\n request: McpConnectionRequest,\n clientInfo: McpSchema.Implementation,\n): Effect.fn.Return<McpConnectedServer, McpConnectionError, Scope.Scope | R> {\n const serverId = transport.serverId;\n const protocol = yield* transport.protocol;\n\n const client = yield* RpcClient.make(McpSchema.ClientRpcs, {\n spanPrefix: \"McpClient\",\n spanAttributes: { \"mcp.server_id\": serverId },\n }).pipe(Effect.provideService(RpcClient.Protocol, protocol));\n\n const initialized = yield* client\n .initialize({\n protocolVersion: OFFERED_PROTOCOL_VERSION,\n capabilities: McpSchema.ClientCapabilities.make({}),\n clientInfo,\n })\n .pipe(failClosed(serverId, `MCP initialize with ${serverId} failed`));\n\n const negotiated = yield* Schema.decodeUnknownEffect(McpClientProtocolVersion)(\n initialized.protocolVersion,\n ).pipe(\n Effect.mapError(\n connectionError(\n serverId,\n `MCP server ${serverId} negotiated unsupported protocol version '${initialized.protocolVersion}'`,\n ),\n ),\n );\n\n yield* Effect.annotateCurrentSpan({ \"mcp.protocol_version\": negotiated });\n yield* client[\"notifications/initialized\"](undefined, { discard: true }).pipe(\n failClosed(serverId, `Could not acknowledge MCP initialization with ${serverId}`),\n );\n\n const tools: Array<McpSchema.Tool> = [];\n let cursor: string | undefined;\n let pages = 0;\n\n do {\n const page = yield* client[\"tools/list\"](\n cursor === undefined ? undefined : McpSchema.PaginatedRequestMeta.make({ cursor }),\n ).pipe(failClosed(serverId, `MCP tools/list with ${serverId} failed`));\n\n tools.push(...page.tools);\n cursor = page.nextCursor;\n pages += 1;\n // `validateMcpDiscovery` rejects the count; stop paying for more pages.\n if (tools.length > request.maxToolCount) break;\n if (cursor !== undefined && pages >= MAX_TOOL_LIST_PAGES) {\n return yield* McpConnectionError.make({\n serverId,\n message: `MCP server ${serverId} paginated tools/list beyond ${MAX_TOOL_LIST_PAGES} pages`,\n });\n }\n } while (cursor !== undefined);\n\n const callTool = Effect.fnUntraced(function* (name: string, params: unknown) {\n const args = yield* decodeToolArguments(params ?? {}).pipe(\n Effect.mapError((cause) =>\n McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: \"invalid-arguments\",\n message: `MCP tool arguments must be a JSON object: ${cause.message}`,\n }),\n ),\n );\n\n const result = yield* client[\"tools/call\"]({ name, arguments: args }).pipe(\n Effect.mapError((error) =>\n McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: isRpcClientError(error) ? \"transport\" : \"protocol-error\",\n message: error.message,\n }),\n ),\n // A JSON-RPC error the MCP error union cannot decode (or any other\n // malformed reply) surfaces as a defect from the RPC client. It is still\n // the server's answer, so it reaches the model as a failed tool result\n // rather than aborting the batch.\n Effect.catchDefect((defect) =>\n Effect.fail(\n McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: \"protocol-error\",\n message: describeDefect(defect),\n }),\n ),\n ),\n );\n\n if (result.isError === true) {\n return yield* McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: \"tool-error\",\n message: errorText(result.content),\n content: result.content,\n });\n }\n\n return McpToolResult.make({\n content: result.content,\n ...(result.structuredContent === undefined\n ? {}\n : { structuredContent: result.structuredContent }),\n });\n });\n\n const toolkit: McpToolkit = yield* Effect.try({\n try: () =>\n Toolkit.make(...tools.map((tool) => makeMcpTool(tool, transport.trustToolAnnotations))),\n catch: connectionError(\n serverId,\n `MCP server ${serverId} advertised tools that cannot form a Toolkit`,\n ),\n });\n\n const handlers = toolkit.toLayer(\n Object.fromEntries(\n tools.map((tool) => [tool.name, (params: unknown) => callTool(tool.name, params)] as const),\n ),\n );\n\n return {\n identity: McpServerIdentity.make({ serverId, implementation: initialized.serverInfo }),\n capabilities: initialized.capabilities,\n tools,\n toolkit,\n handlers,\n } satisfies McpConnectedServer;\n});\n\n/** Platform services one transport needs, as declared by `McpServerTransport<R>`. */\nexport type McpTransportRequirements<Transport> =\n Transport extends McpServerTransport<infer R> ? R : never;\n\nconst makeConnectorLayer = <R>(\n transports: ReadonlyArray<McpServerTransport<R>>,\n options: { readonly clientInfo?: McpSchema.Implementation | undefined } | undefined,\n): Layer.Layer<McpConnector, never, R> =>\n Layer.effect(McpConnector)(\n Effect.gen(function* () {\n const services = yield* Effect.context<R>();\n const byServerId = new Map(transports.map((transport) => [transport.serverId, transport]));\n const clientInfo = options?.clientInfo ?? defaultMcpClientInfo;\n\n return McpConnector.of({\n connect: (request) => {\n const transport = byServerId.get(request.serverId);\n\n if (transport === undefined) {\n return Effect.fail(\n McpConnectionError.make({\n serverId: request.serverId,\n message: `No MCP transport is configured for server '${request.serverId}'`,\n }),\n );\n }\n\n // The Layer supplies the transport's platform services, but the\n // connection must live and die with the caller's Scope, never the\n // Layer's.\n return connectServer(transport, request, clientInfo).pipe(\n Effect.updateContext((caller: Context.Context<Scope.Scope>) =>\n Context.merge(Context.merge(caller, services), Context.pick(Scope.Scope)(caller)),\n ),\n );\n },\n });\n }),\n );\n\n/**\n * `McpConnector` over real transports. Each `connect` acquires the transport\n * in the caller's Scope, negotiates a protocol revision, lists tools within the\n * request bounds, and returns dynamic Effect AI Tools plus the handler Layer\n * that forwards their calls. The Layer requires the union of every\n * transport's platform services.\n */\nexport const layer = <const Transports extends ReadonlyArray<McpServerTransport<unknown>>>(\n transports: Transports,\n options?: { readonly clientInfo?: McpSchema.Implementation | undefined },\n): Layer.Layer<McpConnector, never, McpTransportRequirements<Transports[number]>> =>\n makeConnectorLayer(\n // Type-level only: each element declares its own `R`, and the Layer\n // requires their union. Nothing about the values changes.\n transports as ReadonlyArray<McpServerTransport<McpTransportRequirements<Transports[number]>>>,\n options,\n );\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"McpClient.mjs","names":[],"sources":["../../src/capabilities/McpClient.ts"],"sourcesContent":["import {\n Cause,\n Context,\n Effect,\n Layer,\n Option,\n Predicate,\n Queue,\n Schema,\n Scope,\n Stream,\n} from \"effect\";\nimport { Tool, Toolkit } from \"effect/ai\";\nimport * as McpProtocol from \"effect/ai/McpProtocol\";\nimport * as McpSchema from \"effect/ai/McpSchema\";\nimport { Headers, HttpClient, HttpClientRequest, type HttpClientResponse } from \"effect/http\";\nimport { ChildProcess, ChildProcessSpawner } from \"effect/process\";\nimport { RpcClient, RpcClientError, type RpcMessage, RpcSerialization } from \"effect/rpc\";\n\nimport { utf8ByteLength } from \"../core/internal/utf8.ts\";\nimport { ToolExecutionClass, type ToolExecutionClassValue } from \"../engine/DurableStep.ts\";\nimport {\n McpConnectionError,\n McpConnector,\n type McpConnectedServer,\n type McpConnectionRequest,\n McpServerIdentity,\n McpToolOutputSchema,\n} from \"./Mcp.ts\";\n\n// ---------------------------------------------------------------------------\n// MCP client: native Effect AI MCP schemas and protocol adapters, the Effect\n// RPC client, and Effect HTTP / child-process services connect an Agent to a\n// remote MCP server. Discovered tools become dynamic Effect AI Tools whose\n// handlers forward `tools/call`; `connectMcp` still applies every discovery\n// bound before the Toolkit reaches Agent context.\n// ---------------------------------------------------------------------------\n\n/** Largest single JSON-RPC message a transport accepts from a server by default. */\nconst DEFAULT_MAX_MESSAGE_BYTES = 4 * 1024 * 1024;\n/** Bounded `tools/list` pagination: a server cannot keep a client walking cursors forever. */\nconst MAX_TOOL_LIST_PAGES = 64;\nconst MCP_SESSION_ID_HEADER = \"mcp-session-id\";\nconst MCP_PROTOCOL_VERSION_HEADER = \"mcp-protocol-version\";\nconst JSON_RPC_METHOD_NOT_FOUND = -32601;\n\n/**\n * The protocol revisions this client negotiates, as implemented by Effect AI's\n * native MCP protocol adapters. The newest revision is offered first; a server\n * answering with any other listed revision is accepted, anything else fails.\n */\nexport const McpClientProtocolVersion = Schema.Literals([\n McpProtocol.v2025_11_25.protocolVersion,\n McpProtocol.v2025_06_18.protocolVersion,\n McpProtocol.v2025_03_26.protocolVersion,\n McpProtocol.v2024_11_05.protocolVersion,\n]);\n\nexport type McpClientProtocolVersion = typeof McpClientProtocolVersion.Type;\n\nconst OFFERED_PROTOCOL_VERSION: McpClientProtocolVersion = McpProtocol.v2025_11_25.protocolVersion;\n\n/** Identity this client presents to servers during `initialize`. */\nexport const defaultMcpClientInfo = McpSchema.Implementation.make({\n name: \"effect-agent\",\n version: \"1.0.0\",\n});\n\n/**\n * The model-visible result of a remote MCP tool call: the server's content\n * blocks and, when the tool declares an `outputSchema`, its structured result.\n * A result with `isError` never becomes this value; it fails the Tool Call.\n */\nexport class McpToolResult extends Schema.Class<McpToolResult>(\n \"@effect-agent/capabilities/McpToolResult\",\n)({\n content: Schema.Array(McpSchema.ContentBlock),\n structuredContent: Schema.optionalKey(Schema.Json),\n}) {}\n\n/**\n * Typed failure of one remote MCP tool call. `tool-error` carries the server's\n * error content; the other reasons describe why no trustworthy result exists.\n * None of them claims the remote effect did not happen.\n */\nexport class McpToolCallFailed extends Schema.TaggedError<McpToolCallFailed>()(\n \"McpToolCallFailed\",\n {\n serverId: Schema.NonEmptyString,\n tool: Schema.NonEmptyString,\n reason: Schema.Literals([\"tool-error\", \"invalid-arguments\", \"protocol-error\", \"transport\"]),\n message: Schema.String,\n content: Schema.optionalKey(Schema.Array(McpSchema.ContentBlock)),\n },\n) {}\n\n/**\n * One reachable MCP server. `protocol` acquires a JSON-RPC transport in the\n * caller's Scope; `R` names the platform services that transport needs so the\n * connector Layer keeps them in its requirements.\n */\nexport interface McpServerTransport<R = never> {\n readonly serverId: string;\n /**\n * Whether the server's `readOnlyHint`, `idempotentHint`, and\n * `destructiveHint` may set the framework execution class of its tools.\n * Hints are server-declared and untrusted, so the default leaves every\n * remote tool `uncertain`.\n */\n readonly trustToolAnnotations: boolean;\n readonly protocol: Effect.Effect<\n RpcClient.Protocol[\"Service\"],\n McpConnectionError,\n Scope.Scope | R\n >;\n}\n\n/** Streamable HTTP server address. Header values may carry credentials the application owns. */\nexport interface McpHttpTransportOptions {\n readonly serverId: string;\n readonly url: string;\n readonly headers?: Headers.Input | undefined;\n /** Largest accepted response message. Defaults to 4 MiB. */\n readonly maxMessageBytes?: number | undefined;\n readonly trustToolAnnotations?: boolean | undefined;\n}\n\n/** A local MCP server process speaking newline-delimited JSON-RPC on stdio. */\nexport interface McpStdioTransportOptions {\n readonly serverId: string;\n readonly command: string;\n readonly args?: ReadonlyArray<string> | undefined;\n readonly cwd?: string | undefined;\n readonly env?: Readonly<Record<string, string>> | undefined;\n /** Largest accepted stdout frame. Defaults to 4 MiB. */\n readonly maxMessageBytes?: number | undefined;\n readonly trustToolAnnotations?: boolean | undefined;\n}\n\nconst isNotificationTag = (tag: string): boolean => tag.startsWith(\"notifications/\");\nconst isRpcClientError = Schema.is(RpcClientError.RpcClientError);\n\nconst protocolDefect = (message: string, cause?: unknown): RpcClientError.RpcClientError =>\n RpcClientError.RpcClientError.make({\n reason: RpcClientError.RpcClientDefect.make({ message, cause }),\n });\n\nconst InitializeProtocolVersion = Schema.Struct({ protocolVersion: Schema.String });\nconst decodeInitializeProtocolVersion = Schema.decodeUnknownOption(InitializeProtocolVersion);\n\nconst ServerRequest = Schema.Struct({ _tag: Schema.Literal(\"Request\"), tag: Schema.String });\nconst isServerRequest = Schema.is(ServerRequest);\n\nconst isJsonRpcRequest = (message: unknown): message is RpcMessage.RequestEncoded =>\n isServerRequest(message);\n\n/** Effect RPC's tracing extensions are not part of MCP's strict JSON-RPC request shape. */\nconst mcpWireMessage = (message: unknown): unknown => {\n if (!Predicate.hasProperty(message, \"_tag\") || message._tag !== \"Request\") return message;\n const payload = Predicate.hasProperty(message, \"payload\") ? message.payload : undefined;\n\n return {\n ...message,\n payload: payload === null ? undefined : payload,\n traceId: undefined,\n spanId: undefined,\n sampled: undefined,\n headers: [],\n };\n};\n\n/** JSON-RPC error a client returns for a server-initiated request it does not serve. */\nconst declineServerRequest = (\n request: RpcMessage.RequestEncoded,\n): RpcMessage.ResponseExitEncoded => ({\n _tag: \"Exit\",\n requestId: request.id,\n exit: {\n _tag: \"Failure\",\n cause: [\n {\n _tag: \"Fail\",\n error: {\n code: JSON_RPC_METHOD_NOT_FOUND,\n message: `Client does not serve ${request.tag}`,\n },\n },\n ],\n },\n});\n\n/**\n * Routes one decoded JSON-RPC message. Responses reach the RPC client; server\n * notifications are logged; server requests (sampling, elicitation, roots)\n * are declined fail-closed through `respond` because this client serves none.\n */\nconst routeMessage = (\n message: unknown,\n options: {\n readonly clientId: number;\n readonly writeResponse: (\n clientId: number,\n response: RpcMessage.FromServerEncoded,\n ) => Effect.Effect<void>;\n readonly respond: (response: RpcMessage.ResponseExitEncoded) => Effect.Effect<void>;\n readonly onExit: (exit: RpcMessage.ResponseExitEncoded) => void;\n },\n): Effect.Effect<void> => {\n if (isJsonRpcRequest(message)) {\n if (message.isNotification === true) {\n return Effect.logDebug(\"Ignoring MCP server notification\").pipe(\n Effect.annotateLogs({ method: message.tag }),\n );\n }\n\n return options.respond(declineServerRequest(message));\n }\n if (Predicate.hasProperty(message, \"_tag\") && message._tag === \"Exit\") {\n options.onExit(message as RpcMessage.ResponseExitEncoded);\n }\n\n return options.writeResponse(options.clientId, message as RpcMessage.FromServerEncoded);\n};\n\n/** Reads a response body as text while refusing bodies above `maxBytes`. */\nconst readBoundedText = Effect.fnUntraced(function* (\n response: HttpClientResponse.HttpClientResponse,\n maxBytes: number,\n) {\n const declared = Number(response.headers[\"content-length\"]);\n\n if (Number.isFinite(declared) && declared > maxBytes) {\n return yield* protocolDefect(\n `MCP response of ${declared} bytes exceeds the ${maxBytes} byte message bound`,\n );\n }\n const chunks: Array<string> = [];\n let received = 0;\n\n yield* response.stream.pipe(\n Stream.decodeText(),\n Stream.runForEach((chunk) => {\n received += utf8ByteLength(chunk);\n if (received > maxBytes) {\n return Effect.fail(\n protocolDefect(`MCP response exceeds the ${maxBytes} byte message bound`),\n );\n }\n chunks.push(chunk);\n\n return Effect.void;\n }),\n Effect.mapError((error) =>\n isRpcClientError(error)\n ? error\n : protocolDefect(\"Could not read the MCP HTTP response\", error),\n ),\n );\n\n return chunks.join(\"\");\n});\n\n/**\n * Delivers the `data` of each `text/event-stream` event as it arrives. Only\n * `data` fields carry JSON-RPC messages; `event`, `id`, `retry`, and comment\n * lines are ignored because this client never resumes a stream, so a server\n * retry directive neither ends the stream nor fails the request. At most\n * `maxBytes` of an unterminated event stays buffered.\n */\nconst consumeEventStream = Effect.fnUntraced(function* (\n response: HttpClientResponse.HttpClientResponse,\n maxBytes: number,\n deliver: (data: string) => Effect.Effect<void>,\n) {\n let buffer = \"\";\n let pendingBytes = 0;\n\n const dispatchEvent = (block: string): Effect.Effect<void> => {\n const data = block\n .split(/\\r?\\n/)\n .filter((line) => line.startsWith(\"data:\"))\n .map((line) => line.slice(\"data:\".length).replace(/^ /, \"\"))\n .join(\"\\n\");\n\n return data.length === 0 ? Effect.void : deliver(data);\n };\n\n const drain = (final: boolean): Effect.Effect<void> =>\n Effect.suspend(() => {\n const blocks: Array<string> = [];\n\n while (true) {\n const match = /\\r?\\n\\r?\\n/.exec(buffer);\n\n if (match === null) break;\n blocks.push(buffer.slice(0, match.index));\n buffer = buffer.slice(match.index + match[0].length);\n }\n if (final && buffer.length > 0) {\n blocks.push(buffer);\n buffer = \"\";\n }\n pendingBytes = utf8ByteLength(buffer);\n\n return Effect.forEach(blocks, dispatchEvent, { discard: true });\n });\n\n yield* response.stream.pipe(\n Stream.decodeText(),\n Stream.runForEach((chunk) => {\n buffer += chunk;\n pendingBytes += utf8ByteLength(chunk);\n if (pendingBytes > maxBytes) {\n return Effect.fail(protocolDefect(`MCP event stream buffered more than ${maxBytes} bytes`));\n }\n\n return drain(false);\n }),\n Effect.mapError((error) =>\n isRpcClientError(error)\n ? error\n : protocolDefect(\"Could not read the MCP event stream\", error),\n ),\n );\n yield* drain(true);\n});\n\nconst makeHttpProtocol = Effect.fnUntraced(function* (options: McpHttpTransportOptions) {\n const client = yield* HttpClient.HttpClient;\n const serialization = RpcSerialization.jsonRpc();\n const parser = serialization.makeUnsafe();\n const maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;\n const configuredHeaders = Headers.fromInput(options.headers);\n const url = options.url;\n let sessionId: string | undefined;\n let protocolVersion: string | undefined;\n let initializeRequestId: string | number | undefined;\n /** Request ids whose JSON-RPC response has been delivered. */\n const answered = new Set<string | number>();\n\n const transportHeaders = (): Headers.Headers =>\n Headers.merge(\n configuredHeaders,\n Headers.fromInput({\n accept: \"application/json, text/event-stream\",\n ...(sessionId === undefined ? {} : { [MCP_SESSION_ID_HEADER]: sessionId }),\n ...(protocolVersion === undefined\n ? {}\n : { [MCP_PROTOCOL_VERSION_HEADER]: protocolVersion }),\n }),\n );\n\n const post = (body: string) =>\n client\n .execute(\n HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeaders(transportHeaders()),\n HttpClientRequest.bodyText(body, \"application/json\"),\n ),\n )\n .pipe(\n Effect.mapError((error) =>\n protocolDefect(`MCP HTTP request to ${options.serverId} failed`, error),\n ),\n );\n\n // Ending the session is a courtesy to the server; the Scope owns the client.\n yield* Effect.addFinalizer(() =>\n sessionId === undefined\n ? Effect.void\n : client\n .execute(\n HttpClientRequest.delete(url).pipe(HttpClientRequest.setHeaders(transportHeaders())),\n )\n .pipe(Effect.ignore),\n );\n\n return yield* RpcClient.Protocol.make((writeResponse) =>\n Effect.sync(() => {\n const encode = (message: unknown): Effect.Effect<string, RpcClientError.RpcClientError> =>\n Effect.suspend(() => {\n const encoded = parser.encode(mcpWireMessage(message));\n\n return typeof encoded === \"string\"\n ? Effect.succeed(encoded)\n : Effect.fail(protocolDefect(\"Could not encode an MCP JSON-RPC message\"));\n });\n\n const deliver = (clientId: number, data: string): Effect.Effect<void> =>\n Effect.suspend(() => {\n let messages: ReadonlyArray<unknown>;\n\n try {\n messages = parser.decode(data);\n } catch (cause) {\n return writeResponse(clientId, {\n _tag: \"ClientProtocolError\",\n error: protocolDefect(\"Could not decode an MCP JSON-RPC message\", cause),\n });\n }\n\n return Effect.forEach(\n messages,\n (message) =>\n routeMessage(message, {\n clientId,\n writeResponse,\n respond: (response) => encode(response).pipe(Effect.flatMap(post), Effect.ignore),\n onExit: (exit) => {\n answered.add(exit.requestId);\n if (exit.requestId !== initializeRequestId || exit.exit._tag !== \"Success\") {\n return;\n }\n const decoded = decodeInitializeProtocolVersion(exit.exit.value);\n\n if (Option.isSome(decoded)) protocolVersion = decoded.value.protocolVersion;\n },\n }),\n { discard: true },\n );\n });\n\n /**\n * Posts one message and delivers whatever the server answers. A request\n * whose HTTP exchange completes without a JSON-RPC response for its id\n * (for example a `202`, an `id: null` error, or a stream that ends\n * early) fails that request instead of leaving its caller waiting.\n */\n const dispatch = Effect.fnUntraced(function* (\n clientId: number,\n message: unknown,\n requestId?: string | number,\n ) {\n const response = yield* post(yield* encode(message));\n const responseSession = response.headers[MCP_SESSION_ID_HEADER];\n\n if (responseSession !== undefined) sessionId = responseSession;\n if (response.status < 200 || response.status >= 300) {\n return yield* protocolDefect(\n `MCP server ${options.serverId} answered HTTP ${response.status}`,\n );\n }\n const contentType = response.headers[\"content-type\"] ?? \"\";\n\n if (response.status !== 202 && response.status !== 204) {\n if (contentType.startsWith(\"text/event-stream\")) {\n yield* consumeEventStream(response, maxMessageBytes, (data) => deliver(clientId, data));\n } else {\n const text = yield* readBoundedText(response, maxMessageBytes);\n\n if (text.length > 0) yield* deliver(clientId, text);\n }\n }\n if (requestId !== undefined && !answered.has(requestId)) {\n yield* writeResponse(clientId, {\n _tag: \"Exit\",\n requestId,\n exit: {\n _tag: \"Failure\",\n cause: [\n {\n _tag: \"Die\",\n defect: `MCP server ${options.serverId} closed the HTTP exchange without answering request ${String(requestId)}`,\n },\n ],\n },\n });\n }\n answered.delete(requestId ?? \"\");\n });\n\n const send: RpcClient.Protocol[\"Service\"][\"send\"] = (clientId, request) => {\n switch (request._tag) {\n case \"Request\": {\n if (isNotificationTag(request.tag)) {\n return dispatch(clientId, { ...request, isNotification: true });\n }\n if (request.tag === \"initialize\") initializeRequestId = request.id;\n\n return dispatch(clientId, request, request.id);\n }\n case \"Interrupt\": {\n return dispatch(clientId, {\n _tag: \"Request\",\n id: request.requestId,\n tag: \"notifications/cancelled\",\n payload: { requestId: request.requestId },\n headers: [],\n isNotification: true,\n } satisfies RpcMessage.RequestEncoded);\n }\n case \"Ack\":\n case \"Ping\":\n case \"Eof\": {\n return Effect.void;\n }\n }\n };\n\n return {\n send,\n supportsAck: false,\n supportsTransferables: false,\n codecFor: serialization.codecFor,\n };\n }),\n );\n});\n\nconst makeStdioProtocol = Effect.fnUntraced(function* (options: McpStdioTransportOptions) {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;\n const maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;\n const serialization = RpcSerialization.ndJsonRpc({ maxBufferSize: maxMessageBytes });\n const parser = serialization.makeUnsafe();\n\n const handle = yield* spawner\n .spawn(\n ChildProcess.make(options.command, [...(options.args ?? [])], {\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n ...(options.env === undefined ? {} : { env: options.env, extendEnv: true }),\n }),\n )\n .pipe(\n Effect.mapError((cause) =>\n McpConnectionError.make({\n serverId: options.serverId,\n message: `Could not start the MCP server process for ${options.serverId}`,\n cause,\n }),\n ),\n );\n\n const outbound = yield* Queue.unbounded<string>();\n // Once the process is gone every later send fails immediately instead of\n // queueing behind a writer that no longer exists.\n let closed: RpcClientError.RpcClientError | undefined;\n\n const closedWith = (message: string, cause?: unknown): RpcClientError.RpcClientError =>\n (closed ??= protocolDefect(message, cause));\n\n yield* Stream.fromQueue(outbound).pipe(\n Stream.encodeText,\n Stream.run(handle.stdin),\n Effect.matchCauseEffect({\n onSuccess: () =>\n Effect.sync(() => closedWith(`MCP server process ${options.serverId} closed stdin`)),\n onFailure: (cause) =>\n Cause.hasInterruptsOnly(cause)\n ? Effect.void\n : Effect.sync(() =>\n closedWith(\n `Writing to MCP server process ${options.serverId} failed`,\n Cause.squash(cause),\n ),\n ),\n }),\n Effect.forkScoped,\n );\n yield* handle.stderr.pipe(\n Stream.decodeText(),\n Stream.splitLines,\n Stream.runForEach((line) => Effect.logDebug(line)),\n Effect.ignore,\n Effect.annotateLogs({ mcpServerId: options.serverId, stream: \"stderr\" }),\n Effect.forkScoped,\n );\n\n return yield* RpcClient.Protocol.make(\n Effect.fnUntraced(function* (writeResponse, clientIds) {\n const broadcast = (error: RpcClientError.RpcClientError) =>\n Effect.forEach(\n clientIds,\n (clientId) => writeResponse(clientId, { _tag: \"ClientProtocolError\", error }),\n { discard: true },\n );\n\n const deliver = (chunk: Uint8Array): Effect.Effect<void> =>\n Effect.suspend(() => {\n let messages: ReadonlyArray<unknown>;\n\n try {\n messages = parser.decode(chunk);\n } catch (cause) {\n return broadcast(protocolDefect(\"Could not decode an MCP stdio frame\", cause));\n }\n\n return Effect.forEach(\n messages,\n (message) =>\n Effect.forEach(\n clientIds,\n (clientId) =>\n routeMessage(message, {\n clientId,\n writeResponse,\n respond: (response) => enqueue(response).pipe(Effect.ignore),\n onExit: () => {},\n }),\n { discard: true },\n ),\n { discard: true },\n );\n });\n\n const enqueue = (message: unknown): Effect.Effect<void, RpcClientError.RpcClientError> =>\n Effect.suspend(() => {\n if (closed !== undefined) return Effect.fail(closed);\n const encoded = parser.encode(mcpWireMessage(message));\n\n if (typeof encoded !== \"string\") {\n return Effect.fail(protocolDefect(\"Could not encode an MCP JSON-RPC message\"));\n }\n\n return Queue.offer(outbound, encoded).pipe(Effect.asVoid);\n });\n\n yield* handle.stdout.pipe(\n Stream.runForEach(deliver),\n Effect.matchCauseEffect({\n onSuccess: () =>\n broadcast(closedWith(`MCP server process ${options.serverId} closed stdout`)),\n onFailure: (cause) =>\n Cause.hasInterruptsOnly(cause)\n ? Effect.void\n : broadcast(\n closedWith(\n `Reading MCP server process ${options.serverId} failed`,\n Cause.squash(cause),\n ),\n ),\n }),\n Effect.forkScoped,\n );\n\n const send: RpcClient.Protocol[\"Service\"][\"send\"] = (_clientId, request) => {\n switch (request._tag) {\n case \"Request\": {\n return enqueue(\n isNotificationTag(request.tag) ? { ...request, isNotification: true } : request,\n );\n }\n case \"Interrupt\": {\n return enqueue({\n _tag: \"Request\",\n id: request.requestId,\n tag: \"notifications/cancelled\",\n payload: { requestId: request.requestId },\n headers: [],\n isNotification: true,\n } satisfies RpcMessage.RequestEncoded);\n }\n case \"Ack\":\n case \"Ping\":\n case \"Eof\": {\n return Effect.void;\n }\n }\n };\n\n return {\n send,\n supportsAck: false,\n supportsTransferables: false,\n codecFor: serialization.codecFor,\n };\n }),\n );\n});\n\n/** Streamable HTTP transport for one remote MCP server; requires `HttpClient`. */\nexport const McpHttpTransport = {\n make: (options: McpHttpTransportOptions): McpServerTransport<HttpClient.HttpClient> => ({\n serverId: options.serverId,\n trustToolAnnotations: options.trustToolAnnotations ?? false,\n protocol: makeHttpProtocol(options),\n }),\n} as const;\n\n/** stdio transport for one local MCP server process; requires `ChildProcessSpawner`. */\nexport const McpStdioTransport = {\n make: (\n options: McpStdioTransportOptions,\n ): McpServerTransport<ChildProcessSpawner.ChildProcessSpawner> => ({\n serverId: options.serverId,\n trustToolAnnotations: options.trustToolAnnotations ?? false,\n protocol: makeStdioProtocol(options),\n }),\n} as const;\n\n/**\n * Effect AI Tool derived from one discovered MCP tool. Its parameters are the\n * server's JSON Schema, so handlers receive `unknown` and the server validates\n * arguments; `Tool.getJsonSchema` still advertises the discovered schema. A\n * failed call returns `McpToolCallFailed` to the model as a failed tool result.\n */\nexport type McpTool = Tool.Tool<\n string,\n {\n readonly parameters: typeof Schema.Unknown;\n readonly success: typeof McpToolResult;\n readonly failure: typeof McpToolCallFailed;\n readonly failureMode: \"return\";\n }\n>;\n\n/** Toolkit of discovered MCP tools; every member forwards `tools/call` to its server. */\nexport type McpToolkit = Toolkit.Toolkit<Record<string, McpTool>>;\n\nconst executionClassFor = (\n annotations: McpSchema.ToolAnnotations | undefined,\n): ToolExecutionClassValue => {\n if (annotations === undefined) return \"uncertain\";\n if (annotations.readOnlyHint) return \"readonly\";\n if (annotations.idempotentHint && !annotations.destructiveHint) return \"idempotent\";\n\n return \"uncertain\";\n};\n\nconst makeMcpTool = (tool: McpSchema.Tool, trustToolAnnotations: boolean): McpTool => {\n // MCP servers may advertise valid JSON Schemas outside a model provider's strict subset.\n let dynamic: McpTool = Tool.dynamic(tool.name, {\n ...(tool.description === undefined ? {} : { description: tool.description }),\n parameters: tool.inputSchema,\n success: McpToolResult,\n failure: McpToolCallFailed,\n // MCP reports tool errors inside results so the model can self-correct;\n // `return` hands the typed failure to the model the same way.\n failureMode: \"return\",\n }).annotate(Tool.Strict, false);\n\n const title = tool.title ?? tool.annotations?.title;\n\n if (title !== undefined) dynamic = dynamic.annotate(Tool.Title, title);\n dynamic = dynamic.annotate(McpToolOutputSchema, Option.fromNullishOr(tool.outputSchema));\n if (tool.annotations !== undefined) {\n dynamic = dynamic\n .annotate(Tool.Readonly, tool.annotations.readOnlyHint)\n .annotate(Tool.Destructive, tool.annotations.destructiveHint)\n .annotate(Tool.Idempotent, tool.annotations.idempotentHint)\n .annotate(Tool.OpenWorld, tool.annotations.openWorldHint);\n }\n if (trustToolAnnotations) {\n dynamic = dynamic.annotate(ToolExecutionClass, executionClassFor(tool.annotations));\n }\n\n return dynamic;\n};\n\nconst ToolArguments = Schema.Record(Schema.String, Schema.Json);\nconst decodeToolArguments = Schema.decodeUnknownEffect(ToolArguments);\n\nconst errorText = (content: ReadonlyArray<typeof McpSchema.ContentBlock.Type>): string =>\n content\n .flatMap((block) => (block.type === \"text\" ? [block.text] : []))\n .join(\"\\n\")\n .slice(0, 4 * 1024);\n\nconst describeDefect = (defect: unknown): string =>\n (Predicate.hasProperty(defect, \"message\") && Predicate.isString(defect.message)\n ? defect.message\n : String(defect)\n ).slice(0, 4 * 1024);\n\nconst connectionError = (serverId: string, message: string) => (cause: unknown) =>\n McpConnectionError.make({ serverId, message, cause });\n\n/**\n * Keeps every non-interrupt outcome of one protocol step typed: expected\n * failures and defects (such as an undecodable server reply) both become the\n * connection error, so a misbehaving server cannot crash the connector.\n */\nconst failClosed =\n (serverId: string, message: string) =>\n <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, McpConnectionError, R> =>\n self.pipe(\n Effect.mapError(connectionError(serverId, message)),\n Effect.catchDefect((defect) => Effect.fail(connectionError(serverId, message)(defect))),\n );\n\nconst connectServer = Effect.fnUntraced(function* <R>(\n transport: McpServerTransport<R>,\n request: McpConnectionRequest,\n clientInfo: McpSchema.Implementation,\n): Effect.fn.Return<McpConnectedServer, McpConnectionError, Scope.Scope | R> {\n const serverId = transport.serverId;\n const protocol = yield* transport.protocol;\n\n const client = yield* RpcClient.make(McpSchema.ClientRpcs, {\n spanPrefix: \"McpClient\",\n spanAttributes: { \"mcp.server_id\": serverId },\n }).pipe(Effect.provideService(RpcClient.Protocol, protocol));\n\n const initialized = yield* client\n .initialize({\n protocolVersion: OFFERED_PROTOCOL_VERSION,\n capabilities: McpSchema.ClientCapabilities.make({}),\n clientInfo,\n })\n .pipe(failClosed(serverId, `MCP initialize with ${serverId} failed`));\n\n const negotiated = yield* Schema.decodeUnknownEffect(McpClientProtocolVersion)(\n initialized.protocolVersion,\n ).pipe(\n Effect.mapError(\n connectionError(\n serverId,\n `MCP server ${serverId} negotiated unsupported protocol version '${initialized.protocolVersion}'`,\n ),\n ),\n );\n\n yield* Effect.annotateCurrentSpan({ \"mcp.protocol_version\": negotiated });\n yield* client[\"notifications/initialized\"](undefined, { discard: true }).pipe(\n failClosed(serverId, `Could not acknowledge MCP initialization with ${serverId}`),\n );\n\n const tools: Array<McpSchema.Tool> = [];\n let cursor: string | undefined;\n let pages = 0;\n\n do {\n const page = yield* client[\"tools/list\"](\n cursor === undefined ? undefined : McpSchema.PaginatedRequestMeta.make({ cursor }),\n ).pipe(failClosed(serverId, `MCP tools/list with ${serverId} failed`));\n\n tools.push(...page.tools);\n cursor = page.nextCursor;\n pages += 1;\n // `validateMcpDiscovery` rejects the count; stop paying for more pages.\n if (tools.length > request.maxToolCount) break;\n if (cursor !== undefined && pages >= MAX_TOOL_LIST_PAGES) {\n return yield* McpConnectionError.make({\n serverId,\n message: `MCP server ${serverId} paginated tools/list beyond ${MAX_TOOL_LIST_PAGES} pages`,\n });\n }\n } while (cursor !== undefined);\n\n const callTool = Effect.fnUntraced(function* (name: string, params: unknown) {\n const args = yield* decodeToolArguments(params ?? {}).pipe(\n Effect.mapError((cause) =>\n McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: \"invalid-arguments\",\n message: `MCP tool arguments must be a JSON object: ${cause.message}`,\n }),\n ),\n );\n\n const result = yield* client[\"tools/call\"]({ name, arguments: args }).pipe(\n Effect.mapError((error) =>\n McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: isRpcClientError(error) ? \"transport\" : \"protocol-error\",\n message: error.message,\n }),\n ),\n // A JSON-RPC error the MCP error union cannot decode (or any other\n // malformed reply) surfaces as a defect from the RPC client. It is still\n // the server's answer, so it reaches the model as a failed tool result\n // rather than aborting the batch.\n Effect.catchDefect((defect) =>\n Effect.fail(\n McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: \"protocol-error\",\n message: describeDefect(defect),\n }),\n ),\n ),\n );\n\n if (result.isError === true) {\n return yield* McpToolCallFailed.make({\n serverId,\n tool: name,\n reason: \"tool-error\",\n message: errorText(result.content),\n content: result.content,\n });\n }\n\n return McpToolResult.make({\n content: result.content,\n ...(result.structuredContent === undefined\n ? {}\n : { structuredContent: result.structuredContent }),\n });\n });\n\n const toolkit: McpToolkit = yield* Effect.try({\n try: () =>\n Toolkit.make(...tools.map((tool) => makeMcpTool(tool, transport.trustToolAnnotations))),\n catch: connectionError(\n serverId,\n `MCP server ${serverId} advertised tools that cannot form a Toolkit`,\n ),\n });\n\n const handlers = toolkit.toLayer(\n Object.fromEntries(\n tools.map((tool) => [tool.name, (params: unknown) => callTool(tool.name, params)] as const),\n ),\n );\n\n return {\n identity: McpServerIdentity.make({ serverId, implementation: initialized.serverInfo }),\n capabilities: initialized.capabilities,\n tools,\n toolkit,\n handlers,\n } satisfies McpConnectedServer;\n});\n\n/** Platform services one transport needs, as declared by `McpServerTransport<R>`. */\nexport type McpTransportRequirements<Transport> =\n Transport extends McpServerTransport<infer R> ? R : never;\n\nconst makeConnectorLayer = <R>(\n transports: ReadonlyArray<McpServerTransport<R>>,\n options: { readonly clientInfo?: McpSchema.Implementation | undefined } | undefined,\n): Layer.Layer<McpConnector, never, R> =>\n Layer.effect(McpConnector)(\n Effect.gen(function* () {\n const services = yield* Effect.context<R>();\n const byServerId = new Map(transports.map((transport) => [transport.serverId, transport]));\n const clientInfo = options?.clientInfo ?? defaultMcpClientInfo;\n\n return McpConnector.of({\n connect: (request) => {\n const transport = byServerId.get(request.serverId);\n\n if (transport === undefined) {\n return Effect.fail(\n McpConnectionError.make({\n serverId: request.serverId,\n message: `No MCP transport is configured for server '${request.serverId}'`,\n }),\n );\n }\n\n // The Layer supplies the transport's platform services, but the\n // connection must live and die with the caller's Scope, never the\n // Layer's.\n return connectServer(transport, request, clientInfo).pipe(\n Effect.updateContext((caller: Context.Context<Scope.Scope>) =>\n Context.merge(Context.merge(caller, services), Context.pick(Scope.Scope)(caller)),\n ),\n );\n },\n });\n }),\n );\n\n/**\n * `McpConnector` over real transports. Each `connect` acquires the transport\n * in the caller's Scope, negotiates a protocol revision, lists tools within the\n * request bounds, and returns dynamic Effect AI Tools plus the handler Layer\n * that forwards their calls. The Layer requires the union of every\n * transport's platform services.\n */\nexport const layer = <const Transports extends ReadonlyArray<McpServerTransport<unknown>>>(\n transports: Transports,\n options?: { readonly clientInfo?: McpSchema.Implementation | undefined },\n): Layer.Layer<McpConnector, never, McpTransportRequirements<Transports[number]>> =>\n makeConnectorLayer(\n // Type-level only: each element declares its own `R`, and the Layer\n // requires their union. Nothing about the values changes.\n transports as ReadonlyArray<McpServerTransport<McpTransportRequirements<Transports[number]>>>,\n options,\n );\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { a as MessageAdmission, c as MessageRef, i as MessageAddress, l as MessageStatus, n as InboxPage, o as MessagingError, r as InputMessage, s as PeerName, t as InboxEntry } from "../Messaging-DF_IWnxV.mjs";
|
|
2
|
-
import { a as inspect, c as reply, d as retryTool, f as send, i as inboxTool, l as replyTool, n as Peer, o as inspectTool, p as sendTool, r as inbox, s as peer, u as retry } from "../Messaging-
|
|
2
|
+
import { a as inspect, c as reply, d as retryTool, f as send, i as inboxTool, l as replyTool, n as Peer, o as inspectTool, p as sendTool, r as inbox, s as peer, u as retry } from "../Messaging-SVu6rWV8.mjs";
|
|
3
3
|
export { InboxEntry, InboxPage, InputMessage, MessageAddress, MessageAdmission, MessageRef, MessageStatus, MessagingError, Peer, PeerName, inbox, inboxTool, inspect, inspectTool, peer, reply, replyTool, retry, retryTool, send, sendTool };
|
|
@@ -2,7 +2,7 @@ import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.mjs";
|
|
|
2
2
|
import { IdempotencyKey } from "../core/Receipt.mjs";
|
|
3
3
|
import { WorkerOperationTool } from "../core/SubagentContract.mjs";
|
|
4
4
|
import { C as MessageStatus, S as MessageRef } from "../Worker-DZjdMjZn.mjs";
|
|
5
|
-
import { c as InboxPage, d as MessageAdmission, f as MessagingError, l as InputMessage, p as PeerName, s as InboxEntry, t as MessagingHost, u as MessageAddress } from "../MessagingHost-
|
|
5
|
+
import { c as InboxPage, d as MessageAdmission, f as MessagingError, l as InputMessage, p as PeerName, s as InboxEntry, t as MessagingHost, u as MessageAddress } from "../MessagingHost-CZCyrnvJ.mjs";
|
|
6
6
|
import { t as utf8Bytes } from "../utf8-B770uxC3.mjs";
|
|
7
7
|
import { Crypto, Effect, Option, Schema } from "effect";
|
|
8
8
|
import { Tool, Toolkit } from "effect/ai";
|
|
@@ -41,7 +41,7 @@ const host = Effect.serviceOption(MessagingHost).pipe(Effect.flatMap((value) =>
|
|
|
41
41
|
operation: "context",
|
|
42
42
|
reason: "unavailable"
|
|
43
43
|
})));
|
|
44
|
-
const dispatch = (declaration, input, options, operation)
|
|
44
|
+
const dispatch = Effect.fnUntraced(function* (declaration, input, options, operation) {
|
|
45
45
|
const service = yield* host;
|
|
46
46
|
const invalid = () => MessagingError.make({
|
|
47
47
|
operation,
|
|
@@ -73,21 +73,21 @@ const reply = (declaration, inReplyTo, input, options) => dispatch(declaration,
|
|
|
73
73
|
inReplyTo
|
|
74
74
|
}, "reply");
|
|
75
75
|
/** Return bounded provenance for messages from this peer, without granting permission to reply. */
|
|
76
|
-
const inbox = (declaration, options = {})
|
|
76
|
+
const inbox = Effect.fnUntraced(function* (declaration, options = {}) {
|
|
77
77
|
return yield* (yield* host).inbox({
|
|
78
78
|
...declaration,
|
|
79
79
|
...options,
|
|
80
80
|
limit: options.limit ?? 20
|
|
81
81
|
});
|
|
82
82
|
});
|
|
83
|
-
const inspect =
|
|
83
|
+
const inspect = Effect.fnUntraced(function* (declaration, message) {
|
|
84
84
|
return yield* (yield* host).inspect({
|
|
85
85
|
...declaration,
|
|
86
86
|
message
|
|
87
87
|
});
|
|
88
88
|
});
|
|
89
89
|
/** Explicitly renew a parked delivery's bounded retry budget, retaining its complete frozen envelope. */
|
|
90
|
-
const retry =
|
|
90
|
+
const retry = Effect.fnUntraced(function* (declaration, message) {
|
|
91
91
|
return yield* (yield* host).retry({
|
|
92
92
|
...declaration,
|
|
93
93
|
message
|