@opengeni/config 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,721 @@
1
+ import { Entitlements, SandboxBackend, StaticUsageLimits, ReasoningEffort } from '@opengeni/contracts';
2
+ import { z } from 'zod';
3
+
4
+ declare const sandboxPreparationProfiles: Record<string, {
5
+ env: string[];
6
+ hooks: string[];
7
+ }>;
8
+ /**
9
+ * Placeholder token inside an agent-instructions persona template. The runtime
10
+ * substitutes the non-bypassable CORE (goal-loop ownership + the dynamic
11
+ * workspace-environment block) at this marker. A template that omits the
12
+ * marker still gets the CORE appended after it (a non-bypassable fail-safe),
13
+ * so a white-labelled persona can never drop the goal-loop contract or the
14
+ * environment metadata the agent depends on.
15
+ */
16
+ declare const AGENT_INSTRUCTIONS_CORE_PLACEHOLDER = "{{core}}";
17
+ /**
18
+ * Default per-workspace agent persona template. This is the BRAND + tool-usage
19
+ * opinion (the white-labellable surface): the "You are an OpenGeni workspace
20
+ * agent." identity line, the framing/opinion lines, and the mount-path facts.
21
+ *
22
+ * The CORE that MUST survive any override — the goal-loop ownership line (which
23
+ * names the opengeni__goal_* tools) and the dynamic workspace-environment block
24
+ * — is injected at AGENT_INSTRUCTIONS_CORE_PLACEHOLDER by the runtime, never
25
+ * baked into this overridable string.
26
+ *
27
+ * INVARIANT: with no per-workspace override and an empty environment, the
28
+ * runtime's composed instructions are BYTE-IDENTICAL to the historical
29
+ * hardcoded preamble. The template below is exactly the historical lines 1–11
30
+ * joined by " ", followed by " " + the placeholder. Changing a single
31
+ * character here changes that default; a runtime test pins it.
32
+ */
33
+ declare const DEFAULT_AGENT_INSTRUCTIONS: string;
34
+ declare const SettingsSchema: z.ZodObject<{
35
+ serviceName: z.ZodDefault<z.ZodString>;
36
+ environment: z.ZodDefault<z.ZodString>;
37
+ deploymentRevision: z.ZodDefault<z.ZodString>;
38
+ databaseUrl: z.ZodDefault<z.ZodString>;
39
+ dbSchema: z.ZodDefault<z.ZodString>;
40
+ rlsStrategy: z.ZodDefault<z.ZodEnum<{
41
+ force: "force";
42
+ scoped: "scoped";
43
+ }>>;
44
+ natsUrl: z.ZodDefault<z.ZodString>;
45
+ temporalHost: z.ZodDefault<z.ZodString>;
46
+ temporalNamespace: z.ZodDefault<z.ZodString>;
47
+ temporalTaskQueue: z.ZodDefault<z.ZodString>;
48
+ startupDependencyRetryAttempts: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
49
+ startupDependencyRetryInitialDelayMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
50
+ startupDependencyRetryMaxDelayMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
51
+ observabilityStructuredLogs: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
52
+ observabilityMetricsEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
53
+ observabilityOtlpEndpoint: z.ZodOptional<z.ZodString>;
54
+ observabilityOtlpHeaders: z.ZodDefault<z.ZodString>;
55
+ publicBaseUrl: z.ZodOptional<z.ZodString>;
56
+ agentReleasesBaseUrl: z.ZodDefault<z.ZodString>;
57
+ productAccessMode: z.ZodDefault<z.ZodEnum<{
58
+ local: "local";
59
+ configured: "configured";
60
+ managed: "managed";
61
+ }>>;
62
+ billingMode: z.ZodDefault<z.ZodEnum<{
63
+ disabled: "disabled";
64
+ stripe: "stripe";
65
+ }>>;
66
+ entitlementsMode: z.ZodDefault<z.ZodEnum<{
67
+ none: "none";
68
+ managed: "managed";
69
+ static: "static";
70
+ }>>;
71
+ usageLimitsMode: z.ZodDefault<z.ZodEnum<{
72
+ none: "none";
73
+ managed: "managed";
74
+ static: "static";
75
+ }>>;
76
+ staticEntitlementsJson: z.ZodDefault<z.ZodString>;
77
+ staticUsageLimitsJson: z.ZodDefault<z.ZodString>;
78
+ delegationSecret: z.ZodOptional<z.ZodString>;
79
+ streamTokenSecret: z.ZodOptional<z.ZodString>;
80
+ streamControlEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
81
+ environmentsEncryptionKey: z.ZodOptional<z.ZodString>;
82
+ goalMaxAutoContinuations: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
83
+ goalNoProgressLimit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
84
+ agentMaxModelCallsPerTurn: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
85
+ sessionHistorySource: z.ZodDefault<z.ZodEnum<{
86
+ run_state: "run_state";
87
+ items: "items";
88
+ }>>;
89
+ contextCompactionMode: z.ZodDefault<z.ZodEnum<{
90
+ auto: "auto";
91
+ server: "server";
92
+ client: "client";
93
+ off: "off";
94
+ }>>;
95
+ contextWindowTokens: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
96
+ contextReservedOutputTokens: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
97
+ contextServerCompactThresholdTokens: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
98
+ contextCompactSoftFraction: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
99
+ contextCompactHardFraction: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
100
+ contextKeepRecentTokens: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
101
+ contextSummaryMaxTokens: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
102
+ authRequired: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
103
+ accessKey: z.ZodOptional<z.ZodString>;
104
+ authAllowHealth: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
105
+ authAllowMetrics: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
106
+ apiHost: z.ZodDefault<z.ZodString>;
107
+ apiPort: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
108
+ opengeniMcpUrl: z.ZodOptional<z.ZodString>;
109
+ corsAllowOriginRegex: z.ZodDefault<z.ZodString>;
110
+ openaiProvider: z.ZodDefault<z.ZodEnum<{
111
+ azure: "azure";
112
+ openai: "openai";
113
+ }>>;
114
+ openaiApiKey: z.ZodOptional<z.ZodString>;
115
+ openaiBaseUrl: z.ZodOptional<z.ZodString>;
116
+ openaiModel: z.ZodDefault<z.ZodString>;
117
+ openaiAllowedModels: z.ZodDefault<z.ZodString>;
118
+ modelPricingJson: z.ZodDefault<z.ZodString>;
119
+ modelProvidersJson: z.ZodDefault<z.ZodString>;
120
+ codexSubscriptionEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
121
+ codexProductSku: z.ZodOptional<z.ZodString>;
122
+ codexToolSearchEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
123
+ codexRotationNearExhaustionPct: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
124
+ openaiReasoningEffort: z.ZodDefault<z.ZodEnum<{
125
+ none: "none";
126
+ minimal: "minimal";
127
+ low: "low";
128
+ medium: "medium";
129
+ high: "high";
130
+ xhigh: "xhigh";
131
+ }>>;
132
+ openaiAllowedReasoningEfforts: z.ZodDefault<z.ZodString>;
133
+ openaiResponsesTransport: z.ZodDefault<z.ZodEnum<{
134
+ http: "http";
135
+ websocket: "websocket";
136
+ }>>;
137
+ openaiProviderItemIds: z.ZodDefault<z.ZodEnum<{
138
+ strip: "strip";
139
+ preserve: "preserve";
140
+ }>>;
141
+ openaiReasoningEncryptedContent: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
142
+ openaiMaxRetries: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
143
+ webSearchEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
144
+ agentInstructionsTemplate: z.ZodDefault<z.ZodString>;
145
+ azureOpenaiBaseUrl: z.ZodOptional<z.ZodString>;
146
+ azureOpenaiEndpoint: z.ZodOptional<z.ZodString>;
147
+ azureOpenaiDeployment: z.ZodOptional<z.ZodString>;
148
+ azureOpenaiApiVersion: z.ZodOptional<z.ZodString>;
149
+ azureOpenaiApiKey: z.ZodOptional<z.ZodString>;
150
+ azureOpenaiAdToken: z.ZodOptional<z.ZodString>;
151
+ disableOpenaiTracing: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
152
+ sandboxBackend: z.ZodDefault<z.ZodEnum<{
153
+ none: "none";
154
+ local: "local";
155
+ docker: "docker";
156
+ modal: "modal";
157
+ daytona: "daytona";
158
+ runloop: "runloop";
159
+ e2b: "e2b";
160
+ blaxel: "blaxel";
161
+ cloudflare: "cloudflare";
162
+ vercel: "vercel";
163
+ selfhosted: "selfhosted";
164
+ }>>;
165
+ dockerImage: z.ZodDefault<z.ZodString>;
166
+ dockerExposedPorts: z.ZodDefault<z.ZodString>;
167
+ dockerNetwork: z.ZodOptional<z.ZodString>;
168
+ modalAppName: z.ZodDefault<z.ZodString>;
169
+ modalImageRef: z.ZodOptional<z.ZodString>;
170
+ modalTimeoutSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
171
+ modalTokenId: z.ZodOptional<z.ZodString>;
172
+ modalTokenSecret: z.ZodOptional<z.ZodString>;
173
+ modalEnvironment: z.ZodOptional<z.ZodString>;
174
+ modalIdleTimeoutSeconds: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
175
+ modalWorkspacePersistence: z.ZodDefault<z.ZodEnum<{
176
+ tar: "tar";
177
+ snapshot_filesystem: "snapshot_filesystem";
178
+ snapshot_directory: "snapshot_directory";
179
+ }>>;
180
+ modalSnapshotRetentionSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
181
+ sandboxDesktopEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
182
+ sandboxDesktopInteractive: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
183
+ sandboxTerminalEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
184
+ streamResolutionWidth: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
185
+ streamResolutionHeight: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
186
+ computerUseEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
187
+ computerUseReadOnly: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
188
+ recordingEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
189
+ recordingDefaultCodec: z.ZodDefault<z.ZodEnum<{
190
+ "h264-mp4": "h264-mp4";
191
+ "vp9-webm": "vp9-webm";
192
+ }>>;
193
+ recordingFramerate: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
194
+ recordingMaxSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
195
+ recordingMaxBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
196
+ daytonaApiKey: z.ZodOptional<z.ZodString>;
197
+ daytonaApiUrl: z.ZodOptional<z.ZodString>;
198
+ daytonaTarget: z.ZodOptional<z.ZodString>;
199
+ daytonaImage: z.ZodOptional<z.ZodString>;
200
+ daytonaSnapshotName: z.ZodOptional<z.ZodString>;
201
+ daytonaAutoStopInterval: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
202
+ daytonaTimeoutSeconds: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
203
+ daytonaExposedPortUrlTtlSeconds: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
204
+ runloopApiKey: z.ZodOptional<z.ZodString>;
205
+ runloopBaseUrl: z.ZodOptional<z.ZodString>;
206
+ runloopBlueprintName: z.ZodOptional<z.ZodString>;
207
+ runloopBlueprintId: z.ZodOptional<z.ZodString>;
208
+ runloopTunnel: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
209
+ runloopKeepAliveSeconds: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
210
+ e2bApiKey: z.ZodOptional<z.ZodString>;
211
+ e2bTemplate: z.ZodOptional<z.ZodString>;
212
+ e2bTimeoutSeconds: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
213
+ e2bTimeoutAction: z.ZodOptional<z.ZodEnum<{
214
+ pause: "pause";
215
+ kill: "kill";
216
+ }>>;
217
+ e2bAllowInternetAccess: z.ZodOptional<z.ZodPreprocess<z.ZodBoolean>>;
218
+ e2bAutoResume: z.ZodOptional<z.ZodPreprocess<z.ZodBoolean>>;
219
+ e2bWorkspacePersistence: z.ZodOptional<z.ZodEnum<{
220
+ tar: "tar";
221
+ snapshot: "snapshot";
222
+ }>>;
223
+ blaxelApiKey: z.ZodOptional<z.ZodString>;
224
+ blaxelImage: z.ZodOptional<z.ZodString>;
225
+ blaxelRegion: z.ZodOptional<z.ZodString>;
226
+ blaxelExposedPortPublic: z.ZodOptional<z.ZodPreprocess<z.ZodBoolean>>;
227
+ blaxelExposedPortUrlTtlSeconds: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
228
+ blaxelMemoryMb: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
229
+ blaxelTtl: z.ZodOptional<z.ZodString>;
230
+ cloudflareWorkerUrl: z.ZodOptional<z.ZodString>;
231
+ cloudflareApiKey: z.ZodOptional<z.ZodString>;
232
+ vercelToken: z.ZodOptional<z.ZodString>;
233
+ vercelProjectId: z.ZodOptional<z.ZodString>;
234
+ vercelTeamId: z.ZodOptional<z.ZodString>;
235
+ vercelRuntime: z.ZodOptional<z.ZodString>;
236
+ sandboxOwnershipEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
237
+ sandboxSelfhostedEnabled: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
238
+ enrollmentSigningSecret: z.ZodOptional<z.ZodString>;
239
+ selfhostedNatsUrl: z.ZodOptional<z.ZodString>;
240
+ selfhostedRelayUrl: z.ZodOptional<z.ZodString>;
241
+ selfhostedRelayTokenSecret: z.ZodOptional<z.ZodString>;
242
+ agentUpdatePublicKey: z.ZodOptional<z.ZodString>;
243
+ selfhostedNatsCalloutAccountSeed: z.ZodOptional<z.ZodString>;
244
+ selfhostedNatsCalloutAccountName: z.ZodOptional<z.ZodString>;
245
+ selfhostedNatsCalloutUser: z.ZodOptional<z.ZodString>;
246
+ selfhostedNatsCalloutPassword: z.ZodOptional<z.ZodString>;
247
+ selfhostedNatsControlUser: z.ZodOptional<z.ZodString>;
248
+ selfhostedNatsControlPassword: z.ZodOptional<z.ZodString>;
249
+ sandboxLeaseReaperPeriodMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
250
+ sandboxViewerHolderTtlMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
251
+ sandboxIdleGraceMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
252
+ sandboxLeaseTtlMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
253
+ sandboxLeaseWarmingTtlMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
254
+ sandboxWarmRateMicrosPerSecondJson: z.ZodDefault<z.ZodString>;
255
+ sandboxMaxWarmSecondsPerWorkspace: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
256
+ sandboxPreparationProfiles: z.ZodDefault<z.ZodString>;
257
+ sandboxEnvAllowlist: z.ZodDefault<z.ZodString>;
258
+ objectStorageEndpoint: z.ZodOptional<z.ZodString>;
259
+ objectStorageSandboxEndpoint: z.ZodOptional<z.ZodString>;
260
+ objectStorageBackend: z.ZodDefault<z.ZodEnum<{
261
+ "s3-compatible": "s3-compatible";
262
+ "aws-s3": "aws-s3";
263
+ "azure-blob": "azure-blob";
264
+ gcs: "gcs";
265
+ }>>;
266
+ objectStorageBucket: z.ZodDefault<z.ZodString>;
267
+ objectStorageRegion: z.ZodDefault<z.ZodString>;
268
+ objectStorageS3Provider: z.ZodDefault<z.ZodString>;
269
+ objectStorageAccessKeyId: z.ZodOptional<z.ZodString>;
270
+ objectStorageSecretAccessKey: z.ZodOptional<z.ZodString>;
271
+ objectStorageForcePathStyle: z.ZodDefault<z.ZodPreprocess<z.ZodBoolean>>;
272
+ objectStorageAzureConnectionString: z.ZodOptional<z.ZodString>;
273
+ objectStorageAzureAccountName: z.ZodOptional<z.ZodString>;
274
+ objectStorageAzureAccountKey: z.ZodOptional<z.ZodString>;
275
+ objectStorageAzureEndpoint: z.ZodOptional<z.ZodString>;
276
+ objectStorageGcsProjectId: z.ZodOptional<z.ZodString>;
277
+ objectStorageGcsCredentialsJson: z.ZodOptional<z.ZodString>;
278
+ objectStorageGcsKeyFilename: z.ZodOptional<z.ZodString>;
279
+ objectStorageGcsApiEndpoint: z.ZodOptional<z.ZodString>;
280
+ documentParser: z.ZodDefault<z.ZodString>;
281
+ documentChunkSize: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
282
+ documentChunkOverlap: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
283
+ documentEmbeddingProvider: z.ZodDefault<z.ZodEnum<{
284
+ openai: "openai";
285
+ deterministic: "deterministic";
286
+ }>>;
287
+ documentEmbeddingModel: z.ZodDefault<z.ZodString>;
288
+ documentEmbeddingDimensions: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
289
+ documentEmbeddingApiKey: z.ZodOptional<z.ZodString>;
290
+ documentEmbeddingBaseUrl: z.ZodOptional<z.ZodString>;
291
+ gitAuthorName: z.ZodOptional<z.ZodString>;
292
+ gitAuthorEmail: z.ZodOptional<z.ZodString>;
293
+ gitCommitterName: z.ZodOptional<z.ZodString>;
294
+ gitCommitterEmail: z.ZodOptional<z.ZodString>;
295
+ githubAppManifestBaseUrl: z.ZodOptional<z.ZodString>;
296
+ githubAppManifestStateSecret: z.ZodOptional<z.ZodString>;
297
+ githubAppId: z.ZodOptional<z.ZodString>;
298
+ githubClientId: z.ZodOptional<z.ZodString>;
299
+ githubClientSecret: z.ZodOptional<z.ZodString>;
300
+ githubAppSlug: z.ZodOptional<z.ZodString>;
301
+ githubWebhookSecret: z.ZodOptional<z.ZodString>;
302
+ githubAppPrivateKey: z.ZodOptional<z.ZodString>;
303
+ betterAuthSecret: z.ZodOptional<z.ZodString>;
304
+ betterAuthAllowedHosts: z.ZodDefault<z.ZodString>;
305
+ betterAuthCookieDomain: z.ZodOptional<z.ZodString>;
306
+ betterAuthTrustedOrigins: z.ZodDefault<z.ZodString>;
307
+ resendApiKey: z.ZodOptional<z.ZodString>;
308
+ emailFrom: z.ZodDefault<z.ZodString>;
309
+ stripeSecretKey: z.ZodOptional<z.ZodString>;
310
+ stripePublishableKey: z.ZodOptional<z.ZodString>;
311
+ stripeWebhookSecret: z.ZodOptional<z.ZodString>;
312
+ stripeCreditsProductId: z.ZodOptional<z.ZodString>;
313
+ mcpServers: z.ZodDefault<z.ZodArray<z.ZodObject<{
314
+ id: z.ZodString;
315
+ name: z.ZodOptional<z.ZodString>;
316
+ url: z.ZodString;
317
+ allowedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
318
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
319
+ cacheToolsList: z.ZodDefault<z.ZodBoolean>;
320
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
321
+ }, z.core.$strip>>>;
322
+ }, z.core.$strip>;
323
+ type Settings = z.infer<typeof SettingsSchema>;
324
+ type McpServerConfig = Settings["mcpServers"][number];
325
+ type ModelPricing = {
326
+ inputMicrosPerMillionTokens: number;
327
+ cachedInputMicrosPerMillionTokens?: number | undefined;
328
+ outputMicrosPerMillionTokens: number;
329
+ marginBps?: number | undefined;
330
+ };
331
+ type ModelUsageInput = {
332
+ inputTokens?: number | undefined;
333
+ outputTokens?: number | undefined;
334
+ totalTokens?: number | undefined;
335
+ inputTokensDetails?: Record<string, number> | Array<Record<string, number>> | undefined;
336
+ requestUsageEntries?: ModelUsageInput[] | undefined;
337
+ };
338
+ type StaticUsageLimitsConfig = StaticUsageLimits;
339
+ type EntitlementsConfig = Entitlements;
340
+ /**
341
+ * Wire API a provider speaks. The built-in OpenAI/Azure provider always uses
342
+ * "responses" (the OpenAI Responses API). Extra registry providers default to
343
+ * "chat" (the broadly compatible /v1/chat/completions surface); Fireworks is
344
+ * wired as "chat" because its beta Responses endpoint echoes input back and
345
+ * silently no-ops hosted tools (see docs/model-providers.md).
346
+ */
347
+ declare const ModelProviderApi: z.ZodEnum<{
348
+ responses: "responses";
349
+ chat: "chat";
350
+ }>;
351
+ type ModelProviderApi = z.infer<typeof ModelProviderApi>;
352
+ /**
353
+ * Registry provider kind. "api-key" providers carry their own static key/headers;
354
+ * "codex-subscription" providers authenticate per-request with a ChatGPT/Codex
355
+ * subscription token resolved at call time (no static key) — see @opengeni/codex.
356
+ */
357
+ declare const RegistryProviderKind: z.ZodEnum<{
358
+ "api-key": "api-key";
359
+ "codex-subscription": "codex-subscription";
360
+ }>;
361
+ type RegistryProviderKind = z.infer<typeof RegistryProviderKind>;
362
+ /** A non-built-in provider declared by the host via OPENGENI_MODEL_PROVIDERS_JSON. */
363
+ declare const RegistryProviderSchema: z.ZodObject<{
364
+ kind: z.ZodDefault<z.ZodEnum<{
365
+ "api-key": "api-key";
366
+ "codex-subscription": "codex-subscription";
367
+ }>>;
368
+ id: z.ZodString;
369
+ label: z.ZodOptional<z.ZodString>;
370
+ api: z.ZodDefault<z.ZodEnum<{
371
+ responses: "responses";
372
+ chat: "chat";
373
+ }>>;
374
+ baseUrl: z.ZodString;
375
+ apiKey: z.ZodOptional<z.ZodString>;
376
+ apiKeyEnv: z.ZodOptional<z.ZodString>;
377
+ defaultQuery: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
378
+ defaultHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
379
+ models: z.ZodArray<z.ZodObject<{
380
+ id: z.ZodString;
381
+ label: z.ZodOptional<z.ZodString>;
382
+ contextWindowTokens: z.ZodOptional<z.ZodNumber>;
383
+ reasoningEffort: z.ZodOptional<z.ZodBoolean>;
384
+ hostedWebSearch: z.ZodOptional<z.ZodBoolean>;
385
+ pricing: z.ZodOptional<z.ZodObject<{
386
+ inputMicrosPerMillionTokens: z.ZodNumber;
387
+ cachedInputMicrosPerMillionTokens: z.ZodOptional<z.ZodNumber>;
388
+ outputMicrosPerMillionTokens: z.ZodNumber;
389
+ marginBps: z.ZodOptional<z.ZodNumber>;
390
+ }, z.core.$strip>>;
391
+ }, z.core.$strip>>;
392
+ }, z.core.$strip>;
393
+ type RegistryProvider = z.infer<typeof RegistryProviderSchema>;
394
+ /**
395
+ * Runtime-resolved provider (built-in or registry), client-construction-ready.
396
+ * The built-in OpenAI/Azure provider is always present and always "responses";
397
+ * registry providers carry their own base URL / key / wire API. compactionMode
398
+ * is "server" only for the built-in OpenAI platform provider (its Responses API
399
+ * honors server-side context_management) and "client" for everything else.
400
+ */
401
+ interface ResolvedModelProvider {
402
+ id: string;
403
+ label: string;
404
+ kind: RegistryProviderKind;
405
+ api: ModelProviderApi;
406
+ builtin: boolean;
407
+ baseUrl?: string | undefined;
408
+ apiKey?: string | undefined;
409
+ defaultQuery?: Record<string, string> | undefined;
410
+ defaultHeaders?: Record<string, string> | undefined;
411
+ compactionMode: ContextCompactionMode;
412
+ }
413
+ /** A single exposed model + the provider that serves it. */
414
+ interface ConfiguredModel {
415
+ id: string;
416
+ label: string;
417
+ providerId: string;
418
+ providerLabel: string;
419
+ api: ModelProviderApi;
420
+ contextWindowTokens?: number | undefined;
421
+ reasoningEffort: boolean;
422
+ hostedWebSearch: boolean;
423
+ }
424
+ declare const defaultModelPricing: Record<string, ModelPricing>;
425
+ type SandboxRequiredEnv = {
426
+ field: keyof Settings;
427
+ env: string;
428
+ };
429
+ declare const SANDBOX_REQUIRED_ENV: Record<z.infer<typeof SandboxBackend>, readonly SandboxRequiredEnv[]>;
430
+ /** The required OPENGENI_* env var names for a backend (for the deployment manifest). */
431
+ declare function requiredSandboxEnvForBackend(backend: z.infer<typeof SandboxBackend>): string[];
432
+ declare function getSettings(): Settings;
433
+ /**
434
+ * The Modal sandbox idle timeout (seconds) the provider actually passes as
435
+ * idleTimeoutMs (sandbox-file-persistence). When the operator did not pin
436
+ * OPENGENI_MODAL_IDLE_TIMEOUT_SECONDS we DEFAULT it to the hard lifetime
437
+ * (modalTimeoutSeconds): OpenGeni's reaper owns box lifecycle, so Modal's
438
+ * built-in idle-reap (which would otherwise fire on its short server default and
439
+ * kill the box BEFORE the reaper can snapshot /workspace) is pushed out to the
440
+ * hard backstop. An explicit smaller value is honoured (the boot invariant keeps
441
+ * it above reaperPeriod + idleGrace so a drained box still survives long enough
442
+ * to be persisted).
443
+ */
444
+ declare function effectiveModalIdleTimeoutSeconds(settings: Settings): number;
445
+ declare function collectSandboxEnvironment(settings: Settings, source?: NodeJS.ProcessEnv): Record<string, string>;
446
+ /**
447
+ * Resolved API key for a registry provider: the inline `apiKey` when present,
448
+ * else the value of the env var named by `apiKeyEnv`. The preferred form is
449
+ * `apiKeyEnv` (the secret stays out of OPENGENI_MODEL_PROVIDERS_JSON). Reads
450
+ * from `source` (defaults to process.env) so callers can resolve against an
451
+ * explicit environment in tests.
452
+ */
453
+ declare function resolveProviderApiKey(provider: Pick<RegistryProvider, "apiKey" | "apiKeyEnv">, source?: NodeJS.ProcessEnv): string | undefined;
454
+ /**
455
+ * Every provider a client may route to: the built-in OpenAI/Azure provider
456
+ * first (id "openai"/"azure", always "responses", compactionMode from
457
+ * resolveContextCompactionMode), then each registry provider in declaration
458
+ * order (compactionMode "client"). Client-construction inputs are filled from
459
+ * the existing flat openai/azure settings for the built-in, and from the
460
+ * registry entry for the rest. Registry ids may not collide with the built-in
461
+ * id — validateSettings rejects that at boot.
462
+ */
463
+ declare function configuredProviders(settings: Settings): ResolvedModelProvider[];
464
+ /**
465
+ * Every model a client may use, the built-in provider's models first
466
+ * (configuredAllowedModels-from-openai, mapped to "responses" with
467
+ * hostedWebSearch/contextWindow/reasoningEffort from the flat settings), then
468
+ * each registry provider's models (label→id, hostedWebSearch/reasoningEffort
469
+ * default false). De-duplicated by id (first wins) so the default model stays
470
+ * first and the built-in allow-list takes precedence over registry entries.
471
+ */
472
+ declare function configuredModels(settings: Settings): ConfiguredModel[];
473
+ /**
474
+ * Allowed model ids in selection order. Reimplemented on top of
475
+ * configuredModels so it is the union of the built-in allow-list and every
476
+ * registry provider's ids, de-duplicated. INVARIANT (existing callers + tests
477
+ * depend on it): settings.openaiModel is always first, then the rest of the
478
+ * openai allow-list, then registry ids.
479
+ */
480
+ declare function configuredAllowedModels(settings: Settings): string[];
481
+ /**
482
+ * Resolve a model string to the provider that serves it and its configured
483
+ * shape. Returns undefined when the id is not exposed (built-in allow-list nor
484
+ * any registry provider), so the runtime can fall back to the legacy global
485
+ * client path.
486
+ */
487
+ declare function resolveModelProvider(settings: Settings, modelId: string): {
488
+ provider: ResolvedModelProvider;
489
+ model: ConfiguredModel;
490
+ } | undefined;
491
+ /**
492
+ * Effective per-model pricing. Merge order (later wins):
493
+ * defaultModelPricing → registry model `pricing` entries (keyed by model id)
494
+ * → parseModelPricingJson(settings.modelPricingJson) (explicit JSON wins).
495
+ */
496
+ declare function configuredModelPricing(settings: Settings): Record<string, ModelPricing>;
497
+ /**
498
+ * Resolved conversation-context compaction path for a run.
499
+ * - "server": let the OpenAI platform Responses API compact server-side (the
500
+ * SDK emits context_management; we pass the correct gpt-5.5 threshold).
501
+ * - "client": run OpenGeni's own client-side compaction (Azure and any other
502
+ * backend that rejects/ignores context_management).
503
+ * - "off": neither (legacy unbounded growth; escape hatch).
504
+ *
505
+ * "auto" maps to "server" on the OpenAI platform provider and "client"
506
+ * otherwise — Azure's Responses API returns 400 unsupported_parameter for
507
+ * context_management, so it must never take the server path.
508
+ */
509
+ type ContextCompactionMode = "server" | "client" | "off";
510
+ declare function resolveContextCompactionMode(settings: Pick<Settings, "contextCompactionMode" | "openaiProvider">): ContextCompactionMode;
511
+ /** Usable input-token budget B = window - reserved output. */
512
+ declare function contextInputBudgetTokens(settings: Pick<Settings, "contextWindowTokens" | "contextReservedOutputTokens">): number;
513
+ /**
514
+ * Server-path compact_threshold (tokens) handed to the SDK's
515
+ * StaticCompactionPolicy: the explicit override when set, else
516
+ * floor(B * softFraction). This is what sidesteps the SDK's wrong 240k
517
+ * fallback for gpt-5.5 (which is absent from its hardcoded window map).
518
+ */
519
+ declare function contextServerCompactThreshold(settings: Pick<Settings, "contextWindowTokens" | "contextReservedOutputTokens" | "contextServerCompactThresholdTokens" | "contextCompactSoftFraction">): number;
520
+ declare function configuredStaticUsageLimits(settings: Settings): StaticUsageLimitsConfig;
521
+ declare function configuredEntitlements(settings: Settings): EntitlementsConfig;
522
+ declare function calculateModelUsageCostMicros(settings: Settings, model: string, usage: ModelUsageInput): number;
523
+ declare function configuredAllowedReasoningEfforts(settings: Settings): Array<z.infer<typeof ReasoningEffort>>;
524
+ /**
525
+ * Decodes OPENGENI_ENVIRONMENTS_ENCRYPTION_KEY (base64, exactly 32 bytes) for
526
+ * AES-256-GCM workspace environment value encryption. Returns null when unset.
527
+ * Throws naming only the env var, never echoing its value.
528
+ */
529
+ declare function environmentsEncryptionKeyBytes(settings: Settings): Uint8Array | null;
530
+ /**
531
+ * The connection `search_path` for OpenGeni's db handles + the managed-auth pool
532
+ * (Step I, §7.8 runtime half). Returns `undefined` when `dbSchema` is unset
533
+ * (standalone) so no `search_path` startup parameter is sent and the server
534
+ * default (`public`) applies — byte-for-byte today's behavior. When `dbSchema`
535
+ * is set (embedded), returns `"<schema>,opengeni_private,public"` — `public`
536
+ * stays LAST so `gen_random_uuid()` (pgcrypto) and the `vector` type still
537
+ * resolve (the SPIKE-1 live footgun). `opengeni_private` is on the path so the
538
+ * RLS GUC-reader helpers resolve when referenced unqualified.
539
+ */
540
+ declare function dbSearchPath(settings: Pick<Settings, "dbSchema">): string | undefined;
541
+ declare function collectGitIdentityEnvironment(settings: Settings): Record<string, string>;
542
+ /**
543
+ * The STABLE run-scoped sandbox environment: the subset of a run's box-manifest
544
+ * environment that is IDENTICAL whether the box is first warmed by the worker
545
+ * TURN or by an API-direct ATTACH (viewer / Channel-A / desktop / terminal). It
546
+ * is the layered base every cold box must be created with so a later turn's
547
+ * agent-manifest apply finds an EMPTY environment delta in the SDK's
548
+ * `validateNoEnvironmentDelta` (which throws "Live sandbox sessions cannot change
549
+ * manifest environment variables" on ANY key the agent declares that the box's
550
+ * manifest lacks or carries a different value for).
551
+ *
552
+ * Precedence (lowest → highest): deployment allowlist (`collectSandboxEnvironment`)
553
+ * < git identity (`collectGitIdentityEnvironment`) < the session's attached
554
+ * workspace environment < the backend-aware HOME default. Reserved-name validation
555
+ * at write time keeps workspace values from colliding with platform entries.
556
+ *
557
+ * DELIBERATELY EXCLUDES the per-run, ROTATING GitHub App installation token
558
+ * VALUE that `sandboxEnvironmentForRun` mints when a repository resource is
559
+ * attached: that token is minted FRESH per call, so it is not a stable, attach-
560
+ * reproducible value and must not be part of the shared base. Under the token-
561
+ * broker (B1) the token VALUE never rides the manifest at all — it is seeded to a
562
+ * FILE inside the box (agent-managed, refreshable mid-turn via the `github_token`
563
+ * MCP tool) and git auth flows through GIT_ASKPASS -> that file. What IS stable and
564
+ * lives here is the token FILE PATH (`OPENGENI_GIT_TOKEN_FILE`): a constant derived
565
+ * from HOME, so it appears IDENTICALLY on BOTH the turn AND every attach manifest
566
+ * (the SDK's per-turn provided-session env delta stays empty even as the token
567
+ * rotates). The attach surfaces have only the `Session` (no repo resources) and so
568
+ * never seed a token, but the file-path pointer is harmless (an unwritten file
569
+ * simply yields no auth); the BLOCKING attach-vs-turn error this helper fixes is
570
+ * for the common (no-repo) and workspace-environment-attached cases.
571
+ */
572
+ declare function stableSandboxEnvironmentForRun(settings: Settings, workspaceEnvironment?: Record<string, string>): Record<string, string>;
573
+ /**
574
+ * Whether a resource set carries a GitHub-App-connected repository (installation
575
+ * + repository ids present) — the SAME predicate the worker turn uses to decide
576
+ * whether it declares the stable git-auth pointers. Attach surfaces call this so
577
+ * an attach-warmed cold box carries the IDENTICAL manifest env a later repo turn
578
+ * declares (env parity — see applyGitAuthPointerEnvironment).
579
+ */
580
+ declare function hasGitHubRepositorySelection(resources: ReadonlyArray<{
581
+ kind: string;
582
+ githubInstallationId?: unknown;
583
+ githubRepositoryId?: unknown;
584
+ }>): boolean;
585
+ /**
586
+ * TOKEN-BROKER (B1) parity: the STABLE git-auth POINTER environment a
587
+ * repo-attached run declares — GIT_ASKPASS (a fixed path under HOME; the script
588
+ * itself is provisioned at box setup), GIT_TERMINAL_PROMPT, and the GitHub-App
589
+ * bot identity fallbacks. NO rotating value rides here (the token lives in the
590
+ * file behind the askpass), so the layer is attach-reproducible and MUST be
591
+ * applied identically by the worker turn (sandboxEnvironmentForRun) AND every
592
+ * API-direct attach surface that can cold-create the box (viewer attach,
593
+ * channel-A ops). A box cold-created WITHOUT this layer kills the next repo
594
+ * turn: the turn's manifest declares these keys, the box's env lacks them, and
595
+ * the SDK's provided-session guard throws "Live sandbox sessions cannot change
596
+ * manifest environment variables" (observed live: an open session page's viewer
597
+ * attach won the cold-create race and the first turn died).
598
+ *
599
+ * Mutates and returns `environment`. Identity fallbacks preserve values already
600
+ * present (the deployment git-identity allowlist wins over the bot identity).
601
+ */
602
+ declare function applyGitAuthPointerEnvironment(environment: Record<string, string>, identity: {
603
+ name: string;
604
+ email: string;
605
+ } | null): Record<string, string>;
606
+ type StartupRetryOptions = {
607
+ attempts?: number;
608
+ initialDelayMs?: number;
609
+ maxDelayMs?: number;
610
+ onRetry?: (event: {
611
+ label: string;
612
+ attempt: number;
613
+ attempts: number;
614
+ delayMs: number;
615
+ error: unknown;
616
+ }) => void;
617
+ };
618
+ declare function startupRetryOptions(settings: Settings): Required<Omit<StartupRetryOptions, "onRetry">>;
619
+ declare function retryStartupDependency<T>(label: string, operation: () => Promise<T>, options?: StartupRetryOptions): Promise<T>;
620
+ declare function sandboxEnvironmentVariableNames(settings: Settings): string[];
621
+ declare function sandboxLifecycleHookIds(settings: Settings): string[];
622
+ declare function parseExposedPorts(raw: string): number[];
623
+ declare function parseMcpServers(raw: string | undefined): unknown[] | undefined;
624
+ declare function parseModelPricingJson(raw: string): Record<string, ModelPricing>;
625
+ declare function parseSandboxWarmRateJson(raw: string): Record<string, number>;
626
+ declare function sandboxWarmRateMicrosPerSecond(settings: Settings, backend: string): number;
627
+ /**
628
+ * Parse + validate the extra-provider registry JSON. `[]` (or empty/whitespace)
629
+ * yields an empty list. Surfaces JSON and zod errors prefixed with the env-var
630
+ * name so a malformed registry fails fast at boot (validateSettings calls this).
631
+ */
632
+ declare function parseModelProvidersJson(raw: string): RegistryProvider[];
633
+ declare function parseStaticUsageLimitsJson(raw: string): StaticUsageLimitsConfig;
634
+ declare function parseStaticEntitlementsJson(raw: string): EntitlementsConfig;
635
+ /**
636
+ * The base URL of OpenGeni's own first-party MCP endpoint, as a `{workspaceId}`
637
+ * template — the SINGLE source of truth for the `opengeniMcpUrl`-or-loopback
638
+ * decision. Every site that needs the first-party MCP base (config's tool
639
+ * registry here, and the worker-side `firstPartyMcpServerUrlForRun` /
640
+ * `firstPartyMcpUrls` in @opengeni/runtime) MUST route through this so the
641
+ * default lives in exactly one place.
642
+ *
643
+ * BINDING CONTRACT (`opengeniMcpUrl`):
644
+ * - STANDALONE (unset): falls back to the loopback default
645
+ * `http://127.0.0.1:${apiPort}/v1/workspaces/{workspaceId}/mcp` — the worker
646
+ * and API are in/next to the same host:port, so loopback resolves the
647
+ * workspace-scoped MCP. Byte-for-byte today's behavior.
648
+ * - EMBEDDED / MOUNTED (must set): when OpenGeni's API is mounted as a host
649
+ * sub-app under a prefix (e.g. `https://host/og/v1/...`), the loopback
650
+ * default is WRONG — the worker runs in the host process and `127.0.0.1:
651
+ * ${apiPort}` is not where the mounted, sandbox-routable MCP lives. The host
652
+ * MUST set `OPENGENI_MCP_URL` to the externally/sandbox-routable base (a
653
+ * `{workspaceId}` template, or a concrete base that gets re-scoped). This is
654
+ * the one binding a mounted embed cannot leave unset.
655
+ */
656
+ declare function firstPartyMcpBaseUrl(settings: Settings): string;
657
+ /**
658
+ * Resolve the secret used to sign/verify scoped stream tokens (master-spine
659
+ * §C.3). Falls back to `delegationSecret` (the same HMAC envelope family —
660
+ * `ogs_` vs `ogd_` prefix) so a deployment that already carries a delegation
661
+ * secret does not need a second one. Returns undefined when neither is set,
662
+ * which drives the graceful-degrade (DesktopStream.transport:null).
663
+ */
664
+ declare function resolveStreamTokenSecret(settings: Settings): string | undefined;
665
+ /**
666
+ * True iff the desktop pixel plane must GRACEFULLY DEGRADE because desktop is
667
+ * enabled but no stream-token secret is resolvable (I8/OD-8). When true,
668
+ * negotiateCapabilities forces DesktopStream.transport:null.
669
+ */
670
+ declare function streamTokenDegraded(settings: Settings): boolean;
671
+ /**
672
+ * Resolve the secret the control plane signs the enrollment bearer credential
673
+ * with (the `oge_` envelope the agent presents back — M5/dossier §10.2). Falls
674
+ * back to `delegationSecret` (the same HMAC envelope family) so a deployment that
675
+ * already carries a delegation secret needs no second one. Returns undefined when
676
+ * neither is set; when selfhosted is enabled but this is undefined, the poll route
677
+ * reports the credential plane disabled (graceful degrade, never a 500). NEVER log
678
+ * the returned value.
679
+ */
680
+ declare function resolveEnrollmentSigningSecret(settings: Settings): string | undefined;
681
+ /**
682
+ * Resolve the HMAC secret the control plane signs the agent's relay PRODUCER token
683
+ * with (the `ogr_` envelope; M8b/dossier §10.5). The RELAY verifies the producer
684
+ * token with the SAME secret (injected into the relay via env). Prefers an explicit
685
+ * `selfhostedRelayTokenSecret`, then the `streamTokenSecret` (the relay already
686
+ * needs that one to verify the viewer's `ogs_` token, so a single secret can back
687
+ * both planes), then `delegationSecret` (same HMAC family). Returns undefined when
688
+ * none is set — the enrollment poll then returns an empty relayToken (graceful
689
+ * degrade; the stream plane is unavailable until configured). NEVER log the value.
690
+ */
691
+ declare function resolveRelayTokenSecret(settings: Settings): string | undefined;
692
+ /**
693
+ * The resolved NATS auth-callout responder config (M-AUTH). Present only when the
694
+ * callout plane is FULLY configured: the account signing seed + the responder's own
695
+ * login. When any piece is missing this returns null and the responder does not
696
+ * start (selfhosted agents cannot connect — a graceful disabled state, never a boot
697
+ * crash). The returned `accountSeed` is a secret; NEVER log it.
698
+ */
699
+ interface NatsCalloutConfig {
700
+ /** The callout account SIGNING seed (`SA...`) — signs the user + response JWTs. */
701
+ accountSeed: string;
702
+ /** The target account NAME the user is placed into (the response `aud`). */
703
+ accountName: string;
704
+ /** The responder's NATS login (an `auth_callout.auth_users` user). */
705
+ user: string;
706
+ password: string;
707
+ }
708
+ declare function resolveNatsCalloutConfig(settings: Settings): NatsCalloutConfig | null;
709
+ /**
710
+ * The PRIVILEGED control-plane NATS login (api/worker). Present only when BOTH a
711
+ * user and password are set; otherwise null and the bus connects anonymously (local
712
+ * dev / a NATS without auth_callout). When the callout plane is on, this is the
713
+ * static account user permitted to request `agent.*.rpc`.
714
+ */
715
+ interface NatsControlPlaneAuth {
716
+ user: string;
717
+ password: string;
718
+ }
719
+ declare function resolveNatsControlPlaneAuth(settings: Settings): NatsControlPlaneAuth | null;
720
+
721
+ export { AGENT_INSTRUCTIONS_CORE_PLACEHOLDER, type ConfiguredModel, type ContextCompactionMode, DEFAULT_AGENT_INSTRUCTIONS, type EntitlementsConfig, type McpServerConfig, type ModelPricing, ModelProviderApi, type ModelUsageInput, type NatsCalloutConfig, type NatsControlPlaneAuth, type RegistryProvider, RegistryProviderKind, type ResolvedModelProvider, SANDBOX_REQUIRED_ENV, type SandboxRequiredEnv, type Settings, type StartupRetryOptions, type StaticUsageLimitsConfig, applyGitAuthPointerEnvironment, calculateModelUsageCostMicros, collectGitIdentityEnvironment, collectSandboxEnvironment, configuredAllowedModels, configuredAllowedReasoningEfforts, configuredEntitlements, configuredModelPricing, configuredModels, configuredProviders, configuredStaticUsageLimits, contextInputBudgetTokens, contextServerCompactThreshold, dbSearchPath, defaultModelPricing, effectiveModalIdleTimeoutSeconds, environmentsEncryptionKeyBytes, firstPartyMcpBaseUrl, getSettings, hasGitHubRepositorySelection, parseExposedPorts, parseMcpServers, parseModelPricingJson, parseModelProvidersJson, parseSandboxWarmRateJson, parseStaticEntitlementsJson, parseStaticUsageLimitsJson, requiredSandboxEnvForBackend, resolveContextCompactionMode, resolveEnrollmentSigningSecret, resolveModelProvider, resolveNatsCalloutConfig, resolveNatsControlPlaneAuth, resolveProviderApiKey, resolveRelayTokenSecret, resolveStreamTokenSecret, retryStartupDependency, sandboxEnvironmentVariableNames, sandboxLifecycleHookIds, sandboxPreparationProfiles, sandboxWarmRateMicrosPerSecond, stableSandboxEnvironmentForRun, startupRetryOptions, streamTokenDegraded };