@opengeni/runtime 0.2.3 → 0.3.1

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/index.d.ts CHANGED
@@ -7,7 +7,9 @@ import { ReasoningEffort, SessionEventType, ResourceRef, ToolRef, Permission } f
7
7
  export { CAPABILITY_DESCRIPTORS, CapabilityDescriptor, DESKTOP_STREAM_PORT, StreamTokenPayload, StreamTokenPayload as StreamTokenPayloadType, TERMINAL_STREAM_PORT } from '@opengeni/contracts';
8
8
  import { Capability, SandboxSessionLike, SandboxSessionState, Manifest, Capabilities, LocalDirLazySkillSource, SandboxClient } from '@openai/agents/sandbox';
9
9
  import OpenAI from 'openai';
10
- export { ActiveBackendResolverDeps, ActiveBackendUnresolvableError, ActivePointer, ChannelAConflictError, ChannelAEmitter, ChannelAExecArgs, ChannelAExecResult, ChannelANotFoundError, ChannelASession, ChannelAUnsupportedError, ChannelAValidationError, ControlRpc, DEFAULT_DESKTOP_GEOMETRY, DISPLAY_STACK_TIMEOUT_MS, DesktopGeometry, DisplayStackError, DisplayStackUnsupportedError, EnsureDisplayStackOptions, EnsureDisplayStackResult, EnsureTerminalServerOptions, EnsureTerminalServerResult, EstablishedSandboxSession, ExposeStreamPortInput, ExposeStreamPortResult, ExposedPortEndpoint, FinalizeRecordingResult, MintStreamTokenInput, MockAgentResponder, MockAgentResponderOptions, MockExecHandler, NatsControlRpc, NatsRequestConnection, NegotiationContext, NumstatEntry, PROVIDER_REGISTRY, ProviderConstructionContext, ProviderRegistration, RecordingCodec, RecordingContentType, RecordingError, RecordingProcess, RecordingUnavailableError, ResolvedActiveBackend, RoutableBackendSession, RoutableSandbox, RoutingSandboxSession, RoutingSandboxSessionDeps, RoutingTransitionEvent, RoutingUnsupportedError, SELFHOSTED_DEFAULT_TIMEOUT_MS, SELFHOSTED_RECONNECT_WINDOW_MS, SELFHOSTED_RELAY_STREAM_PATH, STREAM_PORT, STREAM_TOKEN_DEFAULT_TTL_SECONDS, SandboxChannelAService, SandboxChannelAServiceOptions, SandboxConfigError, SandboxProviderUnavailableError, SelfhostedApplyDiff, SelfhostedControlError, SelfhostedEditor, SelfhostedEnrollment, SelfhostedExecArgs, SelfhostedExecResult, SelfhostedImageOutput, SelfhostedLivenessState, SelfhostedNegotiationInput, SelfhostedRelayConfig, SelfhostedSandboxClient, SelfhostedSession, SelfhostedSessionBuild, SelfhostedSessionDeps, SelfhostedSessionState, SelfhostedUnavailableReason, StartRecordingInput, StreamPortUnavailableError, TERMINAL_SERVER_TIMEOUT_MS, TerminalServerError, TerminalServerUnsupportedError, agentErrorToControlError, assertDescriptorRegistryInvariants, assertProviderRegistryInvariants, assertSafeRelPath, backendSupportsOs, buildDisplayStackScript, buildSelfhostedBackendSession, buildStreamUrl, buildTerminalServerScript, contentTypeForCodec, createSandboxClient, createSandboxClientForBackend, decodeModalSnapshotId, deletePriorPersistedSnapshot, deleteRecordingArtifacts, deserializeSandboxSessionStateEnvelope, desktopCapableBackend, ensureDisplayStack, ensureTerminalServer, establishSandboxSessionFromEnvelope, exposeStreamPort, extForCodec, isExecSessionLostBanner, isProviderSandboxNotFoundError, isSelfhostedProviderNotFoundError, isWorkspaceEscapeError, makeActiveBackendResolver, mintStreamToken, negotiateCapabilities, negotiateSelfhostedCapabilities, offlineAgentError, offlineControlResponse, parseExecBannerSessionId, parseNumstatZ, parsePorcelainV2, parseUnifiedPatch, readRecordingBytes, readWorkspaceArchiveFromEnvelopeSessionState, recordingStorageKey, restoredSandboxSessionStateFromEntry, sandboxStateEntryFromRunState, selectBackend, selfhostedLiveness, serializeEstablishedSandboxEnvelope, setSelfhostedApplyDiff, startRecording, stopRecording, stripExecBanner, subjectFor, tearDownDisplayStack, tearDownTerminalServer, timeoutAgentError, timeoutControlResponse, verifyStreamToken } from './sandbox/index.js';
10
+ import { R as RuntimeMetricsHooks } from './index-CSGkld-v.js';
11
+ export { A as ActiveBackendResolverDeps, a as ActiveBackendUnresolvableError, b as ActivePointer, C as ChannelAConflictError, c as ChannelAEmitter, d as ChannelAExecArgs, e as ChannelAExecResult, f as ChannelANotFoundError, g as ChannelASession, h as ChannelAUnsupportedError, i as ChannelAValidationError, j as ControlRpc, D as DEFAULT_DESKTOP_GEOMETRY, k as DISPLAY_STACK_TIMEOUT_MS, l as DesktopGeometry, m as DisplayStackError, n as DisplayStackUnsupportedError, E as EnsureDisplayStackOptions, o as EnsureDisplayStackResult, p as EnsureTerminalServerOptions, q as EnsureTerminalServerResult, r as EstablishedSandboxSession, s as ExposeStreamPortInput, t as ExposeStreamPortResult, u as ExposedPortEndpoint, F as FinalizeRecordingResult, L as LiveModalSandboxLeaseAttribution, M as MintStreamTokenInput, v as MockAgentResponder, w as MockAgentResponderOptions, x as MockExecHandler, y as ModalOrphanSweepResult, z as ModalSandboxAttribution, N as NatsControlRpc, B as NatsRequestConnection, G as NegotiationContext, H as NumstatEntry, P as PROVIDER_REGISTRY, I as ProviderConstructionContext, J as ProviderRegistration, K as RecordingCodec, O as RecordingContentType, Q as RecordingError, S as RecordingProcess, T as RecordingUnavailableError, U as ResolvedActiveBackend, V as RoutableBackendSession, W as RoutableSandbox, X as RoutingSandboxSession, Y as RoutingSandboxSessionDeps, Z as RoutingTransitionEvent, _ as RoutingUnsupportedError, $ as SELFHOSTED_DEFAULT_TIMEOUT_MS, a0 as SELFHOSTED_RECONNECT_WINDOW_MS, a1 as SELFHOSTED_RELAY_STREAM_PATH, a2 as STREAM_PORT, a3 as STREAM_TOKEN_DEFAULT_TTL_SECONDS, a4 as SandboxChannelAService, a5 as SandboxChannelAServiceOptions, a6 as SandboxConfigError, a7 as SandboxCreatedCallback, a8 as SandboxProviderUnavailableError, a9 as SelfhostedApplyDiff, aa as SelfhostedControlError, ab as SelfhostedEditor, ac as SelfhostedEnrollment, ad as SelfhostedExecArgs, ae as SelfhostedExecResult, af as SelfhostedImageOutput, ag as SelfhostedLivenessState, ah as SelfhostedNegotiationInput, ai as SelfhostedRelayConfig, aj as SelfhostedSandboxClient, ak as SelfhostedSession, al as SelfhostedSessionBuild, am as SelfhostedSessionDeps, an as SelfhostedSessionState, ao as SelfhostedUnavailableReason, ap as StartRecordingInput, aq as StreamPortUnavailableError, ar as TERMINAL_SERVER_TIMEOUT_MS, as as TerminalServerError, at as TerminalServerUnsupportedError, au as agentErrorToControlError, av as assertDescriptorRegistryInvariants, aw as assertProviderRegistryInvariants, ax as assertSafeRelPath, ay as backendSupportsOs, az as buildDisplayStackScript, aA as buildSelfhostedBackendSession, aB as buildStreamUrl, aC as buildTerminalServerScript, aD as contentTypeForCodec, aE as createSandboxClient, aF as createSandboxClientForBackend, aG as decodeModalSnapshotId, aH as deletePriorPersistedSnapshot, aI as deleteRecordingArtifacts, aJ as deserializeSandboxSessionStateEnvelope, aK as desktopCapableBackend, aL as ensureDisplayStack, aM as ensureTerminalServer, aN as establishSandboxSessionFromEnvelope, aO as exposeStreamPort, aP as extForCodec, aQ as isExecSessionLostBanner, aR as isProviderSandboxNotFoundError, aS as isSelfhostedProviderNotFoundError, aT as isWorkspaceEscapeError, aU as makeActiveBackendResolver, aV as mintStreamToken, aW as modalSandboxAttributionEnvironment, aX as modalSandboxAttributionTags, aY as negotiateCapabilities, aZ as negotiateSelfhostedCapabilities, a_ as offlineAgentError, a$ as offlineControlResponse, b0 as parseExecBannerSessionId, b1 as parseNumstatZ, b2 as parsePorcelainV2, b3 as parseUnifiedPatch, b4 as readRecordingBytes, b5 as readWorkspaceArchiveFromEnvelopeSessionState, b6 as recordingStorageKey, b7 as restoredSandboxSessionStateFromEntry, b8 as sandboxStateEntryFromRunState, b9 as selectBackend, ba as selfhostedLiveness, bb as serializeEstablishedSandboxEnvelope, bc as setSelfhostedApplyDiff, bd as startRecording, be as stopRecording, bf as stripExecBanner, bg as subjectFor, bh as sweepModalOrphanSandboxes, bi as tagModalSandbox, bj as tearDownDisplayStack, bk as tearDownTerminalServer, bl as terminateModalSandboxById, bm as timeoutAgentError, bn as timeoutControlResponse, bo as verifyStreamToken } from './index-CSGkld-v.js';
12
+ import 'modal';
11
13
  import '@opengeni/agent-proto';
12
14
 
13
15
  type ComputerButton = "left" | "right" | "wheel" | "back" | "forward";
@@ -64,6 +66,7 @@ declare class SandboxComputer implements Computer {
64
66
  private guardWrite;
65
67
  private shq;
66
68
  screenshot(): Promise<string>;
69
+ private readCmdRaw;
67
70
  private readScreenshotBytes;
68
71
  click(xp: number, yp: number, button: ComputerButton): Promise<void>;
69
72
  doubleClick(xp: number, yp: number): Promise<void>;
@@ -433,6 +436,7 @@ type SandboxFileDownload = {
433
436
  expiresAt?: Date | string;
434
437
  sizeBytes?: number;
435
438
  };
439
+ declare function configureRuntimeMetricsHooks(hooks: RuntimeMetricsHooks | null | undefined): void;
436
440
  type OpenGeniRuntime = {
437
441
  configure: (settings: Settings) => void;
438
442
  resolveTurnModel: (settings: Settings, modelId: string) => ReturnType<typeof resolveTurnModel>;
@@ -445,6 +449,7 @@ type OpenGeniRuntime = {
445
449
  type ProductionRuntimeOverrides = {
446
450
  model?: Model;
447
451
  sandboxClient?: unknown;
452
+ metrics?: RuntimeMetricsHooks;
448
453
  };
449
454
  declare function createProductionAgentRuntime(overrides?: ProductionRuntimeOverrides): OpenGeniRuntime;
450
455
  /**
@@ -454,7 +459,7 @@ declare function createProductionAgentRuntime(overrides?: ProductionRuntimeOverr
454
459
  * the OpenAI-platform path has only a key (the SDK default client is used via
455
460
  * setDefaultOpenAIKey there); the caller then constructs a key-only client.
456
461
  */
457
- declare function buildOpenAIClientFromSettings(settings: Settings): OpenAI;
462
+ declare function buildOpenAIClientFromSettings(settings: Settings, providerId?: string): OpenAI;
458
463
  declare function buildProviderClient(provider: ResolvedModelProvider, settings: Settings): OpenAI;
459
464
  /**
460
465
  * Bind a model id to a provider's OpenAI client as an @openai/agents `Model`
@@ -569,6 +574,7 @@ type BuildAgentOptions = {
569
574
  gitTokenSeed?: string;
570
575
  genesisTitleHint?: boolean;
571
576
  instructionsTemplate?: string;
577
+ sessionInstructions?: string;
572
578
  packSkills?: PackSkill[];
573
579
  };
574
580
  type PackSkillFile = {
@@ -615,6 +621,20 @@ declare function coreInstructions(workspaceEnvironment?: WorkspaceEnvironmentCon
615
621
  * with an empty environment reproduces the historical preamble byte-for-byte.
616
622
  */
617
623
  declare function composeAgentInstructions(template: string, workspaceEnvironment?: WorkspaceEnvironmentContext): string;
624
+ /**
625
+ * Appends the per-session persona instructions to the already-composed
626
+ * (workspace + CORE) instructions, joined by " " — exactly the join used
627
+ * throughout the persona composition. The session slice is intentionally LAST
628
+ * (session-specific refinement of the workspace persona). An absent/blank value
629
+ * is a no-op that returns the composed string byte-for-byte.
630
+ */
631
+ declare function appendSessionInstructions(composed: string, sessionInstructions?: string): string;
632
+ /**
633
+ * Appends the one-shot genesis title directive (genesis turn only), joined by
634
+ * " " and always LAST so a white-label persona template or a per-session
635
+ * instruction can't drop it. A no-op when the hint is absent.
636
+ */
637
+ declare function appendGenesisTitleDirective(instructions: string, genesisTitleHint?: boolean): string;
618
638
  declare function buildOpenGeniAgent(settings: Settings, resources: ResourceRef[], options?: BuildAgentOptions): Agent<any, any>;
619
639
  /**
620
640
  * Build the SandboxAgent capability set provider-aware.
@@ -845,4 +865,4 @@ declare function azureOpenAIDefaultQuery(settings: Pick<Settings, "azureOpenaiAp
845
865
  */
846
866
  declare function lazySkillSourceWithPackSkills(packSkills: PackSkill[]): LocalDirLazySkillSource;
847
867
 
848
- export { type AgentSegmentInput, type BuildAgentOptions, CLIENT_COMPACTION_TRIGGER_FRACTION, COMPACTION_PROMPT, COMPACTION_SUMMARY_MARKER, COMPACT_USER_MESSAGE_MAX_TOKENS, type ClientCompactionDecision, CodexSubscriptionUnavailableError, type CompactionItem, CompactionNeededError, ComputerActionError, ComputerReadOnlyError, type ComputerToolMode, ComputerUnavailableError, type ComputerUseArgs, ComputerUseCapability, type ContextRobustnessFilterOptions, type ElideStaleScreenshotsOptions, type ElideStaleScreenshotsResult, GENESIS_TITLE_DIRECTIVE, type HistoryItem, type ModelResponseUsage, MultiProviderModelProvider, type NormalizedRuntimeEvent, type OpenGeniRuntime, type PackSkill, type PackSkillFile, type PrepareInputOptions, type PrepareToolsOptions, type PreparedAgentInput, type PreparedAgentTools, type ProductionRuntimeOverrides, type RunAgentStreamOptions, SCREENSHOT_OMITTED_PLACEHOLDER, SUMMARY_BUFFER_TOKENS, SUMMARY_PREFIX, SandboxComputer, type SandboxComputerOptions, type SandboxFileDownload, type SandboxLifecycleHook, type SandboxLifecycleHookContext, type SandboxLifecycleHookPhase, USER_MESSAGE_TRUNCATION_MARKER, type WorkspaceEnvironmentContext, agentsErrorRunState, applyMissingManifestEntries, azureCliLoginCommand, azureOpenAIDefaultQuery, buildAgentCapabilities, buildCompactionPromptInput, buildCompactionReplacementHistory, buildManifest, buildModelInstance, buildOpenAIClientFromSettings, buildOpenGeniAgent, buildProviderClient, buildSummaryItem, callModelInputFilterForSettings, clientCompactionThresholdTokens, composeAgentInstructions, computerUse, configureOpenAI, contextRobustnessFilterForSettings, coreInstructions, createProductionAgentRuntime, decideClientCompaction, elideStaleScreenshotImages, enforceInputBudget, ensureReadableStreamFrom, estimateItemTokens, estimateTokens, extractResponseOutputText, findCompactionNeededError, findKeepBoundary, isCompactionSummary, isUserMessage, lazySkillSourceWithPackSkills, materializeSandboxFileDownloads, maxTurnsExceededRunState, modelResponseUsageFromSdkEvent, neutralizeToolSearchItemsInSerializedRunState, normalizeComputerCallsFilter, normalizeSdkEvent, normalizeToolOutputForEvent, prefixedMcpToolName, prepareAgentTools, prepareRunInput, renderCompactionPromptInputForChat, repositoryCloneCommand, repositoryUsesSandboxClone, resolveTurnModel, runAgentStream, runAzureCliLoginHook, runBeforeAgentStartHooks, runRepositoryCloneHook, sandboxCommandExitCode, sandboxCommandOutput, sandboxCommandStillRunning, sandboxFileDownloadsForAgent, sandboxLifecycleHooksForIds, sandboxRunAs, sanitizeHistoryItemsForModel, serializeApprovals, stripProviderItemIdsFilter, stripReasoningEncryptedContent, stripReasoningIdentityFromSerializedRunState, summarizeForCompaction, withManifestRefreshOnResume, withSandboxFileDownloads, withSandboxLifecycleHooks, workspaceEnvironmentInstructions };
868
+ export { type AgentSegmentInput, type BuildAgentOptions, CLIENT_COMPACTION_TRIGGER_FRACTION, COMPACTION_PROMPT, COMPACTION_SUMMARY_MARKER, COMPACT_USER_MESSAGE_MAX_TOKENS, type ClientCompactionDecision, CodexSubscriptionUnavailableError, type CompactionItem, CompactionNeededError, ComputerActionError, ComputerReadOnlyError, type ComputerToolMode, ComputerUnavailableError, type ComputerUseArgs, ComputerUseCapability, type ContextRobustnessFilterOptions, type ElideStaleScreenshotsOptions, type ElideStaleScreenshotsResult, GENESIS_TITLE_DIRECTIVE, type HistoryItem, type ModelResponseUsage, MultiProviderModelProvider, type NormalizedRuntimeEvent, type OpenGeniRuntime, type PackSkill, type PackSkillFile, type PrepareInputOptions, type PrepareToolsOptions, type PreparedAgentInput, type PreparedAgentTools, type ProductionRuntimeOverrides, type RunAgentStreamOptions, RuntimeMetricsHooks, SCREENSHOT_OMITTED_PLACEHOLDER, SUMMARY_BUFFER_TOKENS, SUMMARY_PREFIX, SandboxComputer, type SandboxComputerOptions, type SandboxFileDownload, type SandboxLifecycleHook, type SandboxLifecycleHookContext, type SandboxLifecycleHookPhase, USER_MESSAGE_TRUNCATION_MARKER, type WorkspaceEnvironmentContext, agentsErrorRunState, appendGenesisTitleDirective, appendSessionInstructions, applyMissingManifestEntries, azureCliLoginCommand, azureOpenAIDefaultQuery, buildAgentCapabilities, buildCompactionPromptInput, buildCompactionReplacementHistory, buildManifest, buildModelInstance, buildOpenAIClientFromSettings, buildOpenGeniAgent, buildProviderClient, buildSummaryItem, callModelInputFilterForSettings, clientCompactionThresholdTokens, composeAgentInstructions, computerUse, configureOpenAI, configureRuntimeMetricsHooks, contextRobustnessFilterForSettings, coreInstructions, createProductionAgentRuntime, decideClientCompaction, elideStaleScreenshotImages, enforceInputBudget, ensureReadableStreamFrom, estimateItemTokens, estimateTokens, extractResponseOutputText, findCompactionNeededError, findKeepBoundary, isCompactionSummary, isUserMessage, lazySkillSourceWithPackSkills, materializeSandboxFileDownloads, maxTurnsExceededRunState, modelResponseUsageFromSdkEvent, neutralizeToolSearchItemsInSerializedRunState, normalizeComputerCallsFilter, normalizeSdkEvent, normalizeToolOutputForEvent, prefixedMcpToolName, prepareAgentTools, prepareRunInput, renderCompactionPromptInputForChat, repositoryCloneCommand, repositoryUsesSandboxClone, resolveTurnModel, runAgentStream, runAzureCliLoginHook, runBeforeAgentStartHooks, runRepositoryCloneHook, sandboxCommandExitCode, sandboxCommandOutput, sandboxCommandStillRunning, sandboxFileDownloadsForAgent, sandboxLifecycleHooksForIds, sandboxRunAs, sanitizeHistoryItemsForModel, serializeApprovals, stripProviderItemIdsFilter, stripReasoningEncryptedContent, stripReasoningIdentityFromSerializedRunState, summarizeForCompaction, withManifestRefreshOnResume, withSandboxFileDownloads, withSandboxLifecycleHooks, workspaceEnvironmentInstructions };
package/dist/index.js CHANGED
@@ -63,6 +63,8 @@ import {
63
63
  isWorkspaceEscapeError,
64
64
  makeActiveBackendResolver,
65
65
  mintStreamToken,
66
+ modalSandboxAttributionEnvironment,
67
+ modalSandboxAttributionTags,
66
68
  negotiateCapabilities,
67
69
  negotiateSelfhostedCapabilities,
68
70
  offlineAgentError,
@@ -85,12 +87,15 @@ import {
85
87
  stopRecording,
86
88
  stripExecBanner,
87
89
  subjectFor,
90
+ sweepModalOrphanSandboxes,
91
+ tagModalSandbox,
88
92
  tearDownDisplayStack,
89
93
  tearDownTerminalServer,
94
+ terminateModalSandboxById,
90
95
  timeoutAgentError,
91
96
  timeoutControlResponse,
92
97
  verifyStreamToken
93
- } from "./chunk-KNW7AMQB.js";
98
+ } from "./chunk-HGQ252FL.js";
94
99
 
95
100
  // src/index.ts
96
101
  import { AGENT_INSTRUCTIONS_CORE_PLACEHOLDER, collectSandboxEnvironment as collectSandboxEnvironment2, contextInputBudgetTokens, contextServerCompactThreshold, firstPartyMcpBaseUrl, resolveContextCompactionMode, resolveModelProvider, sandboxLifecycleHookIds } from "@opengeni/config";
@@ -111,6 +116,7 @@ import {
111
116
  setDefaultOpenAIClient,
112
117
  setDefaultOpenAIKey,
113
118
  setOpenAIResponsesTransport,
119
+ setTracingDisabled,
114
120
  webSearchTool,
115
121
  applyDiff
116
122
  } from "@openai/agents";
@@ -140,6 +146,9 @@ import { cpSync, existsSync, mkdirSync, readdirSync, renameSync, rmSync } from "
140
146
  import { dirname, isAbsolute, join, posix as posixPath, relative } from "path";
141
147
  import { fileURLToPath } from "url";
142
148
 
149
+ // src/screenshot-error-card.ts
150
+ var SCREENSHOT_FAILURE_CARD_IMAGE_URL = "data:image/png;base64,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";
151
+
143
152
  // src/history-sanitizer.ts
144
153
  var RESULT_TYPE_BY_CALL_TYPE = {
145
154
  function_call: "function_call_result",
@@ -461,7 +470,6 @@ function rewriteComputerCallsToActionsOnly(body) {
461
470
  }
462
471
  return changed;
463
472
  }
464
- var EMPTY_IMAGE_URL_PLACEHOLDER = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/iZk9HQAAAABJRU5ErkJggg==";
465
473
  function rewriteEmptyComputerCallOutputImageUrls(body) {
466
474
  if (!body || typeof body !== "object") {
467
475
  return false;
@@ -486,7 +494,7 @@ function rewriteEmptyComputerCallOutputImageUrls(body) {
486
494
  const out = output;
487
495
  const imageUrl = out.image_url;
488
496
  if (typeof imageUrl !== "string" || imageUrl.length === 0) {
489
- out.image_url = EMPTY_IMAGE_URL_PLACEHOLDER;
497
+ out.image_url = SCREENSHOT_FAILURE_CARD_IMAGE_URL;
490
498
  changed = true;
491
499
  }
492
500
  }
@@ -1086,6 +1094,7 @@ var SCROLL_NOTCH_PIXELS = 100;
1086
1094
  var SCROLL_MAX_CLICKS = 15;
1087
1095
  var SCREENSHOT_WARMUP_BUDGET_MS = 3e4;
1088
1096
  var SCREENSHOT_RETRY_DELAY_MS = 750;
1097
+ var SCREENSHOT_READ_CHUNK_BYTES = 98304;
1089
1098
  var KEYSYM = {
1090
1099
  ctrl: "ctrl",
1091
1100
  control: "ctrl",
@@ -1126,6 +1135,12 @@ var ComputerUnavailableError = class extends Error {
1126
1135
  this.name = "ComputerUnavailableError";
1127
1136
  }
1128
1137
  };
1138
+ var ScreenshotReadError = class extends Error {
1139
+ constructor(message) {
1140
+ super(message);
1141
+ this.name = "ScreenshotReadError";
1142
+ }
1143
+ };
1129
1144
  var ComputerReadOnlyError = class extends Error {
1130
1145
  constructor() {
1131
1146
  super("computer-use is read-only \u2014 write actions are disabled");
@@ -1229,6 +1244,9 @@ var SandboxComputer = class {
1229
1244
  return Buffer.from(bytes).toString("base64");
1230
1245
  } catch (error) {
1231
1246
  lastError = error;
1247
+ if (error instanceof ScreenshotReadError) {
1248
+ throw error;
1249
+ }
1232
1250
  } finally {
1233
1251
  await this.x(`rm -f ${f}`).catch(() => void 0);
1234
1252
  }
@@ -1241,34 +1259,66 @@ var SandboxComputer = class {
1241
1259
  }
1242
1260
  throw new ComputerUnavailableError("scrot produced an empty screenshot (display not up?)");
1243
1261
  }
1244
- // Read the screenshot PNG bytes by base64-ing the absolute /tmp path through the
1245
- // SAME command primitive (exec ?? execCommand) — NOT `session.readFile` (Modal
1262
+ // Run a read-only command over the SAME command primitive computer actions use
1263
+ // (exec ?? execCommand) and return its RAW stdout body — NOT `session.readFile` (Modal
1246
1264
  // path-validates against /workspace and rejects /tmp) and NOT `this.x()` (its
1247
- // `sandboxCommandOutput` parser drops the execCommand STRING body, returning ""
1248
- // only the exec-object path has a structured body). We capture the RAW result,
1249
- // strip the execCommand banner ("…Output:\n<base64>"), strip whitespace, and
1250
- // decode. Binary-safe: base64 of the scrot is plain ASCII over stdout, no
1251
- // truncation (maxOutputTokens:null), mirroring recording.ts readRecordingBytes.
1252
- async readScreenshotBytes(path) {
1265
+ // `sandboxCommandOutput` parser drops the execCommand STRING body). exec exposes a
1266
+ // structured stdout; execCommand returns the formatted STRING, so we strip its banner
1267
+ // ("…Output:\n<body>") to recover the body.
1268
+ //
1269
+ // ROUTING-PROXY SEAM: when the selfhosted feature is on, the turn's box is wrapped in a
1270
+ // `RoutingSandboxSession`, which ALWAYS exposes an `exec` method — but for a Modal-backed
1271
+ // box (no native `exec`) that method internally falls back to `execCommand` and returns
1272
+ // the formatted STRING, not a `{output}` object. `sandboxCommandOutput` returns "" for a
1273
+ // string, so a naive `sandboxCommandOutput(await session.exec())` silently dropped the
1274
+ // whole screenshot body → empty read → "display not up" error card on EVERY Modal
1275
+ // computer-use turn once routing was enabled. So a STRING exec result is banner-stripped
1276
+ // exactly like the direct execCommand path; only a structured object goes to
1277
+ // sandboxCommandOutput.
1278
+ async readCmdRaw(cmd) {
1253
1279
  const args = {
1254
- cmd: `DISPLAY=${this.display} base64 ${path}`,
1280
+ cmd,
1255
1281
  ...this.runAs ? { runAs: this.runAs } : {},
1256
1282
  yieldTimeMs: ACTION_YIELD_MS,
1257
- // null disables the provider's output truncation so a full-screen PNG's
1258
- // base64 is never clipped (the SDK's truncateOutput passes through on null).
1283
+ // null disables the provider's TOKEN truncation; the byte cap this method chunks
1284
+ // around is a separate, lower-level exec-stdout buffer limit.
1259
1285
  maxOutputTokens: null
1260
1286
  };
1261
- let raw;
1262
1287
  if (typeof this.session.exec === "function") {
1263
- raw = sandboxCommandOutput(await this.session.exec(args));
1264
- } else if (typeof this.session.execCommand === "function") {
1265
- raw = stripExecBanner(await this.session.execCommand(args));
1266
- } else {
1267
- throw new ComputerUnavailableError("session cannot run commands (no exec/execCommand) \u2014 screenshots unavailable");
1288
+ const result = await this.session.exec(args);
1289
+ return typeof result === "string" ? stripExecBanner(result) : sandboxCommandOutput(result);
1268
1290
  }
1269
- const b64 = raw.replace(/\s+/g, "");
1270
- if (b64.length === 0) return new Uint8Array();
1271
- return Uint8Array.from(Buffer.from(b64, "base64"));
1291
+ if (typeof this.session.execCommand === "function") {
1292
+ return stripExecBanner(await this.session.execCommand(args));
1293
+ }
1294
+ throw new ComputerUnavailableError("session cannot run commands (no exec/execCommand) \u2014 screenshots unavailable");
1295
+ }
1296
+ // Read the screenshot PNG bytes off the box. A SINGLE `base64 <file>` over Modal's
1297
+ // exec silently returns "" once the base64 exceeds the exec-stdout buffer cap (a full
1298
+ // desktop ~296 KB base64 trips it — the blank-frame incident). So we size the file
1299
+ // first, then base64 it in SCREENSHOT_READ_CHUNK_BYTES-sized, 3-byte-aligned chunks
1300
+ // (each read's base64 stays well under the cap) and reconstruct — validating the total
1301
+ // against the on-box size and failing LOUD on any short read rather than handing back a
1302
+ // truncated/blank frame. Binary-safe: base64 is plain ASCII over stdout.
1303
+ async readScreenshotBytes(path) {
1304
+ const sizeRaw = (await this.readCmdRaw(`wc -c < ${path} 2>/dev/null`)).replace(/[^0-9]/g, "");
1305
+ const fileSize = Number.parseInt(sizeRaw, 10);
1306
+ if (!Number.isFinite(fileSize) || fileSize <= 0) return new Uint8Array();
1307
+ const chunks = [];
1308
+ const nChunks = Math.ceil(fileSize / SCREENSHOT_READ_CHUNK_BYTES);
1309
+ for (let i = 0; i < nChunks; i++) {
1310
+ const raw = await this.readCmdRaw(
1311
+ `dd if=${path} bs=${SCREENSHOT_READ_CHUNK_BYTES} skip=${i} count=1 2>/dev/null | base64`
1312
+ );
1313
+ chunks.push(Buffer.from(raw.replace(/\s+/g, ""), "base64"));
1314
+ }
1315
+ const bytes = Buffer.concat(chunks);
1316
+ if (bytes.length !== fileSize) {
1317
+ throw new ScreenshotReadError(
1318
+ `screenshot read reconstructed ${bytes.length}B of ${fileSize}B (${nChunks} chunk(s), path=${path}) \u2014 a chunk was truncated by the exec-output cap; frame incomplete`
1319
+ );
1320
+ }
1321
+ return new Uint8Array(bytes);
1272
1322
  }
1273
1323
  async click(xp, yp, button) {
1274
1324
  this.guardWrite();
@@ -1323,16 +1373,35 @@ var POINTER_BUTTON = {
1323
1373
  back: PointerButton.POINTER_BUTTON_UNSPECIFIED,
1324
1374
  forward: PointerButton.POINTER_BUTTON_UNSPECIFIED
1325
1375
  };
1376
+ var NATIVE_SCREENSHOT_WARMUP_BUDGET_MS = 6e3;
1377
+ var NATIVE_SCREENSHOT_RETRY_DELAY_MS = 400;
1378
+ function isTerminalCaptureDenial(error) {
1379
+ const msg = (error instanceof Error ? error.message : String(error ?? "")).toLowerCase();
1380
+ return msg.includes("screen recording") || msg.includes("permission is not granted") || msg.includes("consent");
1381
+ }
1326
1382
  var NativeDesktopComputer = class {
1327
1383
  environment;
1328
1384
  dimensions;
1329
1385
  session;
1330
1386
  readOnly;
1387
+ screenshotWarmupBudgetMs;
1388
+ screenshotRetryDelayMs;
1389
+ // The ENCODED vs NATIVE geometry of the MOST RECENT screenshot the model saw. The
1390
+ // model computes click coordinates in the encoded-pixel space of that screenshot;
1391
+ // when the agent downscaled the PNG to fit the transport budget, encoded < native,
1392
+ // so we scale coordinates back up to native pixels before injecting (the agent's
1393
+ // native inject — macOS CGEvent / Linux XTEST — expects native-pixel coordinates,
1394
+ // exactly as it received them pre-downscale). Null until the first screenshot;
1395
+ // equal encoded==native (or absent) ⇒ scale factor 1.0 ⇒ byte-identical behavior.
1396
+ lastEncoded = null;
1397
+ lastNative = null;
1331
1398
  constructor(session, opts = {}) {
1332
1399
  this.session = session;
1333
1400
  this.dimensions = opts.dimensions ?? DEFAULT_DIMENSIONS;
1334
1401
  this.environment = opts.environment ?? "ubuntu";
1335
1402
  this.readOnly = opts.readOnly ?? false;
1403
+ this.screenshotWarmupBudgetMs = opts.screenshotWarmupBudgetMs ?? NATIVE_SCREENSHOT_WARMUP_BUDGET_MS;
1404
+ this.screenshotRetryDelayMs = opts.screenshotRetryDelayMs ?? NATIVE_SCREENSHOT_RETRY_DELAY_MS;
1336
1405
  }
1337
1406
  /** Rebind to a freshly resumed-by-id session after a box rollover / re-establish. */
1338
1407
  rebind(session) {
@@ -1341,15 +1410,57 @@ var NativeDesktopComputer = class {
1341
1410
  guardWrite() {
1342
1411
  if (this.readOnly) throw new ComputerReadOnlyError();
1343
1412
  }
1413
+ /** Scale a coordinate the model expressed in the MOST RECENT screenshot's
1414
+ * ENCODED pixel space back to NATIVE pixels. When the last frame was not
1415
+ * downscaled (encoded == native), or no screenshot has been taken yet, this is a
1416
+ * 1:1 identity — the byte-identical current behavior. The agent then applies its
1417
+ * own platform mapping (macOS divides native pixels by the backing scale to reach
1418
+ * CGEvent points; Linux XTEST is 1:1) exactly as it did pre-downscale. */
1419
+ toNative(x, y) {
1420
+ const enc = this.lastEncoded;
1421
+ const nat = this.lastNative;
1422
+ if (!enc || !nat || enc[0] <= 0 || enc[1] <= 0) return { x, y };
1423
+ if (enc[0] === nat[0] && enc[1] === nat[1]) return { x, y };
1424
+ return {
1425
+ x: Math.round(x * nat[0] / enc[0]),
1426
+ y: Math.round(y * nat[1] / enc[1])
1427
+ };
1428
+ }
1344
1429
  async pointer(x, y, action, button) {
1345
- await this.session.desktopInput({ $case: "pointer", pointer: { x, y, action, button } });
1430
+ const n = this.toNative(x, y);
1431
+ await this.session.desktopInput({ $case: "pointer", pointer: { x: n.x, y: n.y, action, button } });
1346
1432
  }
1347
1433
  async screenshot() {
1348
- const { png } = await this.session.screenshot();
1349
- if (png.length === 0) {
1350
- throw new ComputerUnavailableError("native desktop screenshot returned an empty frame (display not up?)");
1434
+ let lastError;
1435
+ const deadline = Date.now() + this.screenshotWarmupBudgetMs;
1436
+ let attempt = 0;
1437
+ while (true) {
1438
+ if (attempt > 0) {
1439
+ await new Promise((r) => setTimeout(r, this.screenshotRetryDelayMs));
1440
+ }
1441
+ attempt++;
1442
+ try {
1443
+ const { png, width, height, nativeWidth, nativeHeight } = await this.session.screenshot();
1444
+ if (png.length === 0) {
1445
+ throw new ComputerUnavailableError("native desktop screenshot returned an empty frame (display not up?)");
1446
+ }
1447
+ this.lastEncoded = [width, height];
1448
+ this.lastNative = [nativeWidth || width, nativeHeight || height];
1449
+ return Buffer.from(png).toString("base64");
1450
+ } catch (error) {
1451
+ lastError = error;
1452
+ if (isTerminalCaptureDenial(error)) break;
1453
+ }
1454
+ if (Date.now() + this.screenshotRetryDelayMs >= deadline) {
1455
+ break;
1456
+ }
1351
1457
  }
1352
- return Buffer.from(png).toString("base64");
1458
+ const reason = lastError instanceof Error ? lastError.message : String(lastError);
1459
+ console.warn(`[NativeDesktopComputer] screenshot failed after ${attempt} attempt(s): ${reason}`);
1460
+ if (lastError instanceof Error) {
1461
+ throw lastError;
1462
+ }
1463
+ throw new ComputerUnavailableError("native desktop screenshot returned an empty frame (display not up?)");
1353
1464
  }
1354
1465
  async click(x, y, button) {
1355
1466
  this.guardWrite();
@@ -1365,7 +1476,8 @@ var NativeDesktopComputer = class {
1365
1476
  }
1366
1477
  async scroll(x, y, sx, sy) {
1367
1478
  this.guardWrite();
1368
- await this.session.desktopInput({ $case: "scroll", scroll: { x, y, deltaX: sx, deltaY: sy } });
1479
+ const n = this.toNative(x, y);
1480
+ await this.session.desktopInput({ $case: "scroll", scroll: { x: n.x, y: n.y, deltaX: sx, deltaY: sy } });
1369
1481
  }
1370
1482
  async type(text) {
1371
1483
  this.guardWrite();
@@ -1634,9 +1746,16 @@ function ensureReadableStreamFrom() {
1634
1746
  }
1635
1747
  });
1636
1748
  }
1749
+ var runtimeMetricsHooks = null;
1750
+ function configureRuntimeMetricsHooks(hooks) {
1751
+ runtimeMetricsHooks = hooks ?? null;
1752
+ }
1637
1753
  function createProductionAgentRuntime(overrides = {}) {
1638
1754
  return {
1639
- configure: configureOpenAI,
1755
+ configure: (settings) => {
1756
+ configureRuntimeMetricsHooks(overrides.metrics);
1757
+ configureOpenAI(settings);
1758
+ },
1640
1759
  // A test/override model shadows the registry routing entirely (the scripted
1641
1760
  // model used in worker tests is not in any provider's allow-list), so when
1642
1761
  // one is supplied resolveTurnModel reports "no resolution" and the caller
@@ -1655,7 +1774,7 @@ function createProductionAgentRuntime(overrides = {}) {
1655
1774
  serializeApprovals
1656
1775
  };
1657
1776
  }
1658
- function buildOpenAIClientFromSettings(settings) {
1777
+ function buildOpenAIClientFromSettings(settings, providerId = settings.openaiProvider) {
1659
1778
  if (settings.openaiProvider === "azure") {
1660
1779
  const baseURL = settings.azureOpenaiBaseUrl ?? azureDeploymentBaseUrl(settings);
1661
1780
  const apiKey = settings.azureOpenaiApiKey ?? settings.azureOpenaiAdToken ?? "azure-ad-token";
@@ -1670,13 +1789,14 @@ function buildOpenAIClientFromSettings(settings) {
1670
1789
  // seam — below the SDK responses converter, which always re-synthesizes BOTH
1671
1790
  // `action` and `actions` (rejected 400 "exactly one of action or actions").
1672
1791
  // See computerCallNormalizingFetch / rewriteComputerCallsToActionsOnly.
1673
- fetch: computerCallNormalizingFetch(globalThis.fetch)
1792
+ fetch: computerCallNormalizingFetch(instrumentedModelFetch(providerId, globalThis.fetch))
1674
1793
  });
1675
1794
  }
1676
1795
  return new OpenAI({
1677
1796
  apiKey: settings.openaiApiKey ?? process.env.OPENAI_API_KEY,
1678
1797
  ...settings.openaiBaseUrl ? { baseURL: settings.openaiBaseUrl } : {},
1679
- maxRetries: settings.openaiMaxRetries
1798
+ maxRetries: settings.openaiMaxRetries,
1799
+ fetch: instrumentedModelFetch(providerId, globalThis.fetch)
1680
1800
  });
1681
1801
  }
1682
1802
  var providerClientCache = /* @__PURE__ */ new Map();
@@ -1685,17 +1805,18 @@ function buildProviderClient(provider, settings) {
1685
1805
  if (cached) {
1686
1806
  return cached;
1687
1807
  }
1688
- const client = provider.builtin ? buildOpenAIClientFromSettings(settings) : provider.kind === "codex-subscription" ? new OpenAI({
1808
+ const client = provider.builtin ? buildOpenAIClientFromSettings(settings, provider.id) : provider.kind === "codex-subscription" ? new OpenAI({
1689
1809
  apiKey: provider.apiKey ?? "codex-subscription",
1690
1810
  ...provider.baseUrl ? { baseURL: provider.baseUrl } : {},
1691
1811
  maxRetries: settings.openaiMaxRetries,
1692
- fetch: codexSubscriptionFetch(globalThis.fetch)
1812
+ fetch: codexSubscriptionFetch(instrumentedModelFetch(provider.id, globalThis.fetch))
1693
1813
  }) : new OpenAI({
1694
1814
  ...provider.apiKey ? { apiKey: provider.apiKey } : {},
1695
1815
  ...provider.baseUrl ? { baseURL: provider.baseUrl } : {},
1696
1816
  maxRetries: settings.openaiMaxRetries,
1697
1817
  ...provider.defaultQuery ? { defaultQuery: provider.defaultQuery } : {},
1698
- ...provider.defaultHeaders ? { defaultHeaders: provider.defaultHeaders } : {}
1818
+ ...provider.defaultHeaders ? { defaultHeaders: provider.defaultHeaders } : {},
1819
+ fetch: instrumentedModelFetch(provider.id, globalThis.fetch)
1699
1820
  });
1700
1821
  providerClientCache.set(provider.id, client);
1701
1822
  return client;
@@ -1724,7 +1845,7 @@ var MultiProviderModelProvider = class {
1724
1845
  fallback;
1725
1846
  async getModel(modelName) {
1726
1847
  if (modelName) {
1727
- const resolved = resolveTurnModel(this.settings, modelName);
1848
+ const resolved = resolveTurnModel(settingsForRunScopedModelResolution(this.settings, modelName), modelName);
1728
1849
  if (resolved) {
1729
1850
  if (modelName.startsWith(CODEX_MODEL_ID_PREFIX) && resolved.provider.kind !== "codex-subscription") {
1730
1851
  throw new CodexSubscriptionUnavailableError(modelName);
@@ -1739,6 +1860,20 @@ var MultiProviderModelProvider = class {
1739
1860
  return this.fallback.getModel(modelName);
1740
1861
  }
1741
1862
  };
1863
+ function settingsForRunScopedModelResolution(settings, modelName) {
1864
+ if (modelName !== settings.openaiModel) {
1865
+ return settings;
1866
+ }
1867
+ const builtinAllowed = splitOpenaiAllowedModels(settings.openaiAllowedModels);
1868
+ const fallbackBuiltin = builtinAllowed.find((id) => id !== modelName);
1869
+ if (!fallbackBuiltin) {
1870
+ return settings;
1871
+ }
1872
+ return builtinAllowed.includes(modelName) ? settings : { ...settings, openaiModel: fallbackBuiltin };
1873
+ }
1874
+ function splitOpenaiAllowedModels(value) {
1875
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
1876
+ }
1742
1877
  var CodexSubscriptionUnavailableError = class extends Error {
1743
1878
  constructor(modelName) {
1744
1879
  super(
@@ -1749,6 +1884,7 @@ var CodexSubscriptionUnavailableError = class extends Error {
1749
1884
  };
1750
1885
  function configureOpenAI(settings) {
1751
1886
  setOpenAIResponsesTransport(settings.openaiResponsesTransport);
1887
+ setTracingDisabled(settings.disableOpenaiTracing || !settings.observabilityOtlpEndpoint);
1752
1888
  const router = new MultiProviderModelProvider(settings);
1753
1889
  if (settings.openaiProvider === "azure") {
1754
1890
  setDefaultOpenAIClient(buildOpenAIClientFromSettings(settings));
@@ -1763,6 +1899,41 @@ function configureOpenAI(settings) {
1763
1899
  }
1764
1900
  setDefaultModelProvider(router);
1765
1901
  }
1902
+ function instrumentedModelFetch(provider, inner) {
1903
+ return (async (input, init) => {
1904
+ if (!isModelCallFetch(input)) {
1905
+ return await inner(input, init);
1906
+ }
1907
+ const started = performance.now();
1908
+ try {
1909
+ const response = await inner(input, init);
1910
+ recordModelCallMetric(provider, response.ok ? "completed" : "failed", started);
1911
+ return response;
1912
+ } catch (error) {
1913
+ recordModelCallMetric(provider, "failed", started);
1914
+ throw error;
1915
+ }
1916
+ });
1917
+ }
1918
+ function isModelCallFetch(input) {
1919
+ const rawUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
1920
+ if (typeof rawUrl !== "string" || rawUrl.length === 0) {
1921
+ return false;
1922
+ }
1923
+ try {
1924
+ const pathname = new URL(rawUrl, "http://opengeni.local").pathname;
1925
+ return pathname.endsWith("/responses") || pathname.endsWith("/chat/completions") || pathname.endsWith("/codex/responses");
1926
+ } catch {
1927
+ return /\/(?:codex\/)?responses(?:\?|$)|\/chat\/completions(?:\?|$)/.test(rawUrl);
1928
+ }
1929
+ }
1930
+ function recordModelCallMetric(provider, outcome, started) {
1931
+ const durationSeconds = Math.max(0, (performance.now() - started) / 1e3);
1932
+ try {
1933
+ runtimeMetricsHooks?.onModelCall?.({ provider, outcome, durationSeconds });
1934
+ } catch {
1935
+ }
1936
+ }
1766
1937
  async function summarizeForCompaction(settings, input, options = {}) {
1767
1938
  const client = options.client ?? buildOpenAIClientFromSettings(settings);
1768
1939
  const api = options.api ?? "responses";
@@ -1858,6 +2029,13 @@ function composeAgentInstructions(template, workspaceEnvironment) {
1858
2029
  }
1859
2030
  return core ? `${template} ${core}` : template;
1860
2031
  }
2032
+ function appendSessionInstructions(composed, sessionInstructions) {
2033
+ const trimmed = sessionInstructions?.trim();
2034
+ return trimmed ? `${composed} ${trimmed}` : composed;
2035
+ }
2036
+ function appendGenesisTitleDirective(instructions, genesisTitleHint) {
2037
+ return genesisTitleHint ? `${instructions} ${GENESIS_TITLE_DIRECTIVE}` : instructions;
2038
+ }
1861
2039
  var agentFileDownloads = /* @__PURE__ */ new WeakMap();
1862
2040
  var agentRepositoryCloneHooks = /* @__PURE__ */ new WeakMap();
1863
2041
  var agentGitTokenSeed = /* @__PURE__ */ new WeakMap();
@@ -1879,7 +2057,21 @@ function buildOpenGeniAgent(settings, resources, options = {}) {
1879
2057
  // ownership + workspace-environment block) at the {{core}} marker, or
1880
2058
  // appends it when the template omits the marker. With the default template
1881
2059
  // and no environment this is byte-identical to the historical preamble.
1882
- instructions: options.genesisTitleHint ? `${composeAgentInstructions(options.instructionsTemplate ?? settings.agentInstructionsTemplate, options.workspaceEnvironment)} ${GENESIS_TITLE_DIRECTIVE}` : composeAgentInstructions(options.instructionsTemplate ?? settings.agentInstructionsTemplate, options.workspaceEnvironment),
2060
+ // Persona composition order (all one system-level instructions string):
2061
+ // 1. workspace instructionsTemplate (or deployment default) with the
2062
+ // non-bypassable CORE substituted at {{core}} — composeAgentInstructions,
2063
+ // 2. + the per-session persona instructions (session-specific, LAST so it
2064
+ // refines the workspace persona),
2065
+ // 3. + the one-shot genesis title directive (genesis turn only).
2066
+ // With no session instructions and no genesis hint this is byte-identical to
2067
+ // the historical composed instructions.
2068
+ instructions: appendGenesisTitleDirective(
2069
+ appendSessionInstructions(
2070
+ composeAgentInstructions(options.instructionsTemplate ?? settings.agentInstructionsTemplate, options.workspaceEnvironment),
2071
+ options.sessionInstructions
2072
+ ),
2073
+ options.genesisTitleHint
2074
+ ),
1883
2075
  modelSettings: {
1884
2076
  reasoning: { effort: options.reasoningEffort ?? settings.openaiReasoningEffort, summary: "detailed" },
1885
2077
  // Server-side compaction (OpenAI platform) requires store=false: the
@@ -2513,7 +2705,6 @@ async function runAgentStream(agent, input, settings, overrides = {}) {
2513
2705
  // every mid-turn follow-up.
2514
2706
  callModelInputFilter
2515
2707
  };
2516
- void settings.disableOpenaiTracing;
2517
2708
  if (client) {
2518
2709
  runOptions.sandbox = {
2519
2710
  client,
@@ -3738,6 +3929,8 @@ export {
3738
3929
  USER_MESSAGE_TRUNCATION_MARKER,
3739
3930
  agentErrorToControlError,
3740
3931
  agentsErrorRunState,
3932
+ appendGenesisTitleDirective,
3933
+ appendSessionInstructions,
3741
3934
  applyMissingManifestEntries,
3742
3935
  assertDescriptorRegistryInvariants,
3743
3936
  assertProviderRegistryInvariants,
@@ -3764,6 +3957,7 @@ export {
3764
3957
  composeAgentInstructions,
3765
3958
  computerUse,
3766
3959
  configureOpenAI,
3960
+ configureRuntimeMetricsHooks,
3767
3961
  contentTypeForCodec,
3768
3962
  contextRobustnessFilterForSettings,
3769
3963
  coreInstructions,
@@ -3800,6 +3994,8 @@ export {
3800
3994
  materializeSandboxFileDownloads,
3801
3995
  maxTurnsExceededRunState,
3802
3996
  mintStreamToken,
3997
+ modalSandboxAttributionEnvironment,
3998
+ modalSandboxAttributionTags,
3803
3999
  modelResponseUsageFromSdkEvent,
3804
4000
  negotiateCapabilities,
3805
4001
  negotiateSelfhostedCapabilities,
@@ -3850,8 +4046,11 @@ export {
3850
4046
  stripReasoningIdentityFromSerializedRunState,
3851
4047
  subjectFor,
3852
4048
  summarizeForCompaction,
4049
+ sweepModalOrphanSandboxes,
4050
+ tagModalSandbox,
3853
4051
  tearDownDisplayStack,
3854
4052
  tearDownTerminalServer,
4053
+ terminateModalSandboxById,
3855
4054
  timeoutAgentError,
3856
4055
  timeoutControlResponse,
3857
4056
  verifyStreamToken,