@opengeni/runtime 0.13.3 → 0.13.10

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.
@@ -66,6 +66,7 @@ declare function boundedParallelMap<T, R>(values: readonly T[], concurrency: num
66
66
  declare function guardedMcpFetch<TInput extends string | URL | Request>(settings: Pick<Settings, "environment" | "integrationsAllowPrivateNetworkTargets">, fetchImpl: (input: TInput, init?: RequestInit) => Promise<Response>, options?: {
67
67
  maxResponseBytes?: number;
68
68
  dnsLookup?: DnsLookup;
69
+ pinResolvedDestination?: boolean;
69
70
  requireHttpsOutsideLocalTest?: boolean;
70
71
  }): (input: TInput, init?: RequestInit) => Promise<Response>;
71
72
  declare function boundMcpResponseBody(response: Response, maxBytes: number): Response;
@@ -29,7 +29,7 @@ import {
29
29
  mcpOuterConnectTimeoutMs,
30
30
  mcpSerializedSizeBytes,
31
31
  undiciFetch
32
- } from "./chunk-SSB7VOLE.js";
32
+ } from "./chunk-QYXOVIUK.js";
33
33
  import "./chunk-PZ5AY32C.js";
34
34
  export {
35
35
  MCP_DEFAULT_OUTER_CONNECT_TIMEOUT_MS,
@@ -1,6 +1,6 @@
1
1
  export { collectSandboxEnvironment, parseExposedPorts } from '@opengeni/config';
2
2
  export { CAPABILITY_DESCRIPTORS, CapabilityDescriptor, DESKTOP_STREAM_PORT, StreamTokenPayload, StreamTokenPayload as StreamTokenPayloadType, TERMINAL_STREAM_PORT } from '@opengeni/contracts';
3
3
  import '@openai/agents/sandbox';
4
- export { A as ActiveBackendResolverDeps, b as ActiveBackendUnresolvableError, c as ActivePointer, B as BackendUnresolvableCode, C as ChannelAConflictError, d as ChannelAEmitter, e as ChannelAExecArgs, f as ChannelAExecResult, g as ChannelANotFoundError, h as ChannelASession, i as ChannelAUnavailableError, j as ChannelAUnsupportedError, k as ChannelAValidationError, l as ControlRpc, D as DEFAULT_DESKTOP_GEOMETRY, m as DISPLAY_STACK_TIMEOUT_MS, n as DefaultBackendLossResult, o as DesktopGeometry, p as DisplayStackCallerKind, q as DisplayStackClassification, r as DisplayStackError, s as DisplayStackTelemetryContext, t as DisplayStackTelemetryEvent, u as DisplayStackTelemetryStatus, v as DisplayStackUnsupportedError, E as EnsureDisplayStackOptions, w as EnsureDisplayStackResult, x as EnsureTerminalServerOptions, y as EnsureTerminalServerResult, z as EstablishedSandboxSession, F as ExposeStreamPortInput, G as ExposeStreamPortResult, H as ExposedPortEndpoint, I as FAULT_FIELD_WHAT_HAPPENED, J as FAULT_FIELD_WHAT_PRESERVED, K as FAULT_FIELD_WHAT_TO_TRY, L as FAULT_FIELD_WHICH_LAYER, M as LiveModalSandboxLeaseAttribution, N as MaterializeRunCredentialsOptions, O as MintStreamTokenInput, P as MockAgentResponder, Q as MockAgentResponderOptions, S as MockExecHandler, T as ModalModuleLoader, U as ModalOrphanSweepResult, V as ModalOrphanSweepTermination, W as ModalSandboxAttribution, X as NEVER_SENT_DETAIL_KEY, Y as NatsControlRpc, Z as NatsOpStreamConnection, _ as NatsOpStreamTransport, $ as NatsRequestConnection, a0 as NegotiationContext, a1 as NormalizedRunCredentialMaterial, a2 as NumstatEntry, a3 as OP_STREAM_ACK_INTERVAL_MS, a4 as OP_STREAM_DEFAULT_WINDOW_BYTES, a5 as OP_STREAM_RECONNECT_HOLD_MS, a6 as OP_STREAM_SILENCE_TIMEOUT_MS, a7 as OpStreamExecOutcome, a8 as OpStreamJournal, a9 as OpStreamSubscription, aa as OpStreamTransport, ab as OpStreamUnavailableError, ac as PROVIDER_REGISTRY, ad as ProviderConstructionContext, ae as ProviderRegistration, af as ProviderSandboxFailure, ag as ProviderSandboxFailureKind, ah as REPOSITORY_DISCOVERY_LIMIT, ai as RecordingArtifactMetadata, aj as RecordingCodec, ak as RecordingContentType, al as RecordingError, am as RecordingProcess, an as RecordingUnavailableError, ao as RepositoryDiscoveryDegradedReason, ap as RepositoryDiscoveryResult, aq as ResolvedActiveBackend, ar as RevalidateModalOrphanTermination, as as RoutableBackendSession, at as RoutableSandbox, au as RoutingBackendRecoveryRequiredError, av as RoutingMutationOutcomeUnknownError, aw as RoutingRetainedProcess, ax as RoutingRetainedProcessAdoption, ay as RoutingRetainedProcessNotFoundError, az as RoutingRetainedProcessTerminalProof, aA as RoutingSandboxSession, aB as RoutingSandboxSessionDeps, aC as RoutingTransitionEvent, aD as RoutingUnsupportedError, aE as RunCredentialCommandRunner, aF as RunCredentialCommandSession, aG as RunCredentialExpectedScope, R as RunCredentialSessionReady, aH as RunCredentialValidationError, aI as SELFHOSTED_DEFAULT_TIMEOUT_MS, aJ as SELFHOSTED_DRAINING_MAX_RETRIES, aK as SELFHOSTED_EXEC_DRAINING_MAX_RETRIES, aL as SELFHOSTED_IDEMPOTENT_READONLY_OPS, aM as SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES, aN as SELFHOSTED_NEVER_SENT_MAX_RETRIES, aO as SELFHOSTED_RECONNECT_WINDOW_MS, aP as SELFHOSTED_RELAY_STREAM_PATH, aQ as SELFHOSTED_RETRY_BACKOFF_BASE_MS, aR as SELFHOSTED_RETRY_BACKOFF_CAP_MS, aS as SELFHOSTED_RETRY_BACKOFF_FACTOR, aT as SELFHOSTED_TIMEOUT_MAX_RETRIES, aU as STREAM_PORT, aV as STREAM_TOKEN_DEFAULT_TTL_SECONDS, aW as SandboxChannelAService, aX as SandboxChannelAServiceOptions, aY as SandboxConfigError, aZ as SandboxCreatedCallback, a_ as SandboxExecReadinessError, a$ as SandboxProviderUnavailableError, b0 as SandboxReplacementProviderStateError, b1 as SandboxResumeStateUnavailableError, b2 as SelfhostedApplyDiff, b3 as SelfhostedControlError, b4 as SelfhostedEditor, b5 as SelfhostedEnrollment, b6 as SelfhostedExecArgs, b7 as SelfhostedExecResult, b8 as SelfhostedImageOutput, b9 as SelfhostedLivenessState, ba as SelfhostedNegotiationInput, bb as SelfhostedOpObservation, bc as SelfhostedOpObserver, bd as SelfhostedOpStreamDeps, be as SelfhostedRelayConfig, bf as SelfhostedRetryClock, bg as SelfhostedRetryDecision, bh as SelfhostedSandboxClient, bi as SelfhostedSession, bj as SelfhostedSessionBuild, bk as SelfhostedSessionDeps, bl as SelfhostedSessionState, bm as SelfhostedUnavailableReason, bn as StartRecordingInput, bo as StreamPortUnavailableError, bp as SwapTargetEstablishability, bq as TERMINAL_SERVER_TIMEOUT_MS, br as TerminalServerError, bs as TerminalServerUnsupportedError, bt as ToolspaceTokenPathError, bu as VerifiedWorkspaceArchive, bv as WORKSPACE_ARCHIVE_DESCRIPTOR_VERSION, bw as WorkspaceArchiveDescriptor, bx as WorkspaceArchiveIntegrityCode, by as WorkspaceArchiveIntegrityError, bz as WorkspaceTreeFingerprint, bA as agentErrorToControlError, bB as assertDescriptorRegistryInvariants, bC as assertProviderRegistryInvariants, bD as assertSafeRelPath, bE as backendSupportsOs, bF as buildDisplayStackScript, bG as buildSelfhostedBackendSession, bH as buildStreamUrl, bI as buildTerminalServerScript, bJ as captureVerifiedWorkspaceArchive, bK as classifyProviderSandboxFailure, bL as clearRunCredentials, bM as clearRunCredentialsForAttempt, bN as contentTypeForCodec, bO as createSandboxClient, bP as createSandboxClientForBackend, bQ as decideSelfhostedRetry, bR as decodeModalSnapshotId, bS as defaultSelfhostedRetryClock, bT as deletePriorPersistedSnapshot, bU as deleteRecordingArtifacts, bV as deserializeSandboxSessionStateEnvelope, bW as desktopCapableBackend, bX as drainingExhaustedError, bY as drainingMessage, bZ as ensureDisplayStack, b_ as ensureModalRegistryImage, b$ as ensureTerminalServer, c0 as establishSandboxSessionFromEnvelope, c1 as execDeadlineHint, c2 as exposeStreamPort, c3 as extForCodec, c4 as fingerprintSandboxWorkspace, c5 as hasPersistableSandboxProviderIdentity, c6 as inspectRecordingArtifact, c7 as isExecSessionLostBanner, c8 as isProviderSandboxGoneDuringRoutedOperation, c9 as isProviderSandboxNotFoundError, ca as isProviderSandboxTransientError, cb as isSelfhostedProviderNotFoundError, cc as makeActiveBackendResolver, cd as materializeRunCredentials, ce as mintStreamToken, cf as modalSandboxAttributionEnvironment, cg as modalSandboxAttributionTags, ch as negotiateCapabilities, ci as negotiateSelfhostedCapabilities, cj as nextDurableOpId, ck as normalizeRunCredentialsResolution, cl as offlineAgentError, cm as offlineControlResponse, cn as opAckSubject, co as opFrameSubject, cp as parseExecBannerExitCode, cq as parseExecBannerSessionId, cr as parseNumstatZ, cs as parsePorcelainV2, ct as parseUnifiedPatch, cu as parseWorkspaceArchiveDescriptor, cv as payloadTooLargeMessage, cw as readVerifiedWorkspaceArchive, cx as readWorkspaceArchiveFromEnvelopeSessionState, cy as recordingStorageKey, cz as renderSelfhostedFault, cA as requirePersistableReplacementSandboxEnvelope, cB as restoredSandboxSessionStateFromEntry, cC as runCredentialPointerFile, cD as runCredentialRoot, cE as runWithToolCallCorrelation, cF as sandboxStateEntryFromRunState, cG as sanitizeOpIdToken, cH as selectBackend, cI as selfhostedFaultClass, cJ as selfhostedLiveness, cK as selfhostedRetryBackoffMs, cL as serializeEstablishedSandboxEnvelope, cM as serializeReplacementSandboxEnvelope, cN as setSelfhostedApplyDiff, cO as startRecording, cP as stopRecording, cQ as stripExecBanner, cR as subjectFor, cS as swapTargetEstablishability, cT as sweepModalOrphanSandboxes, cU as tagModalSandbox, cV as tearDownDisplayStack, cW as tearDownTerminalServer, cX as terminateModalSandboxById, cY as timeoutAgentError, cZ as timeoutControlResponse, c_ as toolspaceTokenFileForSession, c$ as toolspaceTokenFileFromEnvironment, d0 as uploadRecordingArtifact, d1 as verifyRestoredWorkspace, d2 as verifySandboxExecReadiness, d3 as verifyStreamToken, d4 as withRunCredentialEnvironment, d5 as withRunCredentialsClient, d6 as withRunCredentialsSession, d7 as withToolspaceTokenClient, d8 as withToolspaceTokenEnvironment, d9 as withToolspaceTokenSession } from '../index-DU-KXVlx.js';
4
+ export { A as ActiveBackendResolverDeps, b as ActiveBackendUnresolvableError, c as ActivePointer, B as BackendUnresolvableCode, C as ChannelAConflictError, d as ChannelAEmitter, e as ChannelAExecArgs, f as ChannelAExecResult, g as ChannelANotFoundError, h as ChannelASession, i as ChannelAUnavailableError, j as ChannelAUnsupportedError, k as ChannelAValidationError, l as ControlRpc, D as DEFAULT_DESKTOP_GEOMETRY, m as DISPLAY_STACK_TIMEOUT_MS, n as DefaultBackendLossResult, o as DesktopGeometry, p as DisplayStackCallerKind, q as DisplayStackClassification, r as DisplayStackError, s as DisplayStackTelemetryContext, t as DisplayStackTelemetryEvent, u as DisplayStackTelemetryStatus, v as DisplayStackUnsupportedError, E as EnsureDisplayStackOptions, w as EnsureDisplayStackResult, x as EnsureTerminalServerOptions, y as EnsureTerminalServerResult, z as EstablishedSandboxSession, F as ExposeStreamPortInput, G as ExposeStreamPortResult, H as ExposedPortEndpoint, I as FAULT_FIELD_WHAT_HAPPENED, J as FAULT_FIELD_WHAT_PRESERVED, K as FAULT_FIELD_WHAT_TO_TRY, L as FAULT_FIELD_WHICH_LAYER, M as LiveModalSandboxLeaseAttribution, N as MaterializeRunCredentialsOptions, O as MintStreamTokenInput, P as MockAgentResponder, Q as MockAgentResponderOptions, S as MockExecHandler, T as ModalModuleLoader, U as ModalOrphanSweepResult, V as ModalOrphanSweepTermination, W as ModalSandboxAttribution, X as NEVER_SENT_DETAIL_KEY, Y as NatsControlRpc, Z as NatsOpStreamConnection, _ as NatsOpStreamTransport, $ as NatsRequestConnection, a0 as NegotiationContext, a1 as NormalizedRunCredentialMaterial, a2 as NumstatEntry, a3 as OP_STREAM_ACK_INTERVAL_MS, a4 as OP_STREAM_DEFAULT_WINDOW_BYTES, a5 as OP_STREAM_RECONNECT_HOLD_MS, a6 as OP_STREAM_SILENCE_TIMEOUT_MS, a7 as OpStreamExecOutcome, a8 as OpStreamJournal, a9 as OpStreamSubscription, aa as OpStreamTransport, ab as OpStreamUnavailableError, ac as PROVIDER_REGISTRY, ad as ProviderConstructionContext, ae as ProviderRegistration, af as ProviderSandboxFailure, ag as ProviderSandboxFailureKind, ah as REPOSITORY_DISCOVERY_LIMIT, ai as RecordingArtifactMetadata, aj as RecordingCodec, ak as RecordingContentType, al as RecordingError, am as RecordingProcess, an as RecordingUnavailableError, ao as RepositoryDiscoveryDegradedReason, ap as RepositoryDiscoveryResult, aq as ResolvedActiveBackend, ar as RevalidateModalOrphanTermination, as as RoutableBackendSession, at as RoutableSandbox, au as RoutingBackendRecoveryRequiredError, av as RoutingMutationOutcomeUnknownError, aw as RoutingMutationSettlementResult, ax as RoutingRetainedProcess, ay as RoutingRetainedProcessAdoption, az as RoutingRetainedProcessNotFoundError, aA as RoutingRetainedProcessTerminalProof, aB as RoutingSandboxSession, aC as RoutingSandboxSessionDeps, aD as RoutingTransitionEvent, aE as RoutingUnsupportedError, aF as RunCredentialCommandRunner, aG as RunCredentialCommandSession, aH as RunCredentialExpectedScope, R as RunCredentialSessionReady, aI as RunCredentialValidationError, aJ as SELFHOSTED_DEFAULT_TIMEOUT_MS, aK as SELFHOSTED_DRAINING_MAX_RETRIES, aL as SELFHOSTED_EXEC_DRAINING_MAX_RETRIES, aM as SELFHOSTED_IDEMPOTENT_READONLY_OPS, aN as SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES, aO as SELFHOSTED_NEVER_SENT_MAX_RETRIES, aP as SELFHOSTED_RECONNECT_WINDOW_MS, aQ as SELFHOSTED_RELAY_STREAM_PATH, aR as SELFHOSTED_RETRY_BACKOFF_BASE_MS, aS as SELFHOSTED_RETRY_BACKOFF_CAP_MS, aT as SELFHOSTED_RETRY_BACKOFF_FACTOR, aU as SELFHOSTED_TIMEOUT_MAX_RETRIES, aV as STREAM_PORT, aW as STREAM_TOKEN_DEFAULT_TTL_SECONDS, aX as SandboxChannelAService, aY as SandboxChannelAServiceOptions, aZ as SandboxConfigError, a_ as SandboxCreatedCallback, a$ as SandboxExecReadinessError, b0 as SandboxProviderUnavailableError, b1 as SandboxReplacementProviderStateError, b2 as SandboxResumeStateUnavailableError, b3 as SelfhostedApplyDiff, b4 as SelfhostedControlError, b5 as SelfhostedEditor, b6 as SelfhostedEnrollment, b7 as SelfhostedExecArgs, b8 as SelfhostedExecResult, b9 as SelfhostedImageOutput, ba as SelfhostedLivenessState, bb as SelfhostedNegotiationInput, bc as SelfhostedOpObservation, bd as SelfhostedOpObserver, be as SelfhostedOpStreamDeps, bf as SelfhostedRelayConfig, bg as SelfhostedRetryClock, bh as SelfhostedRetryDecision, bi as SelfhostedSandboxClient, bj as SelfhostedSession, bk as SelfhostedSessionBuild, bl as SelfhostedSessionDeps, bm as SelfhostedSessionState, bn as SelfhostedUnavailableReason, bo as StartRecordingInput, bp as StreamPortUnavailableError, bq as SwapTargetEstablishability, br as TERMINAL_SERVER_TIMEOUT_MS, bs as TerminalServerError, bt as TerminalServerUnsupportedError, bu as ToolspaceTokenPathError, bv as VerifiedWorkspaceArchive, bw as WORKSPACE_ARCHIVE_DESCRIPTOR_VERSION, bx as WorkspaceArchiveDescriptor, by as WorkspaceArchiveIntegrityCode, bz as WorkspaceArchiveIntegrityError, bA as WorkspaceTreeFingerprint, bB as agentErrorToControlError, bC as assertDescriptorRegistryInvariants, bD as assertProviderRegistryInvariants, bE as assertSafeRelPath, bF as backendSupportsOs, bG as buildDisplayStackScript, bH as buildSelfhostedBackendSession, bI as buildStreamUrl, bJ as buildTerminalServerScript, bK as captureVerifiedWorkspaceArchive, bL as classifyProviderSandboxFailure, bM as clearRunCredentials, bN as clearRunCredentialsForAttempt, bO as contentTypeForCodec, bP as createSandboxClient, bQ as createSandboxClientForBackend, bR as decideSelfhostedRetry, bS as decodeModalSnapshotId, bT as defaultSelfhostedRetryClock, bU as deletePriorPersistedSnapshot, bV as deleteRecordingArtifacts, bW as deserializeSandboxSessionStateEnvelope, bX as desktopCapableBackend, bY as drainingExhaustedError, bZ as drainingMessage, b_ as ensureDisplayStack, b$ as ensureModalRegistryImage, c0 as ensureTerminalServer, c1 as establishSandboxSessionFromEnvelope, c2 as execDeadlineHint, c3 as exposeStreamPort, c4 as extForCodec, c5 as fingerprintSandboxWorkspace, c6 as hasPersistableSandboxProviderIdentity, c7 as inspectRecordingArtifact, c8 as isExecSessionLostBanner, c9 as isProviderSandboxGoneDuringRoutedOperation, ca as isProviderSandboxNotFoundError, cb as isProviderSandboxTransientError, cc as isSelfhostedProviderNotFoundError, cd as makeActiveBackendResolver, ce as materializeRunCredentials, cf as mintStreamToken, cg as modalSandboxAttributionEnvironment, ch as modalSandboxAttributionTags, ci as negotiateCapabilities, cj as negotiateSelfhostedCapabilities, ck as nextDurableOpId, cl as normalizeRunCredentialsResolution, cm as offlineAgentError, cn as offlineControlResponse, co as opAckSubject, cp as opFrameSubject, cq as parseExecBannerExitCode, cr as parseExecBannerSessionId, cs as parseNumstatZ, ct as parsePorcelainV2, cu as parseUnifiedPatch, cv as parseWorkspaceArchiveDescriptor, cw as payloadTooLargeMessage, cx as readVerifiedWorkspaceArchive, cy as readWorkspaceArchiveFromEnvelopeSessionState, cz as recordingStorageKey, cA as renderSelfhostedFault, cB as requirePersistableReplacementSandboxEnvelope, cC as restoredSandboxSessionStateFromEntry, cD as runCredentialPointerFile, cE as runCredentialRoot, cF as runWithToolCallCorrelation, cG as sandboxStateEntryFromRunState, cH as sanitizeOpIdToken, cI as selectBackend, cJ as selfhostedFaultClass, cK as selfhostedLiveness, cL as selfhostedRetryBackoffMs, cM as serializeEstablishedSandboxEnvelope, cN as serializeReplacementSandboxEnvelope, cO as setSelfhostedApplyDiff, cP as startRecording, cQ as stopRecording, cR as stripExecBanner, cS as subjectFor, cT as swapTargetEstablishability, cU as sweepModalOrphanSandboxes, cV as tagModalSandbox, cW as tearDownDisplayStack, cX as tearDownTerminalServer, cY as terminateModalSandboxById, cZ as timeoutAgentError, c_ as timeoutControlResponse, c$ as toolspaceTokenFileForSession, d0 as toolspaceTokenFileFromEnvironment, d1 as uploadRecordingArtifact, d2 as verifyRestoredWorkspace, d3 as verifySandboxExecReadiness, d4 as verifyStreamToken, d5 as withRunCredentialEnvironment, d6 as withRunCredentialsClient, d7 as withRunCredentialsSession, d8 as withToolspaceTokenClient, d9 as withToolspaceTokenEnvironment, da as withToolspaceTokenSession } from '../index-Ciehex_q.js';
5
5
  import 'modal';
6
6
  import '@opengeni/agent-proto';
@@ -170,7 +170,7 @@ import {
170
170
  withToolspaceTokenClient,
171
171
  withToolspaceTokenEnvironment,
172
172
  withToolspaceTokenSession
173
- } from "../chunk-JGUQSAG5.js";
173
+ } from "../chunk-RHB7ETON.js";
174
174
  import "../chunk-4YJ5Z52Z.js";
175
175
  import "../chunk-K4V4QYCL.js";
176
176
  import "../chunk-PZ5AY32C.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/runtime",
3
- "version": "0.13.3",
3
+ "version": "0.13.10",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,8 +50,8 @@
50
50
  "@openai/agents-extensions": "0.13.3",
51
51
  "@opengeni/agent-proto": "^0.3.0",
52
52
  "@opengeni/codex": "^0.2.7",
53
- "@opengeni/config": "^0.7.0",
54
- "@opengeni/contracts": "^0.19.0",
53
+ "@opengeni/config": "^0.7.6",
54
+ "@opengeni/contracts": "^0.19.4",
55
55
  "@opengeni/network": "^0.1.1",
56
56
  "debug": "4.4.3",
57
57
  "modal": "0.7.6",
@@ -438,7 +438,7 @@ component "vpc" {
438
438
 
439
439
  # Incorrect (absolute paths don't work)
440
440
  component "vpc" {
441
- source = "/Users/username/project/modules/vpc"
441
+ source = "/path/to/project/modules/vpc"
442
442
  }
443
443
  ```
444
444
 
@@ -1,14 +1,14 @@
1
- // Progressive connector disclosure for the ChatGPT/Codex backend — parity with
2
- // how the Codex CLI surfaces its ~217 `codex_apps` connector tools WITHOUT paying
3
- // their schemas in every turn's context.
1
+ // Progressive MCP disclosure for the ChatGPT/Codex backend — parity with how the
2
+ // Codex CLI surfaces its ~217 `codex_apps` connector tools WITHOUT paying their
3
+ // schemas in every turn's context, while applying the same bounded search seam to
4
+ // other selected MCP servers.
4
5
  //
5
- // WHY. OpenGeni connects the codex_apps MCP server as a CLIENT and the SDK
6
- // materializes EVERY connector tool as a `function` tool in request.tools[] on
7
- // every codex turn (~217 tools ≈ tens of thousands of context tokens). The Codex
8
- // CLI instead uses the backend's NATIVE tool-search: the model gets one compact
9
- // search tool + all connector tools flagged `defer_loading:true` (schemas dropped
10
- // from model context), searches by capability, and only the matched tools are
11
- // disclosed back and become callable.
6
+ // WHY. OpenGeni connects MCP servers as CLIENTs and the SDK materializes every
7
+ // selected MCP tool as a `function` tool in request.tools[] on a Codex turn. The
8
+ // Codex CLI instead uses the backend's NATIVE tool-search: the model gets one
9
+ // compact search tool + deferred MCP tools (schemas dropped from model context),
10
+ // searches by capability, and only matched tools are disclosed back and become
11
+ // callable.
12
12
  //
13
13
  // PROVEN LIVE (Phase 0 probe against /codex/responses on gpt-5.6-sol): the backend
14
14
  // HONORS `defer_loading:true` on function tools — 50 fat tools dropped input_tokens
@@ -16,19 +16,22 @@
16
16
  // disclosed it (V3). The model emits `tool_search_call` on our slug.
17
17
  //
18
18
  // HOW. We wrap the agent's `getAllTools` (codex turns only, flag-gated): tag every
19
- // `codex_apps__*` function tool `deferLoading = true` (converTool then serializes
19
+ // non-mandatory MCP function tool `deferLoading = true` (converTool then serializes
20
20
  // `defer_loading:true`, dropping the schema from context) and append one
21
21
  // client-executed `toolSearchTool`. The SDK routes a `tool_search_call` to our
22
22
  // executor (ClientToolSearchExecutor), which BM25-ranks the deferred pool and
23
- // returns the matched tools BY REFERENCE — the SDK emits the `tool_search_output`
24
- // that discloses them; the subsequent `function_call` resolves through the normal
25
- // PrefixedMcpServer.callTool path (auth + name-sanitize + structuredContent inline
26
- // all unchanged). Invocation is untouched; only the wire tool-set shrinks.
23
+ // returns matched tools BY REFERENCE — the SDK emits the `tool_search_output` that
24
+ // discloses them; the subsequent `function_call` resolves through the normal
25
+ // `PrefixedMcpServer.callTool` path (auth + name-sanitize + structuredContent
26
+ // inline all unchanged). Invocation is untouched; only the wire tool-set shrinks.
27
27
 
28
28
  import { toolSearchTool, type Tool } from "@openai/agents";
29
29
  import {
30
30
  MCP_MAX_TOOL_DEFINITION_BYTES,
31
+ MCP_MAX_TOOL_SEARCH_DESCRIPTION_BYTES,
31
32
  MCP_MAX_TOOL_SEARCH_DISCLOSURE_BYTES,
33
+ MCP_MAX_TOOL_SEARCH_SOURCE_LABEL_LENGTH,
34
+ MCP_MAX_TOOL_SEARCH_SOURCES,
32
35
  mcpSerializedSizeBytes,
33
36
  } from "./mcp-network";
34
37
 
@@ -50,6 +53,91 @@ export function isCodexAppsFunctionTool(
50
53
  );
51
54
  }
52
55
 
56
+ const MCP_TOOL_NAME_SEPARATOR = "__";
57
+ const MANDATORY_FIRST_PARTY_MCP_SERVER_ID = "opengeni";
58
+ const NO_MCP_SERVER_IDS: ReadonlySet<string> = new Set();
59
+
60
+ /** Return the authorized server id for a runtime MCP function tool name. */
61
+ function mcpServerIdForTool(tool: unknown, mcpServerIds: ReadonlySet<string>): string | null {
62
+ if (!tool || typeof tool !== "object") return null;
63
+ if ((tool as { type?: unknown }).type !== "function") return null;
64
+ const name = (tool as { name?: unknown }).name;
65
+ if (typeof name !== "string") return null;
66
+ let match: string | null = null;
67
+ for (const serverId of mcpServerIds) {
68
+ if (
69
+ typeof serverId !== "string" ||
70
+ serverId.length === 0 ||
71
+ !name.startsWith(`${serverId}${MCP_TOOL_NAME_SEPARATOR}`)
72
+ ) {
73
+ continue;
74
+ }
75
+ if (match === null || serverId.length > match.length) {
76
+ match = serverId;
77
+ }
78
+ }
79
+ return match;
80
+ }
81
+
82
+ /**
83
+ * True for non-mandatory MCP function tools on the effective agent surface.
84
+ * The prefix is the same runtime namespace used by PrefixedMcpServer; this
85
+ * intentionally does not inspect the global registry, connection metadata, or
86
+ * credentials, so search cannot widen the already-authorized tool set.
87
+ */
88
+ export function isSearchableMcpFunctionTool(
89
+ tool: unknown,
90
+ mcpServerIds: ReadonlySet<string> = NO_MCP_SERVER_IDS,
91
+ ): tool is Tool & { name: string; deferLoading?: boolean } {
92
+ const serverId = mcpServerIdForTool(tool, mcpServerIds);
93
+ return serverId !== null && serverId !== MANDATORY_FIRST_PARTY_MCP_SERVER_ID;
94
+ }
95
+
96
+ function truncateUtf8(value: string, maxBytes: number): string {
97
+ if (Buffer.byteLength(value) <= maxBytes) return value;
98
+ let output = "";
99
+ for (const character of value) {
100
+ const candidate = output + character;
101
+ if (Buffer.byteLength(candidate) > maxBytes) break;
102
+ output = candidate;
103
+ }
104
+ return output;
105
+ }
106
+
107
+ function searchSourceForTool(tool: Tool, mcpServerIds: ReadonlySet<string>): string | null {
108
+ const serverId = mcpServerIdForTool(tool, mcpServerIds);
109
+ return serverId && serverId !== MANDATORY_FIRST_PARTY_MCP_SERVER_ID
110
+ ? truncateUtf8(serverId, MCP_MAX_TOOL_SEARCH_SOURCE_LABEL_LENGTH)
111
+ : null;
112
+ }
113
+
114
+ function searchSourcesForTools(
115
+ connectorNamespaces: ReadonlySet<string>,
116
+ tools: readonly Tool[],
117
+ mcpServerIds: ReadonlySet<string>,
118
+ ): Set<string> {
119
+ const sources = new Set<string>();
120
+ for (const source of connectorNamespaces) {
121
+ if (typeof source !== "string" || source.length === 0) continue;
122
+ if (sources.size >= MCP_MAX_TOOL_SEARCH_SOURCES) break;
123
+ sources.add(truncateUtf8(source, MCP_MAX_TOOL_SEARCH_SOURCE_LABEL_LENGTH));
124
+ }
125
+ for (const tool of tools) {
126
+ // Codex connector labels come from the transport's original namespace set
127
+ // (for example, `gmail`), not from the synthetic `codex_apps__` prefix.
128
+ // Keep that authoritative path intact; derive fallback labels only for
129
+ // directly materialized non-Codex MCP tools such as selected Slack tools.
130
+ const source =
131
+ isSearchableMcpFunctionTool(tool, mcpServerIds) && !isCodexAppsFunctionTool(tool)
132
+ ? searchSourceForTool(tool, mcpServerIds)
133
+ : null;
134
+ if (!source || sources.has(source)) continue;
135
+ if (sources.size >= MCP_MAX_TOOL_SEARCH_SOURCES) break;
136
+ sources.add(source);
137
+ }
138
+ return sources;
139
+ }
140
+
53
141
  // Minimal English stopword set: query phrasings like "send an email to someone"
54
142
  // should match on capability words, not drown in glue words (parity with
55
143
  // codex-rs, whose search normalizes tokens server-side).
@@ -211,11 +299,23 @@ export function renderSearchToolDescription(connectorNamespaces: ReadonlySet<str
211
299
  "rather than guessing exact tool names. Returns the matching connector tools, which then become callable.";
212
300
  const sources = Array.from(connectorNamespaces)
213
301
  .filter((n) => typeof n === "string" && n.length > 0)
302
+ .slice(0, MCP_MAX_TOOL_SEARCH_SOURCES)
303
+ .map((source) => truncateUtf8(source, MCP_MAX_TOOL_SEARCH_SOURCE_LABEL_LENGTH))
304
+ .filter(Boolean)
214
305
  .sort();
215
306
  if (sources.length === 0) {
216
307
  return `${base}\nConnected sources: none currently available.`;
217
308
  }
218
- return `${base}\nYou have access to tools from the following sources:\n${sources.map((s) => `- ${s}`).join("\n")}`;
309
+ const header = `${base}\nYou have access to tools from the following sources:`;
310
+ const lines: string[] = [];
311
+ for (const source of sources) {
312
+ const candidate = `${header}${[...lines, `- ${source}`].map((line) => `\n${line}`).join("")}`;
313
+ if (Buffer.byteLength(candidate) > MCP_MAX_TOOL_SEARCH_DESCRIPTION_BYTES) break;
314
+ lines.push(`- ${source}`);
315
+ }
316
+ return lines.length > 0
317
+ ? `${header}\n${lines.join("\n")}`
318
+ : `${base}\nConnected sources: none currently available.`;
219
319
  }
220
320
 
221
321
  const SEARCH_TOOL_PARAMETERS = {
@@ -232,16 +332,21 @@ const SEARCH_TOOL_PARAMETERS = {
232
332
  } as const;
233
333
 
234
334
  /**
235
- * The client tool-search executor: BM25 over the deferred codex_apps pool from the
335
+ * The client tool-search executor: BM25 over the deferred MCP pool from the
236
336
  * turn's live `availableTools`, returning matched tools BY REFERENCE (the only legal
237
337
  * return — the SDK emits the disclosing `tool_search_output` and flips the loaded
238
338
  * gate; returning copies would throw). Stateless — reads the pool per call.
239
339
  */
240
- function codexToolSearchExecutor(args: {
241
- availableTools?: Tool[];
242
- toolCall?: { arguments?: unknown };
243
- }): Tool[] {
244
- const deferred = (args.availableTools ?? []).filter(isCodexAppsFunctionTool);
340
+ function codexToolSearchExecutor(
341
+ args: {
342
+ availableTools?: Tool[];
343
+ toolCall?: { arguments?: unknown };
344
+ },
345
+ mcpServerIds: ReadonlySet<string>,
346
+ ): Tool[] {
347
+ const deferred = (args.availableTools ?? []).filter((tool) =>
348
+ isSearchableMcpFunctionTool(tool, mcpServerIds),
349
+ );
245
350
  if (deferred.length === 0) return [];
246
351
  const { query, limit } = parseSearchArgs(args.toolCall?.arguments);
247
352
  const ranked = bm25RankTools(deferred, query, limit);
@@ -320,20 +425,28 @@ function resolveSearchToolDescription(
320
425
  }
321
426
 
322
427
  /** Build the client-executed tool_search tool from an already-rendered description. */
323
- function buildCodexToolSearchToolFromDescription(description: string): Tool {
428
+ function buildCodexToolSearchToolFromDescription(
429
+ description: string,
430
+ mcpServerIds: ReadonlySet<string>,
431
+ ): Tool {
324
432
  return toolSearchTool({
325
433
  execution: "client",
326
434
  description,
327
435
  parameters: SEARCH_TOOL_PARAMETERS as unknown as Record<string, unknown>,
328
- execute: codexToolSearchExecutor as never,
436
+ execute: ((args: Parameters<typeof codexToolSearchExecutor>[0]) =>
437
+ codexToolSearchExecutor(args, mcpServerIds)) as never,
329
438
  }) as unknown as Tool;
330
439
  }
331
440
 
332
- /** Build the client-executed tool_search tool that discloses codex_apps connectors on demand. */
441
+ /** Build the client-executed tool_search tool that discloses deferred MCP tools on demand. */
333
442
  export function buildCodexToolSearchTool(
334
443
  connectorNamespaces: ReadonlySet<string> = NO_NAMESPACES,
444
+ mcpServerIds: ReadonlySet<string> = NO_MCP_SERVER_IDS,
335
445
  ): Tool {
336
- return buildCodexToolSearchToolFromDescription(renderSearchToolDescription(connectorNamespaces));
446
+ return buildCodexToolSearchToolFromDescription(
447
+ renderSearchToolDescription(connectorNamespaces),
448
+ mcpServerIds,
449
+ );
337
450
  }
338
451
 
339
452
  /** True for the built-in tool_search tool (so we never add a second one). */
@@ -343,15 +456,15 @@ function isToolSearchTool(tool: unknown): boolean {
343
456
  }
344
457
 
345
458
  /**
346
- * The transform applied to a turn's resolved tool list: tag every codex_apps
347
- * connector function tool `deferLoading = true`, and — unless one is already
459
+ * The transform applied to a turn's resolved tool list: tag every searchable
460
+ * non-mandatory MCP function tool `deferLoading = true`, and — unless one is already
348
461
  * present — append the client tool_search tool. Pure (mutates the passed tools +
349
462
  * returns the possibly-extended array); the SDK's `getTools` gate requires a
350
463
  * tool_search whenever a deferred tool is present, which appending here satisfies
351
464
  * in the same request.
352
465
  *
353
466
  * The search tool is appended UNCONDITIONALLY (even when the turn has no
354
- * codex_apps tools, e.g. the best-effort codex_apps connect was dropped this
467
+ * searchable MCP tools, e.g. a best-effort connector was dropped this
355
468
  * turn): a prior turn's history may carry tool_search_call/output items, and
356
469
  * replaying those without a tool_search tool in the request risks a backend
357
470
  * reject; a search over an empty pool simply discloses nothing. The description
@@ -362,10 +475,11 @@ export function applyCodexToolSearch(
362
475
  tools: Tool[],
363
476
  connectorNamespaces: ReadonlySet<string> = NO_NAMESPACES,
364
477
  descriptionFreeze?: CodexToolSearchDescriptionFreeze,
478
+ mcpServerIds: ReadonlySet<string> = NO_MCP_SERVER_IDS,
365
479
  ): Tool[] {
366
480
  for (const tool of tools) {
367
481
  if (
368
- isCodexAppsFunctionTool(tool) &&
482
+ isSearchableMcpFunctionTool(tool, mcpServerIds) &&
369
483
  (tool as { deferLoading?: boolean }).deferLoading !== true
370
484
  ) {
371
485
  (tool as { deferLoading?: boolean }).deferLoading = true;
@@ -376,8 +490,11 @@ export function applyCodexToolSearch(
376
490
  }
377
491
  // AM-8: render through the per-turn freeze so the tools-block prefix stays
378
492
  // byte-stable across a turn's model calls once connectors are discovered.
379
- const description = resolveSearchToolDescription(connectorNamespaces, descriptionFreeze);
380
- return [...tools, buildCodexToolSearchToolFromDescription(description)];
493
+ const description = resolveSearchToolDescription(
494
+ searchSourcesForTools(connectorNamespaces, tools, mcpServerIds),
495
+ descriptionFreeze,
496
+ );
497
+ return [...tools, buildCodexToolSearchToolFromDescription(description, mcpServerIds)];
381
498
  }
382
499
 
383
500
  type CloneCapableAgent = {
@@ -386,11 +503,11 @@ type CloneCapableAgent = {
386
503
  };
387
504
 
388
505
  /**
389
- * Install progressive connector disclosure on a codex-path agent by wrapping
506
+ * Install progressive MCP disclosure on a Codex-path agent by wrapping
390
507
  * `getAllTools` so every per-model-call tool resolution runs
391
508
  * {@link applyCodexToolSearch}. Idempotent-per-call (re-tags each
392
509
  * freshly-materialized MCP tool under cacheToolsList:false). Gated by the caller
393
- * (flag + codex path).
510
+ * (flag + Codex path).
394
511
  *
395
512
  * CLONE SURVIVAL (the part that makes this work on the REAL sandbox path): the
396
513
  * SDK's sandbox runtime routes EVERY model call through
@@ -408,17 +525,19 @@ type CloneCapableAgent = {
408
525
  export function installCodexToolSearch(
409
526
  agent: CloneCapableAgent,
410
527
  connectorNamespaces: ReadonlySet<string> = NO_NAMESPACES,
528
+ mcpServerIds: ReadonlySet<string> = NO_MCP_SERVER_IDS,
411
529
  ): void {
412
530
  // ONE freeze cell per install (i.e. per turn), shared BY REFERENCE into every
413
531
  // clone re-install below so the whole turn — the built agent and every clone the
414
532
  // sandbox runtime resolves tools on — agrees on the same frozen description
415
533
  // (AM-8). Created here, at the top-level install, never per clone.
416
- installCodexToolSearchWithFreeze(agent, connectorNamespaces, { value: null });
534
+ installCodexToolSearchWithFreeze(agent, connectorNamespaces, mcpServerIds, { value: null });
417
535
  }
418
536
 
419
537
  function installCodexToolSearchWithFreeze(
420
538
  agent: CloneCapableAgent,
421
539
  connectorNamespaces: ReadonlySet<string>,
540
+ mcpServerIds: ReadonlySet<string>,
422
541
  descriptionFreeze: CodexToolSearchDescriptionFreeze,
423
542
  ): void {
424
543
  const originalGetAllTools = agent.getAllTools.bind(agent);
@@ -427,12 +546,18 @@ function installCodexToolSearchWithFreeze(
427
546
  await originalGetAllTools(runContext),
428
547
  connectorNamespaces,
429
548
  descriptionFreeze,
549
+ mcpServerIds,
430
550
  )) as typeof agent.getAllTools;
431
551
  const originalClone = agent.clone?.bind(agent);
432
552
  if (originalClone) {
433
553
  const cloneWithToolSearch: NonNullable<CloneCapableAgent["clone"]> = (config: unknown) => {
434
554
  const cloned = originalClone(config);
435
- installCodexToolSearchWithFreeze(cloned, connectorNamespaces, descriptionFreeze);
555
+ installCodexToolSearchWithFreeze(
556
+ cloned,
557
+ connectorNamespaces,
558
+ mcpServerIds,
559
+ descriptionFreeze,
560
+ );
436
561
  return cloned;
437
562
  };
438
563
  agent.clone = cloneWithToolSearch;