@opengeni/config 0.9.3 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -163,6 +163,7 @@ declare const SettingsSchema: z.ZodObject<{
163
163
  openaiBaseUrl: z.ZodOptional<z.ZodString>;
164
164
  openaiModel: z.ZodDefault<z.ZodString>;
165
165
  openaiAllowedModels: z.ZodDefault<z.ZodString>;
166
+ vercelAiGatewayApiKey: z.ZodOptional<z.ZodString>;
166
167
  voiceInputMaxDurationSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
167
168
  voiceInputMaxSizeBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
168
169
  voiceInputProviderOrder: z.ZodDefault<z.ZodString>;
@@ -233,6 +234,7 @@ declare const SettingsSchema: z.ZodObject<{
233
234
  dockerWorkspaceBaseDir: z.ZodOptional<z.ZodString>;
234
235
  modalAppName: z.ZodDefault<z.ZodString>;
235
236
  modalImageRef: z.ZodOptional<z.ZodString>;
237
+ modalImageId: z.ZodOptional<z.ZodString>;
236
238
  modalImageRegistrySecret: z.ZodOptional<z.ZodString>;
237
239
  modalTimeoutSeconds: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
238
240
  modalTokenId: z.ZodOptional<z.ZodString>;
@@ -619,6 +621,19 @@ export declare const ModelCapabilitiesV1Schema: z.ZodObject<{
619
621
  runnable: z.ZodBoolean;
620
622
  }, z.core.$strip>;
621
623
  }, z.core.$strip>;
624
+ promptCaching: z.ZodOptional<z.ZodObject<{
625
+ upstream: z.ZodEnum<{
626
+ supported: "supported";
627
+ unknown: "unknown";
628
+ unsupported: "unsupported";
629
+ }>;
630
+ runnable: z.ZodBoolean;
631
+ mode: z.ZodEnum<{
632
+ automatic: "automatic";
633
+ implicit: "implicit";
634
+ none: "none";
635
+ }>;
636
+ }, z.core.$strip>>;
622
637
  latencyModes: z.ZodArray<z.ZodObject<{
623
638
  id: z.ZodEnum<{
624
639
  fast: "fast";
@@ -679,6 +694,8 @@ export type ModelProviderApi = z.infer<typeof ModelProviderApi>;
679
694
  export declare const RegistryProviderKind: z.ZodEnum<{
680
695
  "api-key": "api-key";
681
696
  "codex-subscription": "codex-subscription";
697
+ "vercel-gateway-managed": "vercel-gateway-managed";
698
+ "vercel-gateway-workspace": "vercel-gateway-workspace";
682
699
  }>;
683
700
  export type RegistryProviderKind = z.infer<typeof RegistryProviderKind>;
684
701
  /** A non-built-in provider declared by the host via OPENGENI_MODEL_PROVIDERS_JSON. */
@@ -686,6 +703,8 @@ declare const RegistryProviderSchema: z.ZodObject<{
686
703
  kind: z.ZodDefault<z.ZodEnum<{
687
704
  "api-key": "api-key";
688
705
  "codex-subscription": "codex-subscription";
706
+ "vercel-gateway-managed": "vercel-gateway-managed";
707
+ "vercel-gateway-workspace": "vercel-gateway-workspace";
689
708
  }>>;
690
709
  id: z.ZodString;
691
710
  label: z.ZodOptional<z.ZodString>;
@@ -817,6 +836,19 @@ declare const RegistryProviderSchema: z.ZodObject<{
817
836
  runnable: z.ZodBoolean;
818
837
  }, z.core.$strip>;
819
838
  }, z.core.$strip>;
839
+ promptCaching: z.ZodOptional<z.ZodObject<{
840
+ upstream: z.ZodEnum<{
841
+ supported: "supported";
842
+ unknown: "unknown";
843
+ unsupported: "unsupported";
844
+ }>;
845
+ runnable: z.ZodBoolean;
846
+ mode: z.ZodEnum<{
847
+ automatic: "automatic";
848
+ implicit: "implicit";
849
+ none: "none";
850
+ }>;
851
+ }, z.core.$strip>>;
820
852
  latencyModes: z.ZodArray<z.ZodObject<{
821
853
  id: z.ZodEnum<{
822
854
  fast: "fast";
@@ -906,6 +938,12 @@ export interface ConfiguredModel {
906
938
  credentialSource: CredentialSourceV1;
907
939
  billing: BillingAttributionV1;
908
940
  capabilities: ModelCapabilitiesV1;
941
+ requestPolicy?: {
942
+ gateway: {
943
+ only: [string];
944
+ caching: "auto" | "none";
945
+ };
946
+ };
909
947
  pricing?: ModelPricingScheduleV1 | undefined;
910
948
  definitionVersion: string;
911
949
  contextWindowTokens?: number | undefined;
@@ -915,6 +953,30 @@ export interface ConfiguredModel {
915
953
  reasoningEffort: boolean;
916
954
  hostedWebSearch: boolean;
917
955
  }
956
+ export declare const VERCEL_AI_GATEWAY_BASE_URL: "https://ai-gateway.vercel.sh/v1";
957
+ export declare const OPENGENI_GATEWAY_PROVIDER_ID: "opengeni-gateway";
958
+ export declare const WORKSPACE_GATEWAY_PROVIDER_ID: "workspace-gateway";
959
+ export declare const WORKSPACE_GATEWAY_MODEL_ID_PREFIX: "workspace-gateway/";
960
+ export declare const VERCEL_AI_GATEWAY_CONNECTION_DOMAIN: "ai-gateway.vercel.sh";
961
+ export declare const VERCEL_AI_GATEWAY_CONNECTION_ROLE: "vercel_ai_gateway";
962
+ export declare const OPENGENI_GATEWAY_MODELS: {
963
+ readonly deepseek: {
964
+ readonly productId: "deepseek-v4-flash-0731";
965
+ readonly workspaceProductId: "workspace-gateway/deepseek-v4-flash-0731";
966
+ readonly upstreamModelId: "deepseek/deepseek-v4-flash-0731";
967
+ readonly label: "DeepSeek V4 Flash 0731";
968
+ readonly provider: "deepinfra";
969
+ readonly implicitCaching: true;
970
+ };
971
+ readonly kimi: {
972
+ readonly productId: "kimi-k3-fast";
973
+ readonly workspaceProductId: "workspace-gateway/kimi-k3-fast";
974
+ readonly upstreamModelId: "moonshotai/kimi-k3-fast";
975
+ readonly label: "Kimi K3 Fast";
976
+ readonly provider: "wafer";
977
+ readonly implicitCaching: true;
978
+ };
979
+ };
918
980
  /**
919
981
  * Built-in OpenGeni credit pricing schedules.
920
982
  *
@@ -976,6 +1038,11 @@ export declare function collectSandboxEnvironment(settings: Settings, source?: N
976
1038
  * explicit environment in tests.
977
1039
  */
978
1040
  export declare function resolveProviderApiKey(provider: Pick<RegistryProvider, "apiKey" | "apiKeyEnv">, source?: NodeJS.ProcessEnv): string | undefined;
1041
+ export declare function gatewayRequestPolicyForUpstreamModel(upstreamModelId: string): ConfiguredModel["requestPolicy"];
1042
+ /** Static catalog overlay; it contains no concrete workspace credential. */
1043
+ export declare function withWorkspaceGatewayCatalogProvider(settings: Settings): Settings;
1044
+ /** Runtime overlay after the worker resolves the workspace's encrypted key. */
1045
+ export declare function withWorkspaceGatewayCredential(settings: Settings, apiKey: string): Settings;
979
1046
  /**
980
1047
  * Product display label for catalog/picker UI.
981
1048
  * Same string for OpenAI and Codex copies of a slug (`gpt-5.6-luna` and
package/dist/index.js CHANGED
@@ -292,6 +292,10 @@ var SettingsSchema = z.object({
292
292
  openaiBaseUrl: z.string().optional(),
293
293
  openaiModel: z.string().default("gpt-5.6-sol"),
294
294
  openaiAllowedModels: z.string().default("gpt-5.6-sol,gpt-5.6-terra,gpt-5.6-luna"),
295
+ // OpenGeni-managed Vercel AI Gateway. When configured, the two reviewed
296
+ // Gateway models below are added to the managed-credit catalog. Workspace
297
+ // Gateway keys use the encrypted connection broker and never this secret.
298
+ vercelAiGatewayApiKey: z.string().optional(),
295
299
  // Native composer voice input (browser MediaRecorder → API transcription).
296
300
  // Provider credentials stay server-side; ClientConfig only projects availability
297
301
  // and hard ceilings. Selection happens once before audio is sent — never retry
@@ -415,6 +419,12 @@ var SettingsSchema = z.object({
415
419
  dockerWorkspaceBaseDir: z.string().min(1).optional(),
416
420
  modalAppName: z.string().default("opengeni-sandbox"),
417
421
  modalImageRef: z.string().optional(),
422
+ // Provider-native immutable Modal image ID for the exact logical
423
+ // `modalImageRef`. When set, the runtime uses ModalImageSelector.fromId and
424
+ // never asks Modal to parse or import the registry ref. The logical ref is
425
+ // still persisted on the sandbox lease for provenance and conflict fencing;
426
+ // the Modal session envelope persists the actual image ID.
427
+ modalImageId: z.string().regex(/^im-[A-Za-z0-9]{22}$/).optional(),
418
428
  // Name of a Modal Secret (containing REGISTRY_USERNAME + REGISTRY_PASSWORD) used
419
429
  // to authenticate the pull of `modalImageRef` from a PRIVATE registry. When UNSET
420
430
  // (the default), the sandbox image is pulled UNAUTHENTICATED — i.e. it must be a
@@ -959,6 +969,9 @@ var ModelCapabilitiesV1Schema = z.object({
959
969
  responsesWebSocket: CapabilityStateV1Schema,
960
970
  realtimeAudio: CapabilityStateV1Schema
961
971
  }),
972
+ promptCaching: CapabilityStateV1Schema.extend({
973
+ mode: z.enum(["implicit", "automatic", "none"])
974
+ }).optional(),
962
975
  latencyModes: z.array(
963
976
  z.object({
964
977
  id: ModelLatencyModeV1,
@@ -1019,7 +1032,12 @@ var ModelCapabilitiesV1Schema = z.object({
1019
1032
  }
1020
1033
  });
1021
1034
  var ModelProviderApi = z.enum(["responses", "chat"]);
1022
- var RegistryProviderKind = z.enum(["api-key", "codex-subscription"]);
1035
+ var RegistryProviderKind = z.enum([
1036
+ "api-key",
1037
+ "codex-subscription",
1038
+ "vercel-gateway-managed",
1039
+ "vercel-gateway-workspace"
1040
+ ]);
1023
1041
  var RegistryModelSchema = z.object({
1024
1042
  id: z.string().min(1),
1025
1043
  // canonical OpenGeni product id
@@ -1063,7 +1081,6 @@ var RegistryModelSchema = z.object({
1063
1081
  });
1064
1082
  var RegistryProviderSchema = z.object({
1065
1083
  kind: RegistryProviderKind.default("api-key"),
1066
- // "codex-subscription" => per-request token, no static key
1067
1084
  id: z.string().min(1).regex(registryId),
1068
1085
  // stable provider id, e.g. "fireworks"
1069
1086
  label: z.string().min(1).optional(),
@@ -1088,6 +1105,30 @@ var IntegrationOAuthClientConfigSchema = z.object({
1088
1105
  clientSecret: z.string().min(1).optional(),
1089
1106
  tokenEndpointAuthMethod: z.enum(["none", "client_secret_post", "client_secret_basic"]).default("none")
1090
1107
  });
1108
+ var VERCEL_AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh/v1";
1109
+ var OPENGENI_GATEWAY_PROVIDER_ID = "opengeni-gateway";
1110
+ var WORKSPACE_GATEWAY_PROVIDER_ID = "workspace-gateway";
1111
+ var WORKSPACE_GATEWAY_MODEL_ID_PREFIX = "workspace-gateway/";
1112
+ var VERCEL_AI_GATEWAY_CONNECTION_DOMAIN = "ai-gateway.vercel.sh";
1113
+ var VERCEL_AI_GATEWAY_CONNECTION_ROLE = "vercel_ai_gateway";
1114
+ var OPENGENI_GATEWAY_MODELS = {
1115
+ deepseek: {
1116
+ productId: "deepseek-v4-flash-0731",
1117
+ workspaceProductId: `${WORKSPACE_GATEWAY_MODEL_ID_PREFIX}deepseek-v4-flash-0731`,
1118
+ upstreamModelId: "deepseek/deepseek-v4-flash-0731",
1119
+ label: "DeepSeek V4 Flash 0731",
1120
+ provider: "deepinfra",
1121
+ implicitCaching: true
1122
+ },
1123
+ kimi: {
1124
+ productId: "kimi-k3-fast",
1125
+ workspaceProductId: `${WORKSPACE_GATEWAY_MODEL_ID_PREFIX}kimi-k3-fast`,
1126
+ upstreamModelId: "moonshotai/kimi-k3-fast",
1127
+ label: "Kimi K3 Fast",
1128
+ provider: "wafer",
1129
+ implicitCaching: true
1130
+ }
1131
+ };
1091
1132
  var defaultModelPricing = {
1092
1133
  "gpt-5.6-sol": {
1093
1134
  default: {
@@ -1147,6 +1188,27 @@ var defaultModelPricing = {
1147
1188
  }
1148
1189
  ]
1149
1190
  },
1191
+ // Vercel AI Gateway endpoint prices, provider-pinned in the runtime.
1192
+ // Snapshot: 2026-08-02. Both pinned routes returned discounted implicit
1193
+ // cache reads in live Gateway responses. Wafer/Kimi reported $0.45/M even
1194
+ // though the provider-discovery flag currently says otherwise; bill from
1195
+ // the response-backed rate, not that inconsistent boolean.
1196
+ [OPENGENI_GATEWAY_MODELS.deepseek.productId]: {
1197
+ default: {
1198
+ inputMicrosPerMillionTokens: 9e4,
1199
+ cachedInputMicrosPerMillionTokens: 18e3,
1200
+ outputMicrosPerMillionTokens: 18e4,
1201
+ marginBps: 2500
1202
+ }
1203
+ },
1204
+ [OPENGENI_GATEWAY_MODELS.kimi.productId]: {
1205
+ default: {
1206
+ inputMicrosPerMillionTokens: 45e5,
1207
+ cachedInputMicrosPerMillionTokens: 45e4,
1208
+ outputMicrosPerMillionTokens: 225e5,
1209
+ marginBps: 2500
1210
+ }
1211
+ },
1150
1212
  // Fireworks AI / GLM 5.2 — the first shipped non-OpenAI registry model. A
1151
1213
  // built-in default pricing entry makes managed billing work out of the box
1152
1214
  // for hosts that expose this model via OPENGENI_MODEL_PROVIDERS_JSON without
@@ -1286,6 +1348,7 @@ function getSettings() {
1286
1348
  openaiBaseUrl: optional("OPENGENI_OPENAI_BASE_URL") ?? optional("OPENAI_BASE_URL"),
1287
1349
  openaiModel: optional("OPENGENI_OPENAI_MODEL"),
1288
1350
  openaiAllowedModels: optional("OPENGENI_OPENAI_ALLOWED_MODELS"),
1351
+ vercelAiGatewayApiKey: optional("OPENGENI_VERCEL_AI_GATEWAY_API_KEY"),
1289
1352
  voiceInputMaxDurationSeconds: optional("OPENGENI_VOICE_INPUT_MAX_DURATION_SECONDS"),
1290
1353
  voiceInputMaxSizeBytes: optional("OPENGENI_VOICE_INPUT_MAX_SIZE_BYTES"),
1291
1354
  voiceInputProviderOrder: optional("OPENGENI_VOICE_INPUT_PROVIDER_ORDER"),
@@ -1330,6 +1393,7 @@ function getSettings() {
1330
1393
  dockerWorkspaceBaseDir: optional("OPENGENI_DOCKER_WORKSPACE_BASE_DIR"),
1331
1394
  modalAppName: optional("OPENGENI_MODAL_APP_NAME"),
1332
1395
  modalImageRef: optional("OPENGENI_MODAL_IMAGE_REF"),
1396
+ modalImageId: optional("OPENGENI_MODAL_IMAGE_ID"),
1333
1397
  modalImageRegistrySecret: optional("OPENGENI_MODAL_IMAGE_REGISTRY_SECRET"),
1334
1398
  modalTimeoutSeconds: optional("OPENGENI_MODAL_TIMEOUT_SECONDS"),
1335
1399
  modalTokenId: optional("OPENGENI_MODAL_TOKEN_ID"),
@@ -1736,6 +1800,108 @@ function legacyModelCapabilities(settings, input) {
1736
1800
  latencyModes: [{ id: "standard", upstream: "unknown", runnable: true }]
1737
1801
  });
1738
1802
  }
1803
+ function gatewayRequestPolicyForUpstreamModel(upstreamModelId) {
1804
+ const model = Object.values(OPENGENI_GATEWAY_MODELS).find(
1805
+ (candidate) => candidate.upstreamModelId === upstreamModelId
1806
+ );
1807
+ if (!model) {
1808
+ return void 0;
1809
+ }
1810
+ return {
1811
+ gateway: {
1812
+ only: [model.provider],
1813
+ caching: model.implicitCaching ? "auto" : "none"
1814
+ }
1815
+ };
1816
+ }
1817
+ function gatewayModelCapabilities(settings, input) {
1818
+ const legacy = legacyModelCapabilities(settings, {
1819
+ reasoningEffort: true,
1820
+ hostedWebSearch: false
1821
+ });
1822
+ return normalizeCapabilities({
1823
+ ...legacy,
1824
+ functionCalling: { upstream: "supported", runnable: true },
1825
+ inputModalities: input.vision ? ["text", "image"] : ["text"],
1826
+ transports: {
1827
+ ...legacy.transports,
1828
+ sse: { upstream: "supported", runnable: true }
1829
+ },
1830
+ promptCaching: input.implicitCaching ? { upstream: "supported", runnable: true, mode: "implicit" } : { upstream: "unsupported", runnable: false, mode: "none" },
1831
+ // "Fast" is part of Kimi's product name, not OpenGeni's separately billed
1832
+ // latency mode. Both Gateway products expose only standard here.
1833
+ latencyModes: [{ id: "standard", upstream: "supported", runnable: true }]
1834
+ });
1835
+ }
1836
+ function gatewayRegistryProvider(settings, input) {
1837
+ const workspace = input.kind === "vercel-gateway-workspace";
1838
+ const models = [OPENGENI_GATEWAY_MODELS.deepseek, OPENGENI_GATEWAY_MODELS.kimi].map((model) => ({
1839
+ id: workspace ? model.workspaceProductId : model.productId,
1840
+ upstreamModelId: model.upstreamModelId,
1841
+ label: model.label,
1842
+ capabilities: gatewayModelCapabilities(settings, {
1843
+ implicitCaching: model.implicitCaching,
1844
+ vision: model === OPENGENI_GATEWAY_MODELS.kimi
1845
+ }),
1846
+ contextWindowTokens: 1e6,
1847
+ effectiveContextWindowTokens: 9e5,
1848
+ autoCompactTokenLimit: 85e4,
1849
+ toolOutputTruncationTokens: settings.modelToolOutputTruncationTokens
1850
+ }));
1851
+ return {
1852
+ kind: input.kind,
1853
+ id: workspace ? WORKSPACE_GATEWAY_PROVIDER_ID : OPENGENI_GATEWAY_PROVIDER_ID,
1854
+ label: workspace ? "Your Gateway" : "OpenGeni",
1855
+ // Responses preserves vision, reasoning items, and provider-native usage.
1856
+ // Model-specific compatibility stays at the reviewed request fence rather
1857
+ // than downgrading the whole provider wire.
1858
+ api: "responses",
1859
+ baseUrl: VERCEL_AI_GATEWAY_BASE_URL,
1860
+ ...input.apiKey ? { apiKey: input.apiKey } : {},
1861
+ models
1862
+ };
1863
+ }
1864
+ function configuredRegistryProviders(settings) {
1865
+ const providers = parseModelProvidersJson(settings.modelProvidersJson);
1866
+ if (!settings.vercelAiGatewayApiKey) {
1867
+ return providers;
1868
+ }
1869
+ if (providers.some((provider) => provider.id === OPENGENI_GATEWAY_PROVIDER_ID)) {
1870
+ throw new Error(
1871
+ `${OPENGENI_GATEWAY_PROVIDER_ID} is reserved for OPENGENI_VERCEL_AI_GATEWAY_API_KEY`
1872
+ );
1873
+ }
1874
+ return [
1875
+ ...providers,
1876
+ gatewayRegistryProvider(settings, {
1877
+ kind: "vercel-gateway-managed",
1878
+ apiKey: settings.vercelAiGatewayApiKey
1879
+ })
1880
+ ];
1881
+ }
1882
+ function withWorkspaceGatewayCatalogProvider(settings) {
1883
+ const providers = parseModelProvidersJson(settings.modelProvidersJson);
1884
+ if (providers.some((provider) => provider.id === WORKSPACE_GATEWAY_PROVIDER_ID)) {
1885
+ return settings;
1886
+ }
1887
+ return {
1888
+ ...settings,
1889
+ modelProvidersJson: JSON.stringify([
1890
+ ...providers,
1891
+ gatewayRegistryProvider(settings, { kind: "vercel-gateway-workspace" })
1892
+ ])
1893
+ };
1894
+ }
1895
+ function withWorkspaceGatewayCredential(settings, apiKey) {
1896
+ if (!apiKey.trim()) {
1897
+ throw new Error("workspace AI Gateway credential is empty");
1898
+ }
1899
+ const catalogSettings = withWorkspaceGatewayCatalogProvider(settings);
1900
+ const providers = parseModelProvidersJson(catalogSettings.modelProvidersJson).map(
1901
+ (provider) => provider.id === WORKSPACE_GATEWAY_PROVIDER_ID ? { ...provider, apiKey } : provider
1902
+ );
1903
+ return { ...catalogSettings, modelProvidersJson: JSON.stringify(providers) };
1904
+ }
1739
1905
  var GPT56_FAST_BILLING_MULTIPLIER_BPS = 2e4;
1740
1906
  function productLabelForModelId(modelId) {
1741
1907
  const slug = modelId.startsWith(CODEX_MODEL_ID_PREFIX) ? modelId.slice(CODEX_MODEL_ID_PREFIX.length) : modelId;
@@ -1765,6 +1931,10 @@ function builtinLatencyModesForModel(modelId) {
1765
1931
  }
1766
1932
  return [{ id: "standard", upstream: "unknown", runnable: true }];
1767
1933
  }
1934
+ function builtinPromptCachingForModel(modelId) {
1935
+ const slug = modelId.startsWith(CODEX_MODEL_ID_PREFIX) ? modelId.slice(CODEX_MODEL_ID_PREFIX.length) : modelId;
1936
+ return slug.startsWith("gpt-5.6-") ? { upstream: "supported", runnable: true, mode: "implicit" } : void 0;
1937
+ }
1768
1938
  function serviceTierForLatencyMode(providerId, latencyMode) {
1769
1939
  if (latencyMode === "standard") {
1770
1940
  return void 0;
@@ -1799,10 +1969,22 @@ function assertLatencyModeRunnable(settings, modelId, latencyMode) {
1799
1969
  }
1800
1970
  }
1801
1971
  function registryCredentialSource(provider) {
1802
- return provider.kind === "codex-subscription" ? { kind: "connected_subscription", provider: "codex" } : { kind: "deployment", mechanism: "api_key" };
1972
+ if (provider.kind === "codex-subscription") {
1973
+ return { kind: "connected_subscription", provider: "codex" };
1974
+ }
1975
+ if (provider.kind === "vercel-gateway-workspace") {
1976
+ return { kind: "workspace_connection", mechanism: "api_key" };
1977
+ }
1978
+ return { kind: "deployment", mechanism: "api_key" };
1803
1979
  }
1804
1980
  function registryBilling(provider) {
1805
- return provider.kind === "codex-subscription" ? { upstreamPayer: "connected_subscription", metering: "external" } : { upstreamPayer: "deployment", metering: "opengeni_credits" };
1981
+ if (provider.kind === "codex-subscription") {
1982
+ return { upstreamPayer: "connected_subscription", metering: "external" };
1983
+ }
1984
+ if (provider.kind === "vercel-gateway-workspace") {
1985
+ return { upstreamPayer: "workspace", metering: "external" };
1986
+ }
1987
+ return { upstreamPayer: "deployment", metering: "opengeni_credits" };
1806
1988
  }
1807
1989
  function builtinCredentialSource(settings) {
1808
1990
  if (settings.openaiProvider === "azure" && !settings.azureOpenaiApiKey) {
@@ -1859,6 +2041,7 @@ function definitionVersionFor(model, provider) {
1859
2041
  billing: model.billing,
1860
2042
  executionLimits: model.executionLimits,
1861
2043
  capabilities: model.capabilities,
2044
+ ...model.requestPolicy ? { requestPolicy: model.requestPolicy } : {},
1862
2045
  pricing: model.pricing ?? null
1863
2046
  });
1864
2047
  return `sha256:${createHash("sha256").update("opengeni:model-definition:v1\n", "utf8").update(digestInput, "utf8").digest("hex")}`;
@@ -1888,7 +2071,7 @@ function configuredProviders(settings) {
1888
2071
  builtin.baseUrl = settings.openaiBaseUrl ? normalizeRegistryBaseUrl(settings.openaiBaseUrl, builtin.id) : void 0;
1889
2072
  builtin.apiKey = settings.openaiApiKey;
1890
2073
  }
1891
- const registry = parseModelProvidersJson(settings.modelProvidersJson).map(
2074
+ const registry = configuredRegistryProviders(settings).map(
1892
2075
  (provider) => ({
1893
2076
  id: provider.id,
1894
2077
  label: provider.label ?? provider.id,
@@ -1924,6 +2107,9 @@ function withCodexCatalogProvider(settings) {
1924
2107
  reasoningEffort: true,
1925
2108
  hostedWebSearch: true
1926
2109
  }),
2110
+ ...builtinPromptCachingForModel(`${CODEX_MODEL_ID_PREFIX}${slug}`) ? {
2111
+ promptCaching: builtinPromptCachingForModel(`${CODEX_MODEL_ID_PREFIX}${slug}`)
2112
+ } : {},
1927
2113
  latencyModes: builtinLatencyModesForModel(`${CODEX_MODEL_ID_PREFIX}${slug}`)
1928
2114
  };
1929
2115
  return {
@@ -1954,6 +2140,9 @@ function policyProviderIdForModel(settings, modelId) {
1954
2140
  if (canonicalModelId.startsWith(CODEX_MODEL_ID_PREFIX)) {
1955
2141
  return CODEX_PROVIDER_ID;
1956
2142
  }
2143
+ if (canonicalModelId.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX)) {
2144
+ return WORKSPACE_GATEWAY_PROVIDER_ID;
2145
+ }
1957
2146
  const configured = configuredModels(settings).find((model) => model.id === canonicalModelId);
1958
2147
  return configured?.providerId ?? builtinProviderId(settings);
1959
2148
  }
@@ -1966,9 +2155,11 @@ function resolvedExecutionLimits(settings, model) {
1966
2155
  };
1967
2156
  }
1968
2157
  function finalizeConfiguredModel(settings, provider, input) {
2158
+ const requestPolicy = provider.kind === "vercel-gateway-managed" || provider.kind === "vercel-gateway-workspace" ? gatewayRequestPolicyForUpstreamModel(input.upstreamModelId) : void 0;
1969
2159
  const modelWithoutVersion = {
1970
2160
  schemaVersion: 1,
1971
2161
  ...input,
2162
+ ...requestPolicy ? { requestPolicy } : {},
1972
2163
  executionLimits: resolvedExecutionLimits(settings, input)
1973
2164
  };
1974
2165
  return {
@@ -2013,7 +2204,7 @@ function configuredModels(settings) {
2013
2204
  const providers = configuredProviders(settings);
2014
2205
  const providerById = new Map(providers.map((provider) => [provider.id, provider]));
2015
2206
  const pricingSchedules = configuredModelPricingSchedules(settings);
2016
- const parsedRegistry = parseModelProvidersJson(settings.modelProvidersJson);
2207
+ const parsedRegistry = configuredRegistryProviders(settings);
2017
2208
  const registryOwnedIds = new Set(
2018
2209
  parsedRegistry.flatMap((provider) => provider.models.map((model) => model.id))
2019
2210
  );
@@ -2034,6 +2225,7 @@ function configuredModels(settings) {
2034
2225
  reasoningEffort: true,
2035
2226
  hostedWebSearch: settings.webSearchEnabled
2036
2227
  }),
2228
+ ...builtinPromptCachingForModel(id) ? { promptCaching: builtinPromptCachingForModel(id) } : {},
2037
2229
  latencyModes: builtinLatencyModesForModel(id)
2038
2230
  };
2039
2231
  return finalizeConfiguredModel(settings, builtinProvider, {
@@ -2122,7 +2314,13 @@ function resolveModelProvider(settings, modelId) {
2122
2314
  return { provider, model };
2123
2315
  }
2124
2316
  function settingsForTurnExecutionPolicy(settings, modelId) {
2125
- return settings.codexSubscriptionEnabled && modelId.startsWith(CODEX_MODEL_ID_PREFIX) ? withCodexCatalogProvider(settings) : settings;
2317
+ if (settings.codexSubscriptionEnabled && modelId.startsWith(CODEX_MODEL_ID_PREFIX)) {
2318
+ return withCodexCatalogProvider(settings);
2319
+ }
2320
+ if (modelId.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX)) {
2321
+ return withWorkspaceGatewayCatalogProvider(settings);
2322
+ }
2323
+ return settings;
2126
2324
  }
2127
2325
  function resolveTurnExecutionPolicyV1(settings, input) {
2128
2326
  const catalogSettings = settingsForTurnExecutionPolicy(settings, input.modelId);
@@ -2186,7 +2384,7 @@ function configuredModelPricingSchedules(settings) {
2186
2384
  ])
2187
2385
  );
2188
2386
  const registry = {};
2189
- for (const provider of parseModelProvidersJson(settings.modelProvidersJson)) {
2387
+ for (const provider of configuredRegistryProviders(settings)) {
2190
2388
  for (const model of provider.models) {
2191
2389
  if (model.pricing) {
2192
2390
  registry[model.id] = normalizeModelPricingSchedule(model.pricing);
@@ -3125,6 +3323,11 @@ function validateSettings(settings) {
3125
3323
  const builtinId = builtinProviderId(settings);
3126
3324
  const providerIds = /* @__PURE__ */ new Set();
3127
3325
  for (const provider of registryProviders) {
3326
+ if (provider.kind === "vercel-gateway-managed" || provider.kind === "vercel-gateway-workspace") {
3327
+ throw new Error(
3328
+ `OPENGENI_MODEL_PROVIDERS_JSON provider kind ${provider.kind} is reserved for the reviewed AI Gateway broker`
3329
+ );
3330
+ }
3128
3331
  if (provider.id === builtinId) {
3129
3332
  throw new Error(
3130
3333
  `OPENGENI_MODEL_PROVIDERS_JSON provider id ${provider.id} collides with the built-in provider id`
@@ -3136,7 +3339,7 @@ function validateSettings(settings) {
3136
3339
  );
3137
3340
  }
3138
3341
  providerIds.add(provider.id);
3139
- if (!resolveProviderApiKey(provider)) {
3342
+ if (provider.kind !== "codex-subscription" && !resolveProviderApiKey(provider)) {
3140
3343
  throw new Error(
3141
3344
  `OPENGENI_MODEL_PROVIDERS_JSON provider ${provider.id} requires a resolvable API key (set apiKey or apiKeyEnv)`
3142
3345
  );
@@ -3235,9 +3438,16 @@ export {
3235
3438
  McpServerConnectionRefSchema,
3236
3439
  ModelCapabilitiesV1Schema,
3237
3440
  ModelProviderApi,
3441
+ OPENGENI_GATEWAY_MODELS,
3442
+ OPENGENI_GATEWAY_PROVIDER_ID,
3238
3443
  RegistryProviderKind,
3239
3444
  SANDBOX_REQUIRED_ENV,
3240
3445
  SocialOAuthClientConfigSchema,
3446
+ VERCEL_AI_GATEWAY_BASE_URL,
3447
+ VERCEL_AI_GATEWAY_CONNECTION_DOMAIN,
3448
+ VERCEL_AI_GATEWAY_CONNECTION_ROLE,
3449
+ WORKSPACE_GATEWAY_MODEL_ID_PREFIX,
3450
+ WORKSPACE_GATEWAY_PROVIDER_ID,
3241
3451
  applyGitAuthPointerEnvironment,
3242
3452
  assertTurnExecutionPolicyMatchesConfigV1,
3243
3453
  builtinProviderId,
@@ -3260,6 +3470,7 @@ export {
3260
3470
  environmentsEncryptionKeyBytes,
3261
3471
  firstPartyMcpBaseUrl,
3262
3472
  firstPartyMcpWorkspaceUrl,
3473
+ gatewayRequestPolicyForUpstreamModel,
3263
3474
  getSettings,
3264
3475
  hasGitCredentialRepositorySelection,
3265
3476
  hasGitHubRepositorySelection,
@@ -3302,6 +3513,8 @@ export {
3302
3513
  streamTokenDegraded,
3303
3514
  temporalConnectionOptions,
3304
3515
  voiceInputDeploymentConfigured,
3305
- withCodexCatalogProvider
3516
+ withCodexCatalogProvider,
3517
+ withWorkspaceGatewayCatalogProvider,
3518
+ withWorkspaceGatewayCredential
3306
3519
  };
3307
3520
  //# sourceMappingURL=index.js.map