@opengeni/config 0.5.1 → 0.6.9

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.js CHANGED
@@ -7,10 +7,22 @@ import {
7
7
  ProductAccessMode,
8
8
  ReasoningEffort,
9
9
  SandboxBackend,
10
+ SessionMcpApprovalPolicy,
10
11
  StaticUsageLimits,
12
+ TurnExecutionPolicyV1,
11
13
  UsageLimitsMode
12
14
  } from "@opengeni/contracts";
13
- import { CODEX_MODEL_ID_PREFIX, CODEX_PROVIDER_ID } from "@opengeni/codex/constants";
15
+ import { CODEX_MODEL_TOOL_OUTPUT_TRUNCATION_TOKENS } from "@opengeni/codex";
16
+ import {
17
+ CODEX_FALLBACK_MODEL_SLUGS,
18
+ CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT,
19
+ CODEX_MODEL_CONTEXT_WINDOW_TOKENS,
20
+ CODEX_MODEL_EFFECTIVE_CONTEXT_WINDOW_TOKENS,
21
+ CODEX_MODEL_ID_PREFIX,
22
+ CODEX_PROVIDER_BASE_URL,
23
+ CODEX_PROVIDER_ID
24
+ } from "@opengeni/codex/constants";
25
+ import { createHash } from "crypto";
14
26
  import { z } from "zod";
15
27
  var envName = /^[A-Za-z_][A-Za-z0-9_]*$/;
16
28
  var registryId = /^[A-Za-z0-9_-]+$/;
@@ -63,7 +75,7 @@ var DEFAULT_AGENT_INSTRUCTIONS = [
63
75
  "You are an OpenGeni workspace agent.",
64
76
  "Follow the user's task and any enabled pack or skill instructions for the current role.",
65
77
  "Work inside the sandbox workspace and use filesystem and shell tools when useful.",
66
- "Repository resources are mounted under repos/<owner>/<repo>.",
78
+ "Repository resources are mounted under repos/<host>/<owner>/<repo> unless the session specifies another collision-free mount path.",
67
79
  "File resources are mounted under files/<file-id>/ unless the session specifies another mount path.",
68
80
  "Attached files are mounted read-only; copy them before modifying.",
69
81
  "Bundled skills are under .agents/ and can include infrastructure, marketing, or other role-specific guidance.",
@@ -74,13 +86,50 @@ var DEFAULT_AGENT_INSTRUCTIONS = [
74
86
  AGENT_INSTRUCTIONS_CORE_PLACEHOLDER
75
87
  ].join(" ");
76
88
  var McpServerConnectionRefSchema = z.object({
77
- connectionId: z.string().uuid().optional(),
89
+ // Standalone ids are UUIDs; embedded hosts may use any stable opaque id.
90
+ connectionId: z.string().min(1).optional(),
91
+ provider: z.string().min(1).max(128).optional(),
78
92
  providerDomain: z.string().min(1),
79
93
  kind: z.enum(["oauth2", "api_key", "app_install", "delegated"]).optional(),
80
94
  scopes: z.array(z.string().min(1)).optional(),
81
95
  resource: z.string().min(1).optional(),
96
+ selectedResources: z.array(
97
+ z.object({
98
+ id: z.string().min(1).max(512),
99
+ kind: z.literal("repository")
100
+ }).strict()
101
+ ).min(1).max(256).superRefine((resources, context) => {
102
+ const seen = /* @__PURE__ */ new Set();
103
+ for (const [index, resource] of resources.entries()) {
104
+ const key = `${resource.kind}\0${resource.id}`;
105
+ if (seen.has(key)) {
106
+ context.addIssue({
107
+ code: "custom",
108
+ message: "selectedResources must not contain duplicates",
109
+ path: [index]
110
+ });
111
+ }
112
+ seen.add(key);
113
+ }
114
+ }).optional(),
82
115
  subjectScope: z.enum(["workspace", "subject"]).optional()
83
- }).strict();
116
+ }).strict().superRefine((reference, context) => {
117
+ if (!reference.selectedResources) return;
118
+ if (!reference.connectionId) {
119
+ context.addIssue({
120
+ code: "custom",
121
+ message: "selectedResources requires connectionId",
122
+ path: ["connectionId"]
123
+ });
124
+ }
125
+ if (!reference.provider) {
126
+ context.addIssue({
127
+ code: "custom",
128
+ message: "selectedResources requires provider",
129
+ path: ["provider"]
130
+ });
131
+ }
132
+ });
84
133
  var SettingsSchema = z.object({
85
134
  serviceName: z.string().default("opengeni"),
86
135
  environment: z.string().default("local"),
@@ -93,7 +142,7 @@ var SettingsSchema = z.object({
93
142
  // topology. Default "" → standalone: no search_path scoping, server default
94
143
  // (`public`). When set (e.g. "opengeni"), the db handle + the managed-auth
95
144
  // pool send `search_path = "<dbSchema>","opengeni_private","public"` so every
96
- // query resolves into the dedicated schema with NO query rewrite (SPIKE-1 F1).
145
+ // query resolves into the dedicated schema with NO query rewrite (schema-isolation contract F1).
97
146
  dbSchema: z.string().default(""),
98
147
  // Step I (§7.7). RLS posture. "force" (default) = today's FORCE-RLS via the
99
148
  // non-owner `opengeni_app` role. "scoped" = the embedded owner-role path (the
@@ -103,6 +152,12 @@ var SettingsSchema = z.object({
103
152
  temporalHost: z.string().default("127.0.0.1:7233"),
104
153
  temporalNamespace: z.string().default("default"),
105
154
  temporalTaskQueue: z.string().default("opengeni-runs-ts"),
155
+ temporalTlsEnabled: EnvBoolean.default(false),
156
+ temporalApiKey: z.string().optional(),
157
+ temporalTlsServerName: z.string().optional(),
158
+ temporalTlsRootCaCertificateBase64: z.string().optional(),
159
+ temporalTlsClientCertificateBase64: z.string().optional(),
160
+ temporalTlsClientPrivateKeyBase64: z.string().optional(),
106
161
  startupDependencyRetryAttempts: z.coerce.number().int().positive().default(30),
107
162
  startupDependencyRetryInitialDelayMs: z.coerce.number().int().positive().default(1e3),
108
163
  startupDependencyRetryMaxDelayMs: z.coerce.number().int().positive().default(5e3),
@@ -122,18 +177,25 @@ var SettingsSchema = z.object({
122
177
  staticEntitlementsJson: z.string().default("{}"),
123
178
  staticUsageLimitsJson: z.string().default("{}"),
124
179
  delegationSecret: z.string().optional(),
125
- // Sandbox-surfacing scoped stream-token HMAC secret (master-spine §C.3 / I8).
180
+ // sandbox workspace scoped stream-token HMAC secret (sandbox contract §C.3 / stream-token availability contract).
126
181
  // When unset, the API falls back to `delegationSecret` (the same HMAC envelope
127
182
  // family, `ogs_` vs `ogd_` prefix). REQUIRED-WHEN-DESKTOP, but the absence of
128
183
  // BOTH while sandboxDesktopEnabled=true is a GRACEFUL DEGRADE (DesktopStream
129
- // transport:null + a loud boot warning), NOT a hard boot-fail (I8/OD-8).
184
+ // transport:null + a loud boot warning), NOT a hard boot-fail (stream-token availability contract).
130
185
  streamTokenSecret: z.string().optional(),
131
186
  // The desktop input plane (raw stream:control writes) is OFF in v1: even a
132
187
  // holder of stream:control gets 403 until this flips. Keeps stream:control a
133
188
  // declared-but-inert permission so later hardening is a flag flip.
134
189
  streamControlEnabled: EnvBoolean.default(false),
190
+ // Existing-session explicit tool replacement is gated until every API and
191
+ // worker instance understands durable tools_provided provenance.
192
+ sessionTurnToolReplacementEnabled: EnvBoolean.default(false),
135
193
  toolspaceEnabled: EnvBoolean.default(false),
136
194
  toolspaceMaxCallsPerTurn: z.coerce.number().int().positive().default(200),
195
+ // Optional release-coherent bootstrap hint for custom rigs/connected machines
196
+ // that do not carry the stock-image ogtool binary. Exact stable versions only:
197
+ // the agent must never guess a tag or silently install `latest`.
198
+ ogtoolPackageSpec: z.string().regex(/^@opengeni\/ogtool@(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/u).optional(),
137
199
  environmentsEncryptionKey: z.string().optional(),
138
200
  integrationsEnabled: EnvBoolean.default(false),
139
201
  integrationsStateSecret: z.string().optional(),
@@ -178,6 +240,10 @@ var SettingsSchema = z.object({
178
240
  // Model-catalog auto-compact limit. When present it is clamped to
179
241
  // 90% of the raw window, matching Codex core's auto_compact_token_limit().
180
242
  contextAutoCompactThresholdTokens: z.coerce.number().int().positive().optional(),
243
+ // Provider-neutral fallback for canonical model-facing tool-result text.
244
+ // The current stable Codex catalog policy is 10k tokens; the truncator adds
245
+ // Codex's 1.2x JSON serialization allowance when applying it.
246
+ modelToolOutputTruncationTokens: z.coerce.number().int().positive().default(1e4),
181
247
  authRequired: EnvBoolean.default(false),
182
248
  accessKey: z.string().optional(),
183
249
  authAllowHealth: EnvBoolean.default(true),
@@ -213,15 +279,11 @@ var SettingsSchema = z.object({
213
279
  // tool that BM25-discloses only the matching connectors. Default OFF — a codex
214
280
  // turn is byte-for-byte unchanged until enabled. OPENGENI_CODEX_TOOL_SEARCH_ENABLED
215
281
  codexToolSearchEnabled: EnvBoolean.default(false),
216
- // OPE-21 atomic, workspace-local credential allocation. Default OFF is a
282
+ // credential allocator atomic, workspace-local credential allocation. Default OFF is a
217
283
  // deliberate rolling-deploy fence: migrate + roll every worker first, then
218
284
  // enable. Turning it off restores the legacy sticky selector without a schema
219
285
  // rollback; the additive lease table/cursor columns become inert.
220
286
  codexCredentialLeasingEnabled: EnvBoolean.default(false),
221
- // Multi-account P3 (auto-rotation): an account is "near exhaustion" — ineligible to be
222
- // rotated TO — when EITHER usage window (5h/weekly) is at/over this percent. Default 90 to
223
- // match the UI danger flip (UsageBar danger at pct >= 90). OPENGENI_CODEX_ROTATION_NEAR_EXHAUSTION_PCT.
224
- codexRotationNearExhaustionPct: z.coerce.number().int().min(1).max(100).default(90),
225
287
  openaiReasoningEffort: ReasoningEffort.default("low"),
226
288
  openaiAllowedReasoningEfforts: z.string().default("low,medium,high,xhigh"),
227
289
  openaiResponsesTransport: z.enum(["http", "websocket"]).default("http"),
@@ -360,7 +422,7 @@ var SettingsSchema = z.object({
360
422
  // recordingMaxSeconds is the ffmpeg -t hard ceiling (bounds a multi-day turn).
361
423
  recordingEnabled: EnvBoolean.default(true),
362
424
  recordingDefaultCodec: z.enum(["h264-mp4", "vp9-webm"]).default("h264-mp4"),
363
- // Workbench v2 turn-end workspace capture (dossier §10.1). When on, the turn
425
+ // Workbench v2 turn-end workspace capture. When on, the turn
364
426
  // activity probes the box's changed files off the live box at turn end and
365
427
  // persists a capture revision (blobs in @opengeni/storage) so the workbench
366
428
  // paints cold/offline sessions with zero machine round-trips. Best-effort and
@@ -423,6 +485,15 @@ var SettingsSchema = z.object({
423
485
  // EnvBoolean (NOT z.coerce.boolean(), which would coerce "false" -> true and
424
486
  // turn the flag ON the moment anyone set the env var to disable it).
425
487
  sandboxOwnershipEnabled: EnvBoolean.default(false),
488
+ // --- standalone rig-verifier ownership rollout flag, default OFF ---
489
+ // Rig verification creates a throwaway provider sandbox outside the normal
490
+ // session-turn path. When enabled, that sandbox must first acquire the same
491
+ // durable lease lifecycle used by session boxes so the global orphan sweep
492
+ // recognizes its exact provider instance. Keep this separate from the general
493
+ // sandboxOwnershipEnabled rollout: every reaper worker must understand verifier
494
+ // leases before dispatch is enabled. When false the verifier fails closed before
495
+ // provider create; it never falls back to the legacy unowned path.
496
+ rigVerificationLeaseOwnershipEnabled: EnvBoolean.default(false),
426
497
  // --- lazy sandbox provisioning rollout flag, default OFF ---
427
498
  // Only effective when sandboxOwnershipEnabled is ALSO on (lazy provisioning is a
428
499
  // property of the owned path — the SDK never creates/resumes an injected session,
@@ -442,7 +513,7 @@ var SettingsSchema = z.object({
442
513
  // 404 (invisible — the surface does not exist for this deployment) and the
443
514
  // selfhosted backend is inert; boot is unaffected. EnvBoolean (NOT
444
515
  // z.coerce.boolean(), which coerces "false" -> true). Flipped per-environment via
445
- // the deploy-staging IaC secret/configmap pattern (dossier §17/§25.1).
516
+ // the deploy-staging IaC secret/configmap pattern.
446
517
  sandboxSelfhostedEnabled: EnvBoolean.default(false),
447
518
  // Gates the op-stream (streaming exec) transport to Connected Machines. The
448
519
  // runner must ALSO advertise Capabilities.op_stream; default off, and legacy
@@ -462,7 +533,7 @@ var SettingsSchema = z.object({
462
533
  selfhostedNatsUrl: z.string().optional(),
463
534
  selfhostedRelayUrl: z.string().optional(),
464
535
  // The HMAC secret the control plane signs the agent's relay PRODUCER token with
465
- // (the `ogr_` envelope threaded into EnrollmentCredentials.relayToken; M8b/dossier
536
+ // (the `ogr_` envelope threaded into EnrollmentCredentials.relayToken; M8b/design
466
537
  // §10.5). The relay verifies the producer token with the SAME secret. Optional:
467
538
  // when ABSENT the poll returns an empty relayToken (graceful degrade — the stream
468
539
  // plane is simply unavailable until configured). Falls back to streamTokenSecret /
@@ -472,7 +543,7 @@ var SettingsSchema = z.object({
472
543
  // The minisign PUBLIC key the agent pins for self-update verification (handed to
473
544
  // the agent in EnrollmentCredentials; the SECRET key lives only in CI).
474
545
  agentUpdatePublicKey: z.string().optional(),
475
- // --- NATS auth-callout tenancy boundary (bring-your-own-compute M-AUTH; dossier
546
+ // --- NATS auth-callout tenancy boundary (bring-your-own-compute M-AUTH; design
476
547
  // §10.1 NATS Accounts per workspace + §17 the isolation smoke) -------------
477
548
  // nats-server is configured with AUTH CALLOUT: an external agent connects
478
549
  // presenting its `oge_` enrollment bearer as the connect auth-token; the server
@@ -640,14 +711,8 @@ var SettingsSchema = z.object({
640
711
  allowedTools: z.array(z.string().min(1)).optional(),
641
712
  timeoutMs: z.number().int().positive().optional(),
642
713
  cacheToolsList: z.boolean().default(false),
643
- /**
644
- * Human-approval policy for this server's tools, overlaid per-run from a
645
- * session MCP server row (never from OPENGENI_MCP_SERVERS). `true` = all
646
- * tools require approval; a string[] = only the listed UNPREFIXED tool
647
- * names do; absent = auto-run (the historical default). Enforced in the
648
- * runtime by attaching `needsApproval` to the matching MCP tools.
649
- */
650
- requireApproval: z.union([z.boolean(), z.array(z.string().min(1))]).optional(),
714
+ /** Runtime approval policy, overlaid from an attempt-frozen session snapshot. */
715
+ requireApproval: SessionMcpApprovalPolicy.optional(),
651
716
  /**
652
717
  * Extra request headers sent to this MCP server (credential injection
653
718
  * for workspace-enabled capability MCPs). Populated at runtime from
@@ -665,21 +730,163 @@ var ModelPricingSchema = z.object({
665
730
  outputMicrosPerMillionTokens: z.number().int().nonnegative(),
666
731
  marginBps: z.number().int().min(0).max(1e5).optional()
667
732
  });
733
+ var ModelPricingScheduleSchema = z.object({
734
+ default: ModelPricingSchema,
735
+ inputTokenTiers: z.array(
736
+ z.object({
737
+ minimumInputTokens: z.number().int().nonnegative(),
738
+ pricing: ModelPricingSchema
739
+ })
740
+ ).optional()
741
+ }).superRefine((schedule, ctx) => {
742
+ let previous = -1;
743
+ for (const [index, tier] of (schedule.inputTokenTiers ?? []).entries()) {
744
+ if (tier.minimumInputTokens <= previous) {
745
+ ctx.addIssue({
746
+ code: "custom",
747
+ path: ["inputTokenTiers", index, "minimumInputTokens"],
748
+ message: "input-token tier thresholds must be strictly increasing"
749
+ });
750
+ }
751
+ previous = tier.minimumInputTokens;
752
+ }
753
+ });
754
+ var CapabilitySupportV1 = z.enum(["supported", "unsupported", "unknown"]);
755
+ var CapabilityStateV1Schema = z.object({
756
+ upstream: CapabilitySupportV1,
757
+ runnable: z.boolean()
758
+ }).superRefine((state, ctx) => {
759
+ if (state.upstream === "unsupported" && state.runnable) {
760
+ ctx.addIssue({
761
+ code: "custom",
762
+ path: ["runnable"],
763
+ message: "an upstream-unsupported capability cannot be runnable"
764
+ });
765
+ }
766
+ });
767
+ var ModelModalityV1 = z.enum(["text", "image", "audio"]);
768
+ var ModelLatencyModeV1 = z.enum(["standard", "priority", "fast"]);
769
+ var ModelCapabilitiesV1Schema = z.object({
770
+ reasoning: CapabilityStateV1Schema.extend({
771
+ efforts: z.array(ReasoningEffort),
772
+ defaultEffort: ReasoningEffort.nullable(),
773
+ required: z.boolean()
774
+ }),
775
+ functionCalling: CapabilityStateV1Schema,
776
+ structuredOutput: CapabilityStateV1Schema,
777
+ hostedTools: z.object({
778
+ webSearch: CapabilityStateV1Schema,
779
+ xSearch: CapabilityStateV1Schema,
780
+ codeExecution: CapabilityStateV1Schema
781
+ }),
782
+ inputModalities: z.array(ModelModalityV1).min(1),
783
+ outputModalities: z.array(ModelModalityV1).min(1),
784
+ transports: z.object({
785
+ sse: CapabilityStateV1Schema,
786
+ responsesWebSocket: CapabilityStateV1Schema,
787
+ realtimeAudio: CapabilityStateV1Schema
788
+ }),
789
+ latencyModes: z.array(
790
+ z.object({
791
+ id: ModelLatencyModeV1,
792
+ upstream: CapabilitySupportV1,
793
+ runnable: z.boolean(),
794
+ billingMultiplierBps: z.number().int().positive().optional()
795
+ })
796
+ ).min(1)
797
+ }).superRefine((capabilities, ctx) => {
798
+ const efforts = new Set(capabilities.reasoning.efforts);
799
+ if (efforts.size !== capabilities.reasoning.efforts.length) {
800
+ ctx.addIssue({
801
+ code: "custom",
802
+ path: ["reasoning", "efforts"],
803
+ message: "reasoning efforts must be unique"
804
+ });
805
+ }
806
+ if (capabilities.reasoning.defaultEffort !== null && !efforts.has(capabilities.reasoning.defaultEffort)) {
807
+ ctx.addIssue({
808
+ code: "custom",
809
+ path: ["reasoning", "defaultEffort"],
810
+ message: "the default reasoning effort must be one of the supported efforts"
811
+ });
812
+ }
813
+ if (capabilities.reasoning.runnable && capabilities.reasoning.efforts.length === 0) {
814
+ ctx.addIssue({
815
+ code: "custom",
816
+ path: ["reasoning", "efforts"],
817
+ message: "a runnable reasoning capability must declare at least one effort"
818
+ });
819
+ }
820
+ for (const field of ["inputModalities", "outputModalities"]) {
821
+ if (new Set(capabilities[field]).size !== capabilities[field].length) {
822
+ ctx.addIssue({
823
+ code: "custom",
824
+ path: [field],
825
+ message: `${field} must be unique`
826
+ });
827
+ }
828
+ }
829
+ const latencyIds = /* @__PURE__ */ new Set();
830
+ for (const [index, mode] of capabilities.latencyModes.entries()) {
831
+ if (latencyIds.has(mode.id)) {
832
+ ctx.addIssue({
833
+ code: "custom",
834
+ path: ["latencyModes", index, "id"],
835
+ message: "latency mode ids must be unique"
836
+ });
837
+ }
838
+ latencyIds.add(mode.id);
839
+ if (mode.upstream === "unsupported" && mode.runnable) {
840
+ ctx.addIssue({
841
+ code: "custom",
842
+ path: ["latencyModes", index, "runnable"],
843
+ message: "an upstream-unsupported latency mode cannot be runnable"
844
+ });
845
+ }
846
+ }
847
+ });
668
848
  var ModelProviderApi = z.enum(["responses", "chat"]);
669
849
  var RegistryProviderKind = z.enum(["api-key", "codex-subscription"]);
670
850
  var RegistryModelSchema = z.object({
671
851
  id: z.string().min(1),
672
- // model id sent to the provider, e.g. "accounts/fireworks/models/glm-5p2"
852
+ // canonical OpenGeni product id
853
+ upstreamModelId: z.string().min(1).optional(),
854
+ // exact provider slug; defaults to id
855
+ aliases: z.array(z.string().min(1)).optional(),
856
+ // accepted input only; never sent upstream
673
857
  label: z.string().min(1).optional(),
674
858
  // display name; defaults to id
675
859
  contextWindowTokens: z.number().int().positive().optional(),
676
860
  effectiveContextWindowTokens: z.number().int().positive().optional(),
677
861
  autoCompactTokenLimit: z.number().int().positive().optional(),
862
+ // Canonical model-facing function/tool-result policy. The runtime applies
863
+ // the same 1.2x serialization allowance as Codex when materializing output.
864
+ toolOutputTruncationTokens: z.number().int().positive().optional(),
678
865
  reasoningEffort: z.boolean().optional(),
679
- // model accepts a reasoning-effort control
866
+ // legacy compatibility input/projection
680
867
  hostedWebSearch: z.boolean().optional(),
681
- // provider executes the hosted web_search tool for this model
682
- pricing: ModelPricingSchema.optional()
868
+ // legacy compatibility input/projection
869
+ capabilities: ModelCapabilitiesV1Schema.optional(),
870
+ pricing: z.union([ModelPricingSchema, ModelPricingScheduleSchema]).optional(),
871
+ // Reserved normalized contracts are derived by OpenGeni in V1. Generic
872
+ // registry JSON must not opt itself into workspace BYOK or reattribute cost.
873
+ credentialSource: z.never().optional(),
874
+ billing: z.never().optional()
875
+ }).superRefine((model, ctx) => {
876
+ if (model.capabilities && model.reasoningEffort !== void 0 && model.reasoningEffort !== model.capabilities.reasoning.runnable) {
877
+ ctx.addIssue({
878
+ code: "custom",
879
+ path: ["reasoningEffort"],
880
+ message: "legacy reasoningEffort must agree with capabilities.reasoning.runnable"
881
+ });
882
+ }
883
+ if (model.capabilities && model.hostedWebSearch !== void 0 && model.hostedWebSearch !== model.capabilities.hostedTools.webSearch.runnable) {
884
+ ctx.addIssue({
885
+ code: "custom",
886
+ path: ["hostedWebSearch"],
887
+ message: "legacy hostedWebSearch must agree with capabilities.hostedTools.webSearch.runnable"
888
+ });
889
+ }
683
890
  });
684
891
  var RegistryProviderSchema = z.object({
685
892
  kind: RegistryProviderKind.default("api-key"),
@@ -695,6 +902,12 @@ var RegistryProviderSchema = z.object({
695
902
  // ... OR name of the env var holding the key (preferred)
696
903
  defaultQuery: z.record(z.string(), z.string()).optional(),
697
904
  defaultHeaders: z.record(z.string(), z.string()).optional(),
905
+ publicDefaultQueryNames: z.array(z.string().min(1)).optional(),
906
+ publicDefaultHeaderNames: z.array(z.string().min(1)).optional(),
907
+ // V1 derives these from provider kind. Workspace BYOK is deliberately not a
908
+ // registry switch and requires a separately reviewed encrypted broker.
909
+ credentialSource: z.never().optional(),
910
+ billing: z.never().optional(),
698
911
  models: z.array(RegistryModelSchema).min(1)
699
912
  });
700
913
  var IntegrationOAuthClientConfigSchema = z.object({
@@ -831,6 +1044,14 @@ function getSettings() {
831
1044
  temporalHost: optional("OPENGENI_TEMPORAL_HOST"),
832
1045
  temporalNamespace: optional("OPENGENI_TEMPORAL_NAMESPACE"),
833
1046
  temporalTaskQueue: optional("OPENGENI_TEMPORAL_TASK_QUEUE"),
1047
+ temporalTlsEnabled: optional("OPENGENI_TEMPORAL_TLS_ENABLED"),
1048
+ temporalApiKey: optional("OPENGENI_TEMPORAL_API_KEY"),
1049
+ temporalTlsServerName: optional("OPENGENI_TEMPORAL_TLS_SERVER_NAME"),
1050
+ temporalTlsRootCaCertificateBase64: optional(
1051
+ "OPENGENI_TEMPORAL_TLS_ROOT_CA_CERTIFICATE_BASE64"
1052
+ ),
1053
+ temporalTlsClientCertificateBase64: optional("OPENGENI_TEMPORAL_TLS_CLIENT_CERTIFICATE_BASE64"),
1054
+ temporalTlsClientPrivateKeyBase64: optional("OPENGENI_TEMPORAL_TLS_CLIENT_PRIVATE_KEY_BASE64"),
834
1055
  startupDependencyRetryAttempts: optional("OPENGENI_STARTUP_DEPENDENCY_RETRY_ATTEMPTS"),
835
1056
  startupDependencyRetryInitialDelayMs: optional(
836
1057
  "OPENGENI_STARTUP_DEPENDENCY_RETRY_INITIAL_DELAY_MS"
@@ -851,8 +1072,10 @@ function getSettings() {
851
1072
  delegationSecret: optional("OPENGENI_DELEGATION_SECRET"),
852
1073
  streamTokenSecret: optional("OPENGENI_STREAM_TOKEN_SECRET"),
853
1074
  streamControlEnabled: optional("OPENGENI_STREAM_CONTROL_ENABLED"),
1075
+ sessionTurnToolReplacementEnabled: optional("OPENGENI_SESSION_TURN_TOOL_REPLACEMENT_ENABLED"),
854
1076
  toolspaceEnabled: optional("OPENGENI_TOOLSPACE_ENABLED"),
855
1077
  toolspaceMaxCallsPerTurn: optional("OPENGENI_TOOLSPACE_MAX_CALLS_PER_TURN"),
1078
+ ogtoolPackageSpec: optional("OPENGENI_OGTOOL_PACKAGE_SPEC"),
856
1079
  environmentsEncryptionKey: optional("OPENGENI_ENVIRONMENTS_ENCRYPTION_KEY"),
857
1080
  integrationsEnabled: optional("OPENGENI_INTEGRATIONS_ENABLED"),
858
1081
  integrationsStateSecret: optional("OPENGENI_INTEGRATIONS_STATE_SECRET"),
@@ -868,6 +1091,7 @@ function getSettings() {
868
1091
  contextCompactionThresholdRatio: optional("OPENGENI_COMPACTION_THRESHOLD_RATIO"),
869
1092
  contextReservedOutputTokens: optional("OPENGENI_CONTEXT_RESERVED_OUTPUT_TOKENS"),
870
1093
  contextAutoCompactThresholdTokens: optional("OPENGENI_CONTEXT_AUTO_COMPACT_THRESHOLD_TOKENS"),
1094
+ modelToolOutputTruncationTokens: optional("OPENGENI_MODEL_TOOL_OUTPUT_TRUNCATION_TOKENS"),
871
1095
  authRequired: optional("OPENGENI_AUTH_REQUIRED"),
872
1096
  accessKey: optional("OPENGENI_ACCESS_KEY"),
873
1097
  authAllowHealth: optional("OPENGENI_AUTH_ALLOW_HEALTH"),
@@ -888,7 +1112,6 @@ function getSettings() {
888
1112
  codexToolSearchEnabled: optional("OPENGENI_CODEX_TOOL_SEARCH_ENABLED"),
889
1113
  codexCredentialLeasingEnabled: optional("OPENGENI_CODEX_CREDENTIAL_LEASING_ENABLED"),
890
1114
  codexProductSku: optional("OPENGENI_CODEX_PRODUCT_SKU"),
891
- codexRotationNearExhaustionPct: optional("OPENGENI_CODEX_ROTATION_NEAR_EXHAUSTION_PCT"),
892
1115
  openaiReasoningEffort: optional("OPENGENI_OPENAI_REASONING_EFFORT"),
893
1116
  openaiAllowedReasoningEfforts: optional("OPENGENI_OPENAI_ALLOWED_REASONING_EFFORTS"),
894
1117
  openaiResponsesTransport: optional("OPENGENI_OPENAI_RESPONSES_TRANSPORT"),
@@ -966,6 +1189,9 @@ function getSettings() {
966
1189
  vercelTeamId: optional("OPENGENI_VERCEL_TEAM_ID"),
967
1190
  vercelRuntime: optional("OPENGENI_VERCEL_RUNTIME"),
968
1191
  sandboxOwnershipEnabled: optional("OPENGENI_SANDBOX_OWNERSHIP_ENABLED"),
1192
+ rigVerificationLeaseOwnershipEnabled: optional(
1193
+ "OPENGENI_RIG_VERIFICATION_LEASE_OWNERSHIP_ENABLED"
1194
+ ),
969
1195
  sandboxLazyProvisionEnabled: optional("OPENGENI_SANDBOX_LAZY_PROVISION"),
970
1196
  sandboxSelfhostedEnabled: optional("OPENGENI_SANDBOX_SELFHOSTED_ENABLED"),
971
1197
  agentOpStreamEnabled: optional("OPENGENI_AGENT_OP_STREAM_ENABLED"),
@@ -1077,6 +1303,287 @@ function resolveProviderApiKey(provider, source = process.env) {
1077
1303
  }
1078
1304
  return void 0;
1079
1305
  }
1306
+ var HTTP_FIELD_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
1307
+ var CREDENTIAL_LIKE_NAME_PARTS = /* @__PURE__ */ new Set([
1308
+ "apikey",
1309
+ "auth",
1310
+ "authorization",
1311
+ "bearer",
1312
+ "credential",
1313
+ "cookie",
1314
+ "key",
1315
+ "password",
1316
+ "secret",
1317
+ "session",
1318
+ "signature",
1319
+ "token"
1320
+ ]);
1321
+ var REASONING_EFFORT_ORDER = new Map(
1322
+ ReasoningEffort.options.map((effort, index) => [effort, index])
1323
+ );
1324
+ var MODALITY_ORDER = new Map(["text", "image", "audio"].map((value, index) => [value, index]));
1325
+ var LATENCY_MODE_ORDER = new Map(
1326
+ ["standard", "priority", "fast"].map((value, index) => [value, index])
1327
+ );
1328
+ function normalizeRegistryBaseUrl(value, providerId) {
1329
+ const url = new URL(value);
1330
+ if (url.username || url.password) {
1331
+ throw new Error(`provider ${providerId} baseUrl must not contain userinfo`);
1332
+ }
1333
+ if (url.search) {
1334
+ throw new Error(
1335
+ `provider ${providerId} baseUrl must not contain a query; move query entries to defaultQuery`
1336
+ );
1337
+ }
1338
+ if (url.hash) {
1339
+ throw new Error(`provider ${providerId} baseUrl must not contain a fragment`);
1340
+ }
1341
+ return url.toString();
1342
+ }
1343
+ function isCredentialLikeMetadataName(name) {
1344
+ return name.toLowerCase().split(/[-_.]/u).some((part) => CREDENTIAL_LIKE_NAME_PARTS.has(part));
1345
+ }
1346
+ function normalizeHeaderMap(providerId, headers) {
1347
+ if (!headers) {
1348
+ return void 0;
1349
+ }
1350
+ const normalized = {};
1351
+ const rawByNormalized = /* @__PURE__ */ new Map();
1352
+ for (const [rawName, value] of Object.entries(headers)) {
1353
+ if (!HTTP_FIELD_NAME.test(rawName)) {
1354
+ throw new Error(
1355
+ `provider ${providerId} defaultHeaders contains invalid HTTP field name ${JSON.stringify(rawName)}`
1356
+ );
1357
+ }
1358
+ const name = rawName.toLowerCase();
1359
+ const previous = rawByNormalized.get(name);
1360
+ if (previous !== void 0) {
1361
+ throw new Error(
1362
+ `provider ${providerId} defaultHeaders names ${JSON.stringify(previous)} and ${JSON.stringify(rawName)} collide after lowercase normalization`
1363
+ );
1364
+ }
1365
+ if (name === "authorization") {
1366
+ throw new Error(
1367
+ `provider ${providerId} defaultHeaders must not override SDK-managed Authorization`
1368
+ );
1369
+ }
1370
+ rawByNormalized.set(name, rawName);
1371
+ normalized[name] = value;
1372
+ }
1373
+ return normalized;
1374
+ }
1375
+ function normalizePublicHeaderNames(providerId, names, headers) {
1376
+ if (!names) {
1377
+ return void 0;
1378
+ }
1379
+ const normalized = [];
1380
+ const seen = /* @__PURE__ */ new Set();
1381
+ for (const rawName of names) {
1382
+ if (!HTTP_FIELD_NAME.test(rawName)) {
1383
+ throw new Error(
1384
+ `provider ${providerId} publicDefaultHeaderNames contains invalid HTTP field name ${JSON.stringify(rawName)}`
1385
+ );
1386
+ }
1387
+ const name = rawName.toLowerCase();
1388
+ if (seen.has(name)) {
1389
+ throw new Error(
1390
+ `provider ${providerId} publicDefaultHeaderNames contains duplicate normalized name ${JSON.stringify(name)}`
1391
+ );
1392
+ }
1393
+ if (!(name in (headers ?? {}))) {
1394
+ throw new Error(
1395
+ `provider ${providerId} publicDefaultHeaderNames declares absent defaultHeaders entry ${JSON.stringify(name)}`
1396
+ );
1397
+ }
1398
+ if (isCredentialLikeMetadataName(name)) {
1399
+ throw new Error(
1400
+ `provider ${providerId} publicDefaultHeaderNames cannot classify credential-like name ${JSON.stringify(name)} as public`
1401
+ );
1402
+ }
1403
+ seen.add(name);
1404
+ normalized.push(name);
1405
+ }
1406
+ return normalized;
1407
+ }
1408
+ function normalizeQueryMap(providerId, query) {
1409
+ if (!query) {
1410
+ return void 0;
1411
+ }
1412
+ for (const name of Object.keys(query)) {
1413
+ if (!name) {
1414
+ throw new Error(`provider ${providerId} defaultQuery contains an empty name`);
1415
+ }
1416
+ }
1417
+ return { ...query };
1418
+ }
1419
+ function normalizePublicQueryNames(providerId, names, query) {
1420
+ if (!names) {
1421
+ return void 0;
1422
+ }
1423
+ const seen = /* @__PURE__ */ new Set();
1424
+ for (const name of names) {
1425
+ if (seen.has(name)) {
1426
+ throw new Error(
1427
+ `provider ${providerId} publicDefaultQueryNames contains duplicate name ${JSON.stringify(name)}`
1428
+ );
1429
+ }
1430
+ if (!(name in (query ?? {}))) {
1431
+ throw new Error(
1432
+ `provider ${providerId} publicDefaultQueryNames declares absent defaultQuery entry ${JSON.stringify(name)}`
1433
+ );
1434
+ }
1435
+ if (isCredentialLikeMetadataName(name)) {
1436
+ throw new Error(
1437
+ `provider ${providerId} publicDefaultQueryNames cannot classify credential-like name ${JSON.stringify(name)} as public`
1438
+ );
1439
+ }
1440
+ seen.add(name);
1441
+ }
1442
+ return [...names];
1443
+ }
1444
+ function normalizeRegistryProvider(provider) {
1445
+ const defaultHeaders = normalizeHeaderMap(provider.id, provider.defaultHeaders);
1446
+ const defaultQuery = normalizeQueryMap(provider.id, provider.defaultQuery);
1447
+ return {
1448
+ ...provider,
1449
+ baseUrl: normalizeRegistryBaseUrl(provider.baseUrl, provider.id),
1450
+ ...defaultHeaders === void 0 ? {} : { defaultHeaders },
1451
+ ...defaultQuery === void 0 ? {} : { defaultQuery },
1452
+ ...provider.publicDefaultHeaderNames === void 0 ? {} : {
1453
+ publicDefaultHeaderNames: normalizePublicHeaderNames(
1454
+ provider.id,
1455
+ provider.publicDefaultHeaderNames,
1456
+ defaultHeaders
1457
+ )
1458
+ },
1459
+ ...provider.publicDefaultQueryNames === void 0 ? {} : {
1460
+ publicDefaultQueryNames: normalizePublicQueryNames(
1461
+ provider.id,
1462
+ provider.publicDefaultQueryNames,
1463
+ defaultQuery
1464
+ )
1465
+ }
1466
+ };
1467
+ }
1468
+ function normalizeModelPricingSchedule(pricing) {
1469
+ return "default" in pricing ? pricing : { default: pricing };
1470
+ }
1471
+ function normalizeCapabilities(capabilities) {
1472
+ const parsed = ModelCapabilitiesV1Schema.parse(capabilities);
1473
+ return {
1474
+ ...parsed,
1475
+ reasoning: {
1476
+ ...parsed.reasoning,
1477
+ efforts: [...parsed.reasoning.efforts].sort(
1478
+ (left, right) => (REASONING_EFFORT_ORDER.get(left) ?? 0) - (REASONING_EFFORT_ORDER.get(right) ?? 0)
1479
+ )
1480
+ },
1481
+ inputModalities: [...parsed.inputModalities].sort(
1482
+ (left, right) => (MODALITY_ORDER.get(left) ?? 0) - (MODALITY_ORDER.get(right) ?? 0)
1483
+ ),
1484
+ outputModalities: [...parsed.outputModalities].sort(
1485
+ (left, right) => (MODALITY_ORDER.get(left) ?? 0) - (MODALITY_ORDER.get(right) ?? 0)
1486
+ ),
1487
+ latencyModes: [...parsed.latencyModes].sort(
1488
+ (left, right) => (LATENCY_MODE_ORDER.get(left.id) ?? 0) - (LATENCY_MODE_ORDER.get(right.id) ?? 0)
1489
+ )
1490
+ };
1491
+ }
1492
+ function legacyModelCapabilities(settings, input) {
1493
+ const reasoningEfforts = input.reasoningEffort ? configuredAllowedReasoningEfforts(settings) : [];
1494
+ return normalizeCapabilities({
1495
+ reasoning: {
1496
+ upstream: input.reasoningEffort ? "supported" : "unknown",
1497
+ runnable: input.reasoningEffort,
1498
+ efforts: reasoningEfforts,
1499
+ defaultEffort: input.reasoningEffort ? settings.openaiReasoningEffort : null,
1500
+ required: false
1501
+ },
1502
+ functionCalling: { upstream: "unknown", runnable: true },
1503
+ structuredOutput: { upstream: "unknown", runnable: false },
1504
+ hostedTools: {
1505
+ webSearch: {
1506
+ upstream: input.hostedWebSearch ? "supported" : "unknown",
1507
+ runnable: input.hostedWebSearch
1508
+ },
1509
+ xSearch: { upstream: "unknown", runnable: false },
1510
+ codeExecution: { upstream: "unknown", runnable: false }
1511
+ },
1512
+ inputModalities: ["text"],
1513
+ outputModalities: ["text"],
1514
+ transports: {
1515
+ sse: { upstream: "unknown", runnable: true },
1516
+ responsesWebSocket: { upstream: "unknown", runnable: false },
1517
+ realtimeAudio: { upstream: "unknown", runnable: false }
1518
+ },
1519
+ latencyModes: [{ id: "standard", upstream: "unknown", runnable: true }]
1520
+ });
1521
+ }
1522
+ function registryCredentialSource(provider) {
1523
+ return provider.kind === "codex-subscription" ? { kind: "connected_subscription", provider: "codex" } : { kind: "deployment", mechanism: "api_key" };
1524
+ }
1525
+ function registryBilling(provider) {
1526
+ return provider.kind === "codex-subscription" ? { upstreamPayer: "connected_subscription", metering: "external" } : { upstreamPayer: "deployment", metering: "opengeni_credits" };
1527
+ }
1528
+ function builtinCredentialSource(settings) {
1529
+ if (settings.openaiProvider === "azure" && !settings.azureOpenaiApiKey) {
1530
+ return { kind: "deployment", mechanism: "azure_ad_bearer" };
1531
+ }
1532
+ return { kind: "deployment", mechanism: "api_key" };
1533
+ }
1534
+ function staticRequestMetadataForDigest(provider) {
1535
+ const publicHeaders = new Set(provider.publicDefaultHeaderNames ?? []);
1536
+ const publicQuery = new Set(provider.publicDefaultQueryNames ?? []);
1537
+ return {
1538
+ headers: Object.entries(provider.defaultHeaders ?? {}).sort(([left], [right]) => left.localeCompare(right)).map(
1539
+ ([name, value]) => publicHeaders.has(name) ? { name, classification: "public", value } : { name, classification: "secret" }
1540
+ ),
1541
+ query: Object.entries(provider.defaultQuery ?? {}).sort(([left], [right]) => left.localeCompare(right)).map(
1542
+ ([name, value]) => publicQuery.has(name) ? { name, classification: "public", value } : { name, classification: "secret" }
1543
+ )
1544
+ };
1545
+ }
1546
+ function canonicalJson(value) {
1547
+ const normalize = (input) => {
1548
+ if (Array.isArray(input)) {
1549
+ return input.map((entry) => normalize(entry));
1550
+ }
1551
+ if (input && typeof input === "object") {
1552
+ const out = {};
1553
+ for (const key of Object.keys(input).sort()) {
1554
+ const child = input[key];
1555
+ if (child !== void 0) {
1556
+ out[key] = normalize(child);
1557
+ }
1558
+ }
1559
+ return out;
1560
+ }
1561
+ return input;
1562
+ };
1563
+ return JSON.stringify(normalize(value));
1564
+ }
1565
+ function definitionVersionFor(model, provider) {
1566
+ const requestMetadata = staticRequestMetadataForDigest(provider);
1567
+ const digestInput = canonicalJson({
1568
+ schemaVersion: model.schemaVersion,
1569
+ id: model.id,
1570
+ providerId: model.providerId,
1571
+ deployment: model.deployment,
1572
+ provider: {
1573
+ adapterKind: provider.kind,
1574
+ wireApi: provider.api,
1575
+ baseUrl: provider.baseUrl ?? null,
1576
+ defaultHeaders: requestMetadata.headers,
1577
+ defaultQuery: requestMetadata.query
1578
+ },
1579
+ credentialSource: model.credentialSource,
1580
+ billing: model.billing,
1581
+ executionLimits: model.executionLimits,
1582
+ capabilities: model.capabilities,
1583
+ pricing: model.pricing ?? null
1584
+ });
1585
+ return `sha256:${createHash("sha256").update("opengeni:model-definition:v1\n", "utf8").update(digestInput, "utf8").digest("hex")}`;
1586
+ }
1080
1587
  function builtinProviderId(settings) {
1081
1588
  return settings.openaiProvider === "azure" ? "azure" : "openai";
1082
1589
  }
@@ -1084,18 +1591,22 @@ function builtinProviderLabel(settings) {
1084
1591
  return settings.openaiProvider === "azure" ? "Azure OpenAI" : "OpenAI";
1085
1592
  }
1086
1593
  function configuredProviders(settings) {
1594
+ const credentialSource = builtinCredentialSource(settings);
1087
1595
  const builtin = {
1088
1596
  id: builtinProviderId(settings),
1089
1597
  label: builtinProviderLabel(settings),
1090
1598
  kind: "api-key",
1091
1599
  api: "responses",
1092
- builtin: true
1600
+ builtin: true,
1601
+ credentialSource,
1602
+ billing: { upstreamPayer: "deployment", metering: "opengeni_credits" }
1093
1603
  };
1094
1604
  if (settings.openaiProvider === "azure") {
1095
- builtin.baseUrl = settings.azureOpenaiBaseUrl ?? settings.azureOpenaiEndpoint;
1605
+ const baseUrl = settings.azureOpenaiBaseUrl ?? settings.azureOpenaiEndpoint;
1606
+ builtin.baseUrl = baseUrl ? normalizeRegistryBaseUrl(baseUrl, builtin.id) : void 0;
1096
1607
  builtin.apiKey = settings.azureOpenaiApiKey ?? settings.azureOpenaiAdToken;
1097
1608
  } else {
1098
- builtin.baseUrl = settings.openaiBaseUrl;
1609
+ builtin.baseUrl = settings.openaiBaseUrl ? normalizeRegistryBaseUrl(settings.openaiBaseUrl, builtin.id) : void 0;
1099
1610
  builtin.apiKey = settings.openaiApiKey;
1100
1611
  }
1101
1612
  const registry = parseModelProvidersJson(settings.modelProvidersJson).map(
@@ -1108,71 +1619,195 @@ function configuredProviders(settings) {
1108
1619
  baseUrl: provider.baseUrl,
1109
1620
  apiKey: resolveProviderApiKey(provider),
1110
1621
  defaultQuery: provider.defaultQuery,
1111
- defaultHeaders: provider.defaultHeaders
1622
+ defaultHeaders: provider.defaultHeaders,
1623
+ publicDefaultQueryNames: provider.publicDefaultQueryNames,
1624
+ publicDefaultHeaderNames: provider.publicDefaultHeaderNames,
1625
+ credentialSource: registryCredentialSource(provider),
1626
+ billing: registryBilling(provider)
1112
1627
  })
1113
1628
  );
1114
1629
  return [builtin, ...registry];
1115
1630
  }
1631
+ function withCodexCatalogProvider(settings) {
1632
+ const providers = parseModelProvidersJson(settings.modelProvidersJson);
1633
+ if (providers.some((provider2) => provider2.id === CODEX_PROVIDER_ID)) {
1634
+ return settings;
1635
+ }
1636
+ const provider = {
1637
+ kind: "codex-subscription",
1638
+ id: CODEX_PROVIDER_ID,
1639
+ label: "Codex (ChatGPT subscription)",
1640
+ api: "responses",
1641
+ baseUrl: CODEX_PROVIDER_BASE_URL,
1642
+ models: CODEX_FALLBACK_MODEL_SLUGS.map((slug) => ({
1643
+ id: `${CODEX_MODEL_ID_PREFIX}${slug}`,
1644
+ upstreamModelId: slug,
1645
+ label: slug,
1646
+ reasoningEffort: true,
1647
+ contextWindowTokens: CODEX_MODEL_CONTEXT_WINDOW_TOKENS,
1648
+ effectiveContextWindowTokens: CODEX_MODEL_EFFECTIVE_CONTEXT_WINDOW_TOKENS,
1649
+ autoCompactTokenLimit: CODEX_MODEL_AUTO_COMPACT_TOKEN_LIMIT,
1650
+ toolOutputTruncationTokens: CODEX_MODEL_TOOL_OUTPUT_TRUNCATION_TOKENS
1651
+ }))
1652
+ };
1653
+ return { ...settings, modelProvidersJson: JSON.stringify([...providers, provider]) };
1654
+ }
1116
1655
  function policyProviderIdForModel(settings, modelId) {
1117
- if (modelId.startsWith(CODEX_MODEL_ID_PREFIX)) {
1656
+ const canonicalModelId = canonicalizeConfiguredModelId(settings, modelId);
1657
+ if (canonicalModelId.startsWith(CODEX_MODEL_ID_PREFIX)) {
1118
1658
  return CODEX_PROVIDER_ID;
1119
1659
  }
1120
- const configured = configuredModels(settings).find((model) => model.id === modelId);
1660
+ const configured = configuredModels(settings).find((model) => model.id === canonicalModelId);
1121
1661
  return configured?.providerId ?? builtinProviderId(settings);
1122
1662
  }
1663
+ function resolvedExecutionLimits(settings, model) {
1664
+ return {
1665
+ contextWindowTokens: model.contextWindowTokens ?? settings.contextWindowTokens,
1666
+ effectiveContextWindowTokens: model.effectiveContextWindowTokens ?? settings.contextEffectiveWindowTokens ?? null,
1667
+ autoCompactTokenLimit: model.autoCompactTokenLimit ?? settings.contextAutoCompactThresholdTokens ?? null,
1668
+ toolOutputTruncationTokens: model.toolOutputTruncationTokens ?? settings.modelToolOutputTruncationTokens ?? null
1669
+ };
1670
+ }
1671
+ function finalizeConfiguredModel(settings, provider, input) {
1672
+ const modelWithoutVersion = {
1673
+ schemaVersion: 1,
1674
+ ...input,
1675
+ executionLimits: resolvedExecutionLimits(settings, input)
1676
+ };
1677
+ return {
1678
+ ...modelWithoutVersion,
1679
+ definitionVersion: definitionVersionFor(modelWithoutVersion, provider)
1680
+ };
1681
+ }
1682
+ function assertUniqueModelIdentities(models) {
1683
+ const canonicalOwners = /* @__PURE__ */ new Map();
1684
+ for (const model of models) {
1685
+ const previous = canonicalOwners.get(model.id);
1686
+ if (previous !== void 0) {
1687
+ throw new Error(
1688
+ `OPENGENI_MODEL_PROVIDERS_JSON model id ${JSON.stringify(model.id)} is declared by both ${previous} and ${model.providerId}`
1689
+ );
1690
+ }
1691
+ canonicalOwners.set(model.id, model.providerId);
1692
+ }
1693
+ const acceptedInputs = new Map(canonicalOwners);
1694
+ for (const model of models) {
1695
+ const ownAliases = /* @__PURE__ */ new Set();
1696
+ for (const alias of model.aliases) {
1697
+ if (ownAliases.has(alias)) {
1698
+ throw new Error(
1699
+ `OPENGENI_MODEL_PROVIDERS_JSON model ${JSON.stringify(model.id)} contains duplicate alias ${JSON.stringify(alias)}`
1700
+ );
1701
+ }
1702
+ ownAliases.add(alias);
1703
+ const previous = acceptedInputs.get(alias);
1704
+ if (previous !== void 0) {
1705
+ throw new Error(
1706
+ `OPENGENI_MODEL_PROVIDERS_JSON alias ${JSON.stringify(alias)} for model ${JSON.stringify(model.id)} collides with model/provider ${previous}`
1707
+ );
1708
+ }
1709
+ acceptedInputs.set(alias, model.id);
1710
+ }
1711
+ }
1712
+ }
1123
1713
  function configuredModels(settings) {
1124
1714
  const builtinId = builtinProviderId(settings);
1125
1715
  const builtinLabel = builtinProviderLabel(settings);
1716
+ const providers = configuredProviders(settings);
1717
+ const providerById = new Map(providers.map((provider) => [provider.id, provider]));
1718
+ const pricingSchedules = configuredModelPricingSchedules(settings);
1719
+ const parsedRegistry = parseModelProvidersJson(settings.modelProvidersJson);
1126
1720
  const registryOwnedIds = new Set(
1127
- parseModelProvidersJson(settings.modelProvidersJson).flatMap(
1128
- (provider) => provider.models.map((model) => model.id)
1129
- )
1721
+ parsedRegistry.flatMap((provider) => provider.models.map((model) => model.id))
1130
1722
  );
1131
- const isRegistryNamespaced = (id) => id.startsWith(CODEX_MODEL_ID_PREFIX) || id.includes("/") && registryOwnedIds.has(id);
1723
+ const registryAliases = new Set(
1724
+ parsedRegistry.flatMap((provider) => provider.models.flatMap((model) => model.aliases ?? []))
1725
+ );
1726
+ const isRegistryNamespaced = (id) => id.startsWith(CODEX_MODEL_ID_PREFIX) || registryAliases.has(id) || id.includes("/") && registryOwnedIds.has(id);
1727
+ const builtinProvider = providerById.get(builtinId);
1728
+ if (!builtinProvider) {
1729
+ throw new Error(`Built-in model provider ${builtinId} is not configured`);
1730
+ }
1132
1731
  const out = uniqueValues([
1133
1732
  settings.openaiModel,
1134
1733
  ...splitCsv(settings.openaiAllowedModels)
1135
- ]).filter((id) => !isRegistryNamespaced(id)).map((id) => ({
1136
- id,
1137
- label: id,
1138
- providerId: builtinId,
1139
- providerLabel: builtinLabel,
1140
- api: "responses",
1141
- contextWindowTokens: settings.contextWindowTokens,
1142
- reasoningEffort: true,
1143
- hostedWebSearch: settings.webSearchEnabled
1144
- }));
1145
- for (const provider of parseModelProvidersJson(settings.modelProvidersJson)) {
1734
+ ]).filter((id) => !isRegistryNamespaced(id)).map((id) => {
1735
+ const capabilities = legacyModelCapabilities(settings, {
1736
+ reasoningEffort: true,
1737
+ hostedWebSearch: settings.webSearchEnabled
1738
+ });
1739
+ return finalizeConfiguredModel(settings, builtinProvider, {
1740
+ id,
1741
+ aliases: [],
1742
+ label: id,
1743
+ providerId: builtinId,
1744
+ providerLabel: builtinLabel,
1745
+ api: "responses",
1746
+ upstreamModelId: id,
1747
+ deployment: { upstreamModelId: id, wireApi: "responses" },
1748
+ credentialSource: builtinProvider.credentialSource,
1749
+ billing: builtinProvider.billing,
1750
+ capabilities,
1751
+ ...pricingSchedules[id] === void 0 ? {} : { pricing: pricingSchedules[id] },
1752
+ contextWindowTokens: settings.contextWindowTokens,
1753
+ toolOutputTruncationTokens: settings.modelToolOutputTruncationTokens,
1754
+ reasoningEffort: capabilities.reasoning.runnable,
1755
+ hostedWebSearch: capabilities.hostedTools.webSearch.runnable
1756
+ });
1757
+ });
1758
+ for (const provider of parsedRegistry) {
1146
1759
  const providerLabel = provider.label ?? provider.id;
1760
+ const resolvedProvider = providerById.get(provider.id);
1761
+ if (!resolvedProvider) {
1762
+ throw new Error(`Registry model provider ${provider.id} is not configured`);
1763
+ }
1147
1764
  for (const model of provider.models) {
1148
- out.push({
1149
- id: model.id,
1150
- label: model.label ?? model.id,
1151
- providerId: provider.id,
1152
- providerLabel,
1153
- api: provider.api,
1154
- ...model.contextWindowTokens === void 0 ? {} : { contextWindowTokens: model.contextWindowTokens },
1155
- ...model.effectiveContextWindowTokens === void 0 ? {} : { effectiveContextWindowTokens: model.effectiveContextWindowTokens },
1156
- ...model.autoCompactTokenLimit === void 0 ? {} : { autoCompactTokenLimit: model.autoCompactTokenLimit },
1765
+ const capabilities = model.capabilities ? normalizeCapabilities(model.capabilities) : legacyModelCapabilities(settings, {
1157
1766
  reasoningEffort: model.reasoningEffort ?? false,
1158
1767
  hostedWebSearch: model.hostedWebSearch ?? false
1159
1768
  });
1769
+ const upstreamModelId = model.upstreamModelId ?? model.id;
1770
+ out.push(
1771
+ finalizeConfiguredModel(settings, resolvedProvider, {
1772
+ id: model.id,
1773
+ aliases: [...model.aliases ?? []],
1774
+ label: model.label ?? model.id,
1775
+ providerId: provider.id,
1776
+ providerLabel,
1777
+ api: provider.api,
1778
+ upstreamModelId,
1779
+ deployment: { upstreamModelId, wireApi: provider.api },
1780
+ credentialSource: resolvedProvider.credentialSource,
1781
+ billing: resolvedProvider.billing,
1782
+ capabilities,
1783
+ ...pricingSchedules[model.id] === void 0 ? {} : { pricing: pricingSchedules[model.id] },
1784
+ ...model.contextWindowTokens === void 0 ? {} : { contextWindowTokens: model.contextWindowTokens },
1785
+ ...model.effectiveContextWindowTokens === void 0 ? {} : { effectiveContextWindowTokens: model.effectiveContextWindowTokens },
1786
+ ...model.autoCompactTokenLimit === void 0 ? {} : { autoCompactTokenLimit: model.autoCompactTokenLimit },
1787
+ ...model.toolOutputTruncationTokens === void 0 ? {} : { toolOutputTruncationTokens: model.toolOutputTruncationTokens },
1788
+ reasoningEffort: capabilities.reasoning.runnable,
1789
+ hostedWebSearch: capabilities.hostedTools.webSearch.runnable
1790
+ })
1791
+ );
1160
1792
  }
1161
1793
  }
1162
- const seen = /* @__PURE__ */ new Set();
1163
- return out.filter((model) => {
1164
- if (seen.has(model.id)) {
1165
- return false;
1166
- }
1167
- seen.add(model.id);
1168
- return true;
1169
- });
1794
+ assertUniqueModelIdentities(out);
1795
+ return out;
1796
+ }
1797
+ function canonicalizeConfiguredModelId(settings, modelId) {
1798
+ const models = configuredModels(settings);
1799
+ const canonical = models.find((model) => model.id === modelId);
1800
+ if (canonical) {
1801
+ return canonical.id;
1802
+ }
1803
+ return models.find((model) => model.aliases.includes(modelId))?.id ?? modelId;
1170
1804
  }
1171
1805
  function configuredAllowedModels(settings) {
1172
1806
  return configuredModels(settings).map((model) => model.id);
1173
1807
  }
1174
1808
  function resolveModelProvider(settings, modelId) {
1175
- const model = configuredModels(settings).find((candidate) => candidate.id === modelId);
1809
+ const canonicalModelId = canonicalizeConfiguredModelId(settings, modelId);
1810
+ const model = configuredModels(settings).find((candidate) => candidate.id === canonicalModelId);
1176
1811
  if (!model) {
1177
1812
  return void 0;
1178
1813
  }
@@ -1184,22 +1819,97 @@ function resolveModelProvider(settings, modelId) {
1184
1819
  }
1185
1820
  return { provider, model };
1186
1821
  }
1187
- function configuredModelPricing(settings) {
1822
+ function settingsForTurnExecutionPolicy(settings, modelId) {
1823
+ return settings.codexSubscriptionEnabled && modelId.startsWith(CODEX_MODEL_ID_PREFIX) ? withCodexCatalogProvider(settings) : settings;
1824
+ }
1825
+ function resolveTurnExecutionPolicyV1(settings, input) {
1826
+ const catalogSettings = settingsForTurnExecutionPolicy(settings, input.modelId);
1827
+ const productModelId = canonicalizeConfiguredModelId(catalogSettings, input.modelId);
1828
+ const resolved = resolveModelProvider(catalogSettings, productModelId);
1829
+ if (!resolved) {
1830
+ throw new Error("Turn execution policy model is not present in the configured catalog");
1831
+ }
1832
+ if (input.requestedModelId !== null && canonicalizeConfiguredModelId(catalogSettings, input.requestedModelId) !== productModelId) {
1833
+ throw new Error("Turn execution policy requested model does not canonicalize to its product");
1834
+ }
1835
+ return TurnExecutionPolicyV1.parse({
1836
+ schemaVersion: 1,
1837
+ productModelId,
1838
+ requestedModelId: input.requestedModelId,
1839
+ modelSource: input.modelSource,
1840
+ reasoningEffort: input.reasoningEffort,
1841
+ reasoningSource: input.reasoningSource,
1842
+ providerId: resolved.provider.id,
1843
+ upstreamModelId: resolved.model.upstreamModelId,
1844
+ wireApi: resolved.model.api,
1845
+ credentialSource: resolved.model.credentialSource,
1846
+ billing: resolved.model.billing,
1847
+ definitionVersion: resolved.model.definitionVersion
1848
+ });
1849
+ }
1850
+ function assertTurnExecutionPolicyMatchesConfigV1(settings, policy, expected) {
1851
+ const parsed = TurnExecutionPolicyV1.parse(policy);
1852
+ const catalogSettings = settingsForTurnExecutionPolicy(settings, parsed.productModelId);
1853
+ const canonicalExpectedModel = canonicalizeConfiguredModelId(catalogSettings, expected.modelId);
1854
+ if (parsed.productModelId !== canonicalExpectedModel || parsed.reasoningEffort !== expected.reasoningEffort) {
1855
+ throw new Error("Turn execution policy does not match the accepted turn model/reasoning");
1856
+ }
1857
+ if (parsed.requestedModelId !== null && canonicalizeConfiguredModelId(catalogSettings, parsed.requestedModelId) !== parsed.productModelId) {
1858
+ throw new Error("Turn execution policy requested model does not match its product model");
1859
+ }
1860
+ const resolved = resolveModelProvider(catalogSettings, parsed.productModelId);
1861
+ if (!resolved) {
1862
+ throw new Error("Turn execution policy model is no longer configured");
1863
+ }
1864
+ const mismatched = parsed.providerId !== resolved.provider.id || parsed.upstreamModelId !== resolved.model.upstreamModelId || parsed.wireApi !== resolved.model.api || parsed.definitionVersion !== resolved.model.definitionVersion || canonicalJson(parsed.credentialSource) !== canonicalJson(resolved.model.credentialSource) || canonicalJson(parsed.billing) !== canonicalJson(resolved.model.billing);
1865
+ if (mismatched) {
1866
+ throw new Error("Turn execution policy does not match the current provider definition");
1867
+ }
1868
+ return { policy: parsed, provider: resolved.provider, model: resolved.model };
1869
+ }
1870
+ function configuredModelPricingSchedules(settings) {
1871
+ const defaults = Object.fromEntries(
1872
+ Object.entries(defaultModelPricing).map(([model, pricing]) => [model, { default: pricing }])
1873
+ );
1188
1874
  const registry = {};
1189
1875
  for (const provider of parseModelProvidersJson(settings.modelProvidersJson)) {
1190
1876
  for (const model of provider.models) {
1191
1877
  if (model.pricing) {
1192
- registry[model.id] = model.pricing;
1878
+ registry[model.id] = normalizeModelPricingSchedule(model.pricing);
1193
1879
  }
1194
1880
  }
1195
1881
  }
1196
- const configured = parseModelPricingJson(settings.modelPricingJson);
1882
+ const configured = Object.fromEntries(
1883
+ Object.entries(parseModelPricingJson(settings.modelPricingJson)).map(([model, pricing]) => [
1884
+ model,
1885
+ { default: pricing }
1886
+ ])
1887
+ );
1197
1888
  return {
1198
- ...defaultModelPricing,
1889
+ ...defaults,
1199
1890
  ...registry,
1200
1891
  ...configured
1201
1892
  };
1202
1893
  }
1894
+ function configuredModelPricing(settings) {
1895
+ return Object.fromEntries(
1896
+ Object.entries(configuredModelPricingSchedules(settings)).map(([model, schedule]) => [
1897
+ model,
1898
+ schedule.default
1899
+ ])
1900
+ );
1901
+ }
1902
+ function selectModelPricing(schedule, inputTokens) {
1903
+ const normalizedInputTokens = Math.max(0, Math.floor(inputTokens));
1904
+ let selected = schedule.default;
1905
+ for (const tier of schedule.inputTokenTiers ?? []) {
1906
+ if (normalizedInputTokens < tier.minimumInputTokens) {
1907
+ break;
1908
+ }
1909
+ selected = tier.pricing;
1910
+ }
1911
+ return selected;
1912
+ }
1203
1913
  function contextInputBudgetTokens(settings) {
1204
1914
  if (settings.contextEffectiveWindowTokens !== void 0) {
1205
1915
  return Math.min(settings.contextWindowTokens, settings.contextEffectiveWindowTokens);
@@ -1217,7 +1927,8 @@ function settingsWithResolvedModelContext(settings, model) {
1217
1927
  model.effectiveContextWindowTokens
1218
1928
  )
1219
1929
  },
1220
- ...model.autoCompactTokenLimit === void 0 ? {} : { contextAutoCompactThresholdTokens: model.autoCompactTokenLimit }
1930
+ ...model.autoCompactTokenLimit === void 0 ? {} : { contextAutoCompactThresholdTokens: model.autoCompactTokenLimit },
1931
+ ...model.toolOutputTruncationTokens === void 0 ? {} : { modelToolOutputTruncationTokens: model.toolOutputTruncationTokens }
1221
1932
  };
1222
1933
  }
1223
1934
  function configuredStaticUsageLimits(settings) {
@@ -1241,14 +1952,25 @@ function configuredEntitlements(settings) {
1241
1952
  };
1242
1953
  }
1243
1954
  function calculateModelUsageCostMicros(settings, model, usage) {
1244
- const pricing = configuredModelPricing(settings)[model];
1245
- if (!pricing) {
1955
+ const schedule = configuredModelPricingSchedules(settings)[model];
1956
+ if (!schedule) {
1246
1957
  throw new Error(`Missing model pricing for ${model}`);
1247
1958
  }
1248
1959
  const entries = usage.requestUsageEntries && usage.requestUsageEntries.length > 0 ? usage.requestUsageEntries : [usage];
1249
- const rawCost = entries.reduce((sum, entry) => sum + calculateEntryCostMicros(pricing, entry), 0);
1250
- const marginBps = pricing.marginBps ?? 0;
1251
- return Math.ceil(rawCost * (1e4 + marginBps) / 1e4);
1960
+ const rawCostByPricing = /* @__PURE__ */ new Map();
1961
+ for (const entry of entries) {
1962
+ const pricing = selectModelPricing(schedule, positiveInt(entry.inputTokens));
1963
+ rawCostByPricing.set(
1964
+ pricing,
1965
+ (rawCostByPricing.get(pricing) ?? 0) + calculateEntryCostMicros(pricing, entry)
1966
+ );
1967
+ }
1968
+ let total = 0;
1969
+ for (const [pricing, rawCost] of rawCostByPricing) {
1970
+ const marginBps = pricing.marginBps ?? 0;
1971
+ total += Math.ceil(rawCost * (1e4 + marginBps) / 1e4);
1972
+ }
1973
+ return total;
1252
1974
  }
1253
1975
  function configuredAllowedReasoningEfforts(settings) {
1254
1976
  return uniqueValues([
@@ -1268,6 +1990,59 @@ function environmentsEncryptionKeyBytes(settings) {
1268
1990
  }
1269
1991
  return new Uint8Array(decoded);
1270
1992
  }
1993
+ function temporalConnectionOptions(settings) {
1994
+ const apiKey = settings.temporalApiKey?.trim() || void 0;
1995
+ const serverNameOverride = settings.temporalTlsServerName?.trim() || void 0;
1996
+ const rootCa = decodeTemporalTlsMaterial(
1997
+ settings.temporalTlsRootCaCertificateBase64,
1998
+ "OPENGENI_TEMPORAL_TLS_ROOT_CA_CERTIFICATE_BASE64"
1999
+ );
2000
+ const clientCertificate = decodeTemporalTlsMaterial(
2001
+ settings.temporalTlsClientCertificateBase64,
2002
+ "OPENGENI_TEMPORAL_TLS_CLIENT_CERTIFICATE_BASE64"
2003
+ );
2004
+ const clientPrivateKey = decodeTemporalTlsMaterial(
2005
+ settings.temporalTlsClientPrivateKeyBase64,
2006
+ "OPENGENI_TEMPORAL_TLS_CLIENT_PRIVATE_KEY_BASE64"
2007
+ );
2008
+ if (Boolean(clientCertificate) !== Boolean(clientPrivateKey)) {
2009
+ throw new Error(
2010
+ "OPENGENI_TEMPORAL_TLS_CLIENT_CERTIFICATE_BASE64 and OPENGENI_TEMPORAL_TLS_CLIENT_PRIVATE_KEY_BASE64 must both be set or both omitted"
2011
+ );
2012
+ }
2013
+ const tls = {};
2014
+ if (serverNameOverride) {
2015
+ tls.serverNameOverride = serverNameOverride;
2016
+ }
2017
+ if (rootCa) {
2018
+ tls.serverRootCACertificate = rootCa;
2019
+ }
2020
+ if (clientCertificate && clientPrivateKey) {
2021
+ tls.clientCertPair = { crt: clientCertificate, key: clientPrivateKey };
2022
+ }
2023
+ const hasCustomTls = Object.keys(tls).length > 0;
2024
+ const tlsEnabled = settings.temporalTlsEnabled || Boolean(apiKey) || hasCustomTls;
2025
+ return {
2026
+ address: settings.temporalHost,
2027
+ ...tlsEnabled ? { tls: hasCustomTls ? tls : true } : {},
2028
+ ...apiKey ? { apiKey } : {}
2029
+ };
2030
+ }
2031
+ function decodeTemporalTlsMaterial(value, settingName) {
2032
+ const encoded = value?.replace(/\s/g, "");
2033
+ if (!encoded) {
2034
+ return void 0;
2035
+ }
2036
+ if (!/^[A-Za-z0-9+/]+={0,2}$/.test(encoded) || encoded.length % 4 === 1) {
2037
+ throw new Error(`${settingName} must contain valid base64`);
2038
+ }
2039
+ const decoded = Buffer.from(encoded, "base64");
2040
+ const canonical = decoded.toString("base64").replace(/=+$/, "");
2041
+ if (decoded.length === 0 || canonical !== encoded.replace(/=+$/, "")) {
2042
+ throw new Error(`${settingName} must contain valid base64`);
2043
+ }
2044
+ return new Uint8Array(decoded);
2045
+ }
1271
2046
  function dbSearchPath(settings) {
1272
2047
  const schema = settings.dbSchema?.trim();
1273
2048
  if (!schema) {
@@ -1315,6 +2090,9 @@ function stableSandboxEnvironmentForRun(settings, workspaceEnvironment = {}, opt
1315
2090
  }
1316
2091
  if (settings.toolspaceEnabled) {
1317
2092
  environment.OPENGENI_TOOLSPACE_TOKEN_FILE ??= `${environment.HOME ?? descriptor.workspaceRoot}/.opengeni/toolspace-token`;
2093
+ if (settings.ogtoolPackageSpec) {
2094
+ environment.OPENGENI_OGTOOL_PACKAGE_SPEC ??= settings.ogtoolPackageSpec;
2095
+ }
1318
2096
  if (options.workspaceId) {
1319
2097
  environment.OPENGENI_TOOLSPACE_URL ??= firstPartyMcpWorkspaceUrl(
1320
2098
  settings,
@@ -1516,7 +2294,14 @@ function parseModelProvidersJson(raw) {
1516
2294
  `OPENGENI_MODEL_PROVIDERS_JSON provider[${index}] is invalid: ${result.error.message}`
1517
2295
  );
1518
2296
  }
1519
- return result.data;
2297
+ try {
2298
+ return normalizeRegistryProvider(result.data);
2299
+ } catch (error) {
2300
+ const message = error instanceof Error ? error.message : String(error);
2301
+ throw new Error(`OPENGENI_MODEL_PROVIDERS_JSON provider[${index}] is invalid: ${message}`, {
2302
+ cause: error
2303
+ });
2304
+ }
1520
2305
  });
1521
2306
  }
1522
2307
  function parseIntegrationsOauthClientsJson(raw) {
@@ -1675,6 +2460,7 @@ function firstPartyDocumentsMcpServerUrl(mcpUrl) {
1675
2460
  return `${mcpUrl.replace(/\/+$/, "")}/docs`;
1676
2461
  }
1677
2462
  function validateSettings(settings) {
2463
+ temporalConnectionOptions(settings);
1678
2464
  if (settings.toolspaceEnabled && !settings.delegationSecret) {
1679
2465
  throw new Error("OPENGENI_DELEGATION_SECRET is required when OPENGENI_TOOLSPACE_ENABLED=true");
1680
2466
  }
@@ -1921,6 +2707,7 @@ function validateSettings(settings) {
1921
2707
  );
1922
2708
  }
1923
2709
  }
2710
+ configuredModels(settings);
1924
2711
  }
1925
2712
  function resolveStreamTokenSecret(settings) {
1926
2713
  const explicit = settings.streamTokenSecret?.trim();
@@ -2006,21 +2793,27 @@ function delay(ms) {
2006
2793
  }
2007
2794
  export {
2008
2795
  AGENT_INSTRUCTIONS_CORE_PLACEHOLDER,
2796
+ CapabilityStateV1Schema,
2797
+ CapabilitySupportV1,
2009
2798
  DEFAULT_AGENT_INSTRUCTIONS,
2010
2799
  IntegrationOAuthClientConfigSchema,
2011
2800
  McpServerConnectionRefSchema,
2801
+ ModelCapabilitiesV1Schema,
2012
2802
  ModelProviderApi,
2013
2803
  RegistryProviderKind,
2014
2804
  SANDBOX_REQUIRED_ENV,
2015
2805
  applyGitAuthPointerEnvironment,
2806
+ assertTurnExecutionPolicyMatchesConfigV1,
2016
2807
  builtinProviderId,
2017
2808
  calculateModelUsageCostMicros,
2809
+ canonicalizeConfiguredModelId,
2018
2810
  collectGitIdentityEnvironment,
2019
2811
  collectSandboxEnvironment,
2020
2812
  configuredAllowedModels,
2021
2813
  configuredAllowedReasoningEfforts,
2022
2814
  configuredEntitlements,
2023
2815
  configuredModelPricing,
2816
+ configuredModelPricingSchedules,
2024
2817
  configuredModels,
2025
2818
  configuredProviders,
2026
2819
  configuredStaticUsageLimits,
@@ -2051,14 +2844,18 @@ export {
2051
2844
  resolveProviderApiKey,
2052
2845
  resolveRelayTokenSecret,
2053
2846
  resolveStreamTokenSecret,
2847
+ resolveTurnExecutionPolicyV1,
2054
2848
  retryStartupDependency,
2055
2849
  sandboxEnvironmentVariableNames,
2056
2850
  sandboxLifecycleHookIds,
2057
2851
  sandboxPreparationProfiles,
2058
2852
  sandboxWarmRateMicrosPerSecond,
2853
+ selectModelPricing,
2059
2854
  settingsWithResolvedModelContext,
2060
2855
  stableSandboxEnvironmentForRun,
2061
2856
  startupRetryOptions,
2062
- streamTokenDegraded
2857
+ streamTokenDegraded,
2858
+ temporalConnectionOptions,
2859
+ withCodexCatalogProvider
2063
2860
  };
2064
2861
  //# sourceMappingURL=index.js.map