@opengeni/config 0.22.5 → 0.23.2-canary.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.
- package/dist/index.d.ts +707 -20
- package/dist/index.js +995 -125
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +1268 -156
package/dist/index.js
CHANGED
|
@@ -45,6 +45,10 @@ import { createHash } from "crypto";
|
|
|
45
45
|
import { z } from "zod";
|
|
46
46
|
var envName = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
47
47
|
var registryId = /^[A-Za-z0-9_-]+$/;
|
|
48
|
+
var DEFAULT_OPENROUTER_MODEL_ID = "openrouter/nvidia/nemotron-3-super-120b-a12b:free";
|
|
49
|
+
var DEFAULT_MODEL_COST_POLICY_JSON = JSON.stringify({
|
|
50
|
+
[DEFAULT_OPENROUTER_MODEL_ID]: "free"
|
|
51
|
+
});
|
|
48
52
|
var SANDBOX_ARCHIVE_CAPTURE_MAX_TIMEOUT_MS = 60 * 6e4;
|
|
49
53
|
var SANDBOX_ARCHIVE_CAPTURE_SETTLEMENT_GRACE_MS = 1e4;
|
|
50
54
|
var SANDBOX_SNAPSHOT_MAX_TIMEOUT_MS = SANDBOX_ARCHIVE_CAPTURE_MAX_TIMEOUT_MS - SANDBOX_ARCHIVE_CAPTURE_SETTLEMENT_GRACE_MS;
|
|
@@ -177,8 +181,16 @@ var McpServerConnectionRefSchema = z.object({
|
|
|
177
181
|
seen.add(key);
|
|
178
182
|
}
|
|
179
183
|
}).optional(),
|
|
184
|
+
authoritySource: z.literal("host").optional(),
|
|
180
185
|
subjectScope: z.enum(["workspace", "subject"]).optional()
|
|
181
186
|
}).strict().superRefine((reference, context) => {
|
|
187
|
+
if (reference.authoritySource === "host" && !reference.connectionId) {
|
|
188
|
+
context.addIssue({
|
|
189
|
+
code: "custom",
|
|
190
|
+
message: "host authority requires connectionId",
|
|
191
|
+
path: ["connectionId"]
|
|
192
|
+
});
|
|
193
|
+
}
|
|
182
194
|
if (!reference.selectedResources) return;
|
|
183
195
|
if (!reference.connectionId) {
|
|
184
196
|
context.addIssue({
|
|
@@ -384,6 +396,13 @@ var SettingsSchema = z.object({
|
|
|
384
396
|
// into @opengeni/db once at boot.
|
|
385
397
|
// Env: OPENGENI_CHILD_LIFECYCLE_NOTICES_ENABLED.
|
|
386
398
|
childLifecycleNoticesEnabled: EnvBoolean.default(false),
|
|
399
|
+
// Explicit host-owned MCP connection authority is a rolling protocol
|
|
400
|
+
// activation. Keep it off while any API, worker, or browser bundle predates
|
|
401
|
+
// the authority discriminator; enable it only after the whole fleet runs an
|
|
402
|
+
// image that understands host refs. Legacy markerless non-UUID refs remain a
|
|
403
|
+
// separate compatibility lane for already-persisted embedding integrations.
|
|
404
|
+
// Env: OPENGENI_HOST_MCP_AUTHORITY_SOURCE_ADMISSION_ENABLED.
|
|
405
|
+
hostMcpAuthoritySourceAdmissionEnabled: EnvBoolean.default(false),
|
|
387
406
|
// Per-channel and per-DM Slack workspace routing. Default ON. A channel does
|
|
388
407
|
// not count a personal workspace as a candidate, so an organization with one
|
|
389
408
|
// shared workspace resolves it as the sole candidate and never asks; the
|
|
@@ -511,6 +530,24 @@ var SettingsSchema = z.object({
|
|
|
511
530
|
// keep subscription model routing while disabling Codex voice input.
|
|
512
531
|
voiceInputCodexExperimentalEnabled: EnvBoolean.default(false),
|
|
513
532
|
modelPricingJson: z.string().default("{}"),
|
|
533
|
+
// Supported-model membership source. Database mode is resolved by the async
|
|
534
|
+
// core overlay; getSettings remains synchronous and env-only.
|
|
535
|
+
modelCatalogSource: z.enum(["code", "database"]).default("code"),
|
|
536
|
+
// Deployment-owned workspace-facing price policy. This is deliberately
|
|
537
|
+
// separate from catalog membership and upstream credential ownership.
|
|
538
|
+
// Shape: { "product/model-id": "free" | "credits" }.
|
|
539
|
+
modelCostPolicyJson: z.string().default("{}"),
|
|
540
|
+
// Optional per-product agent guidance. Database mode replaces this with the
|
|
541
|
+
// singleton document's validated modelNotes map.
|
|
542
|
+
modelNotesJson: z.string().default("{}"),
|
|
543
|
+
// Managed OpenRouter credential. The curated model table is injected in
|
|
544
|
+
// code/catalog-document resolution and never read from host provider JSON.
|
|
545
|
+
openrouterApiKey: z.string().optional(),
|
|
546
|
+
// Internal, secret-free catalog overlays populated only by
|
|
547
|
+
// applyModelCatalogDocument. They intentionally have no OPENGENI_* env
|
|
548
|
+
// binding so database mode cannot be bypassed with a second source.
|
|
549
|
+
resolvedGatewayModelsJson: z.string().optional(),
|
|
550
|
+
resolvedOpenRouterModelsJson: z.string().optional(),
|
|
514
551
|
// Extra (non-built-in) model providers, declared by the host as a JSON
|
|
515
552
|
// provider registry. Each entry carries its own base URL, API key, wire API
|
|
516
553
|
// ("responses" | "chat") and the models it exposes. The models a client may
|
|
@@ -956,6 +993,13 @@ var SettingsSchema = z.object({
|
|
|
956
993
|
// treated exactly like a failed best-effort snapshot. Knob:
|
|
957
994
|
// OPENGENI_SANDBOX_SNAPSHOT_TIMEOUT_MS. Default 60s.
|
|
958
995
|
sandboxSnapshotTimeoutMs: z.coerce.number().int().positive().max(SANDBOX_SNAPSHOT_MAX_TIMEOUT_MS).default(6e4),
|
|
996
|
+
// A zero-holder drain may need substantially longer than a best-effort
|
|
997
|
+
// mid-turn/turn-end snapshot for a very large workspace. Keep that provider
|
|
998
|
+
// budget independent so increasing drain recovery headroom cannot pin an
|
|
999
|
+
// ordinary turn finalizer for the same duration. Unset preserves the legacy
|
|
1000
|
+
// single-budget behavior. Knob:
|
|
1001
|
+
// OPENGENI_SANDBOX_DRAIN_SNAPSHOT_TIMEOUT_MS.
|
|
1002
|
+
sandboxDrainSnapshotTimeoutMs: z.coerce.number().int().positive().max(SANDBOX_SNAPSHOT_MAX_TIMEOUT_MS).optional(),
|
|
959
1003
|
// Begin a controlled snapshot/quiesce/drain/rematerialize transition this far
|
|
960
1004
|
// ahead of a finite provider deadline. Modal's 24h creation clock cannot be
|
|
961
1005
|
// extended; the logical sandbox outlives it by moving to one successor box.
|
|
@@ -1227,6 +1271,7 @@ function voiceInputDeploymentConfigured(settings) {
|
|
|
1227
1271
|
var ModelPricingSchema = z.object({
|
|
1228
1272
|
inputMicrosPerMillionTokens: z.number().int().nonnegative(),
|
|
1229
1273
|
cachedInputMicrosPerMillionTokens: z.number().int().nonnegative().optional(),
|
|
1274
|
+
cacheWriteMicrosPerMillionTokens: z.number().int().nonnegative().optional(),
|
|
1230
1275
|
outputMicrosPerMillionTokens: z.number().int().nonnegative(),
|
|
1231
1276
|
marginBps: z.number().int().min(0).max(1e5).optional()
|
|
1232
1277
|
});
|
|
@@ -1362,7 +1407,10 @@ var RegistryProviderKind = z.enum([
|
|
|
1362
1407
|
"codex-subscription",
|
|
1363
1408
|
"xai-subscription",
|
|
1364
1409
|
"vercel-gateway-managed",
|
|
1365
|
-
"vercel-gateway-workspace"
|
|
1410
|
+
"vercel-gateway-workspace",
|
|
1411
|
+
"vercel-gateway-organization",
|
|
1412
|
+
"openrouter-workspace",
|
|
1413
|
+
"openrouter-organization"
|
|
1366
1414
|
]);
|
|
1367
1415
|
var RegistryModelSchema = z.object({
|
|
1368
1416
|
id: z.string().min(1),
|
|
@@ -1475,6 +1523,297 @@ var RegistryProviderSchema = z.object({
|
|
|
1475
1523
|
});
|
|
1476
1524
|
}
|
|
1477
1525
|
});
|
|
1526
|
+
var OPENGENI_GATEWAY_PROVIDER_ID = "opengeni-gateway";
|
|
1527
|
+
var WORKSPACE_GATEWAY_PROVIDER_ID = "workspace-gateway";
|
|
1528
|
+
var WORKSPACE_GATEWAY_MODEL_ID_PREFIX = "workspace-gateway/";
|
|
1529
|
+
var ORGANIZATION_GATEWAY_PROVIDER_ID = "organization-gateway";
|
|
1530
|
+
var ORGANIZATION_GATEWAY_MODEL_ID_PREFIX = "organization-gateway/";
|
|
1531
|
+
var OPENROUTER_PROVIDER_ID = "openrouter";
|
|
1532
|
+
var OPENROUTER_MODEL_ID_PREFIX = "openrouter/";
|
|
1533
|
+
var WORKSPACE_OPENROUTER_PROVIDER_ID = "workspace-openrouter";
|
|
1534
|
+
var WORKSPACE_OPENROUTER_MODEL_ID_PREFIX = "workspace-openrouter/";
|
|
1535
|
+
var ORGANIZATION_OPENROUTER_PROVIDER_ID = "organization-openrouter";
|
|
1536
|
+
var ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX = "organization-openrouter/";
|
|
1537
|
+
var OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
|
|
1538
|
+
var RESERVED_MODEL_PROVIDER_IDS = /* @__PURE__ */ new Set([
|
|
1539
|
+
"openai",
|
|
1540
|
+
"azure",
|
|
1541
|
+
CODEX_PROVIDER_ID,
|
|
1542
|
+
XAI_SUBSCRIPTION_PROVIDER_ID,
|
|
1543
|
+
OPENGENI_GATEWAY_PROVIDER_ID,
|
|
1544
|
+
WORKSPACE_GATEWAY_PROVIDER_ID,
|
|
1545
|
+
ORGANIZATION_GATEWAY_PROVIDER_ID,
|
|
1546
|
+
OPENROUTER_PROVIDER_ID,
|
|
1547
|
+
WORKSPACE_OPENROUTER_PROVIDER_ID,
|
|
1548
|
+
ORGANIZATION_OPENROUTER_PROVIDER_ID
|
|
1549
|
+
]);
|
|
1550
|
+
var ModelCostClass = z.enum(["free", "credits"]);
|
|
1551
|
+
var ConfiguredModelCostClass = z.enum([
|
|
1552
|
+
"free",
|
|
1553
|
+
"credits",
|
|
1554
|
+
"subscription",
|
|
1555
|
+
"workspace",
|
|
1556
|
+
"organization"
|
|
1557
|
+
]);
|
|
1558
|
+
var ModelNote = z.string().max(500).refine((value) => !/[\r\n|]/u.test(value), {
|
|
1559
|
+
message: "model notes must not contain newlines or the | field separator"
|
|
1560
|
+
});
|
|
1561
|
+
function parseModelCostPolicyJson(raw) {
|
|
1562
|
+
let parsed;
|
|
1563
|
+
try {
|
|
1564
|
+
parsed = JSON.parse(raw);
|
|
1565
|
+
} catch (error) {
|
|
1566
|
+
throw new Error(
|
|
1567
|
+
`OPENGENI_MODEL_COST_POLICY_JSON must be valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
1568
|
+
{ cause: error }
|
|
1569
|
+
);
|
|
1570
|
+
}
|
|
1571
|
+
return z.record(z.string().min(1), ModelCostClass).parse(parsed);
|
|
1572
|
+
}
|
|
1573
|
+
function parseModelNotesJson(raw) {
|
|
1574
|
+
let parsed;
|
|
1575
|
+
try {
|
|
1576
|
+
parsed = JSON.parse(raw);
|
|
1577
|
+
} catch (error) {
|
|
1578
|
+
throw new Error(
|
|
1579
|
+
`OPENGENI_MODEL_NOTES_JSON must be valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
1580
|
+
{ cause: error }
|
|
1581
|
+
);
|
|
1582
|
+
}
|
|
1583
|
+
return z.record(z.string().min(1), ModelNote).parse(parsed);
|
|
1584
|
+
}
|
|
1585
|
+
function configuredModelNotes(settings) {
|
|
1586
|
+
return parseModelNotesJson(settings.modelNotesJson);
|
|
1587
|
+
}
|
|
1588
|
+
var GatewayCatalogModel = z.object({
|
|
1589
|
+
productId: z.string().min(1),
|
|
1590
|
+
workspaceProductId: z.string().min(1).startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX),
|
|
1591
|
+
upstreamModelId: z.string().min(1),
|
|
1592
|
+
label: z.string().min(1),
|
|
1593
|
+
shortLabel: z.string().min(1).max(64).optional(),
|
|
1594
|
+
providers: z.array(z.string().min(1)).min(1),
|
|
1595
|
+
implicitCaching: z.boolean().default(false),
|
|
1596
|
+
vision: z.boolean().default(false),
|
|
1597
|
+
inputFileMediaTypes: z.array(z.string().min(1)).default([]),
|
|
1598
|
+
contextWindowTokens: z.number().int().positive().default(1e6),
|
|
1599
|
+
effectiveContextWindowTokens: z.number().int().positive().default(9e5),
|
|
1600
|
+
autoCompactTokenLimit: z.number().int().positive().default(85e4),
|
|
1601
|
+
pricing: z.union([ModelPricingSchema, ModelPricingScheduleSchema]).optional(),
|
|
1602
|
+
credentialSource: z.never().optional(),
|
|
1603
|
+
billing: z.never().optional(),
|
|
1604
|
+
apiKey: z.never().optional()
|
|
1605
|
+
}).strict();
|
|
1606
|
+
var OpenRouterCatalogModel = z.object({
|
|
1607
|
+
upstreamModelId: z.string().min(1).endsWith(":free"),
|
|
1608
|
+
label: z.string().min(1),
|
|
1609
|
+
shortLabel: z.string().min(1).max(64).optional(),
|
|
1610
|
+
aliases: z.array(z.string().min(1)).default([]),
|
|
1611
|
+
capabilities: ModelCapabilitiesV1Schema,
|
|
1612
|
+
contextWindowTokens: z.number().int().positive().optional(),
|
|
1613
|
+
effectiveContextWindowTokens: z.number().int().positive().optional(),
|
|
1614
|
+
autoCompactTokenLimit: z.number().int().positive().optional(),
|
|
1615
|
+
toolOutputTruncationTokens: z.number().int().positive().optional(),
|
|
1616
|
+
credentialSource: z.never().optional(),
|
|
1617
|
+
billing: z.never().optional(),
|
|
1618
|
+
pricing: z.never().optional(),
|
|
1619
|
+
apiKey: z.never().optional()
|
|
1620
|
+
}).strict();
|
|
1621
|
+
var DeploymentRegistryBaseUrl = z.string().url().superRefine((value, context) => {
|
|
1622
|
+
const url = new URL(value);
|
|
1623
|
+
if (url.username || url.password) {
|
|
1624
|
+
context.addIssue({
|
|
1625
|
+
code: "custom",
|
|
1626
|
+
message: "database catalog provider baseUrl must not contain userinfo"
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
if (url.search) {
|
|
1630
|
+
context.addIssue({
|
|
1631
|
+
code: "custom",
|
|
1632
|
+
message: "database catalog provider baseUrl must not contain a query"
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
if (url.hash) {
|
|
1636
|
+
context.addIssue({
|
|
1637
|
+
code: "custom",
|
|
1638
|
+
message: "database catalog provider baseUrl must not contain a fragment"
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1641
|
+
});
|
|
1642
|
+
var DeploymentRegistryProviderKind = z.enum(["api-key", "anonymous"]);
|
|
1643
|
+
var DeploymentRegistryModelSchema = RegistryModelSchema.safeExtend({
|
|
1644
|
+
pricing: z.never().optional()
|
|
1645
|
+
}).strict();
|
|
1646
|
+
var DeploymentRegistryProviderSchema = RegistryProviderSchema.safeExtend({
|
|
1647
|
+
kind: DeploymentRegistryProviderKind.default("api-key"),
|
|
1648
|
+
baseUrl: DeploymentRegistryBaseUrl,
|
|
1649
|
+
models: z.array(DeploymentRegistryModelSchema).min(1),
|
|
1650
|
+
apiKey: z.never().optional(),
|
|
1651
|
+
apiKeyEnv: z.never().optional(),
|
|
1652
|
+
defaultHeaders: z.never().optional(),
|
|
1653
|
+
defaultQuery: z.never().optional(),
|
|
1654
|
+
publicDefaultHeaderNames: z.never().optional(),
|
|
1655
|
+
publicDefaultQueryNames: z.never().optional()
|
|
1656
|
+
}).strict();
|
|
1657
|
+
var DeploymentGatewayCatalogModelSchema = GatewayCatalogModel.safeExtend({
|
|
1658
|
+
pricing: z.never().optional()
|
|
1659
|
+
}).strict();
|
|
1660
|
+
var ModelCatalogDocument = z.object({
|
|
1661
|
+
schemaVersion: z.literal(1),
|
|
1662
|
+
/** Canonical deployment default. Omission preserves the V1 first-built-in
|
|
1663
|
+
* fallback for existing documents; operators should set this explicitly
|
|
1664
|
+
* when cutting over a registry or connected-subscription default. */
|
|
1665
|
+
defaultModel: z.string().min(1).optional(),
|
|
1666
|
+
builtInModels: z.array(z.string().min(1)).min(1),
|
|
1667
|
+
registryProviders: z.array(DeploymentRegistryProviderSchema).default([]),
|
|
1668
|
+
gatewayModels: z.array(DeploymentGatewayCatalogModelSchema).default([]),
|
|
1669
|
+
openrouterModels: z.array(OpenRouterCatalogModel).default([]),
|
|
1670
|
+
modelNotes: z.record(z.string().min(1), ModelNote).default({}),
|
|
1671
|
+
billing: z.never().optional(),
|
|
1672
|
+
enabled: z.never().optional(),
|
|
1673
|
+
apiKey: z.never().optional(),
|
|
1674
|
+
bands: z.never().optional()
|
|
1675
|
+
}).strict().superRefine((document, context) => {
|
|
1676
|
+
const productIds = /* @__PURE__ */ new Set();
|
|
1677
|
+
const providerIds = /* @__PURE__ */ new Set();
|
|
1678
|
+
const gatewayUpstreamIds = /* @__PURE__ */ new Set();
|
|
1679
|
+
const add = (id, path) => {
|
|
1680
|
+
if (/[\u000A\u000D|]/u.test(id)) {
|
|
1681
|
+
context.addIssue({
|
|
1682
|
+
code: "custom",
|
|
1683
|
+
path,
|
|
1684
|
+
message: "catalog product ids must not contain newlines or the | field separator"
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1687
|
+
if (productIds.has(id)) {
|
|
1688
|
+
context.addIssue({
|
|
1689
|
+
code: "custom",
|
|
1690
|
+
path,
|
|
1691
|
+
message: `duplicate product id ${id}`
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
productIds.add(id);
|
|
1695
|
+
};
|
|
1696
|
+
document.builtInModels.forEach((id, index) => add(id, ["builtInModels", index]));
|
|
1697
|
+
document.registryProviders.forEach((provider, providerIndex) => {
|
|
1698
|
+
if (RESERVED_MODEL_PROVIDER_IDS.has(provider.id)) {
|
|
1699
|
+
context.addIssue({
|
|
1700
|
+
code: "custom",
|
|
1701
|
+
path: ["registryProviders", providerIndex, "id"],
|
|
1702
|
+
message: `provider id ${provider.id} is reserved for a reviewed OpenGeni provider`
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
if (providerIds.has(provider.id)) {
|
|
1706
|
+
context.addIssue({
|
|
1707
|
+
code: "custom",
|
|
1708
|
+
path: ["registryProviders", providerIndex, "id"],
|
|
1709
|
+
message: `duplicate provider id ${provider.id}`
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1712
|
+
providerIds.add(provider.id);
|
|
1713
|
+
provider.models.forEach(
|
|
1714
|
+
(model, modelIndex) => add(model.id, ["registryProviders", providerIndex, "models", modelIndex, "id"])
|
|
1715
|
+
);
|
|
1716
|
+
});
|
|
1717
|
+
document.gatewayModels.forEach((model, index) => {
|
|
1718
|
+
if (gatewayUpstreamIds.has(model.upstreamModelId)) {
|
|
1719
|
+
context.addIssue({
|
|
1720
|
+
code: "custom",
|
|
1721
|
+
path: ["gatewayModels", index, "upstreamModelId"],
|
|
1722
|
+
message: `duplicate Gateway upstream model id ${model.upstreamModelId}`
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1725
|
+
gatewayUpstreamIds.add(model.upstreamModelId);
|
|
1726
|
+
add(model.productId, ["gatewayModels", index, "productId"]);
|
|
1727
|
+
add(model.workspaceProductId, ["gatewayModels", index, "workspaceProductId"]);
|
|
1728
|
+
});
|
|
1729
|
+
document.openrouterModels.forEach(
|
|
1730
|
+
(model, index) => add(`${OPENROUTER_MODEL_ID_PREFIX}${model.upstreamModelId}`, [
|
|
1731
|
+
"openrouterModels",
|
|
1732
|
+
index,
|
|
1733
|
+
"upstreamModelId"
|
|
1734
|
+
])
|
|
1735
|
+
);
|
|
1736
|
+
if (document.defaultModel && /[\u000A\u000D|]/u.test(document.defaultModel)) {
|
|
1737
|
+
context.addIssue({
|
|
1738
|
+
code: "custom",
|
|
1739
|
+
path: ["defaultModel"],
|
|
1740
|
+
message: "catalog default model must not contain newlines or the | field separator"
|
|
1741
|
+
});
|
|
1742
|
+
}
|
|
1743
|
+
if (document.defaultModel && !productIds.has(document.defaultModel) && !document.defaultModel.startsWith(CODEX_MODEL_ID_PREFIX) && !document.defaultModel.startsWith(XAI_SUBSCRIPTION_MODEL_ID_PREFIX)) {
|
|
1744
|
+
context.addIssue({
|
|
1745
|
+
code: "custom",
|
|
1746
|
+
path: ["defaultModel"],
|
|
1747
|
+
message: "catalog default model must reference deployment catalog membership or a connected-subscription product"
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
for (const productId of Object.keys(document.modelNotes)) {
|
|
1751
|
+
if (!productIds.has(productId)) {
|
|
1752
|
+
context.addIssue({
|
|
1753
|
+
code: "custom",
|
|
1754
|
+
path: ["modelNotes", productId],
|
|
1755
|
+
message: "model note references a product id outside the deployment catalog"
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
});
|
|
1760
|
+
function parseModelCatalogDocument(value) {
|
|
1761
|
+
return ModelCatalogDocument.parse(value);
|
|
1762
|
+
}
|
|
1763
|
+
function deploymentRegistryProvidersWithHostCredentials(settings, providers) {
|
|
1764
|
+
const hostProviders = new Map(
|
|
1765
|
+
parseModelProvidersJson(settings.modelProvidersJson).map((provider) => [provider.id, provider])
|
|
1766
|
+
);
|
|
1767
|
+
return providers.map((provider) => {
|
|
1768
|
+
if (provider.kind !== "api-key") return provider;
|
|
1769
|
+
const host = hostProviders.get(provider.id);
|
|
1770
|
+
if (!host || host.kind !== "api-key") {
|
|
1771
|
+
throw new Error(
|
|
1772
|
+
`database model catalog provider ${provider.id} has no matching host-authorized api-key transport`
|
|
1773
|
+
);
|
|
1774
|
+
}
|
|
1775
|
+
const transportIdentity = (candidate) => ({
|
|
1776
|
+
kind: candidate.kind,
|
|
1777
|
+
baseUrl: candidate.baseUrl,
|
|
1778
|
+
api: candidate.api,
|
|
1779
|
+
wireProfile: candidate.wireProfile
|
|
1780
|
+
});
|
|
1781
|
+
if (canonicalJson(transportIdentity(provider)) !== canonicalJson(transportIdentity(host))) {
|
|
1782
|
+
throw new Error(
|
|
1783
|
+
`database model catalog provider ${provider.id} does not match its host-authorized transport`
|
|
1784
|
+
);
|
|
1785
|
+
}
|
|
1786
|
+
return {
|
|
1787
|
+
...provider,
|
|
1788
|
+
...host.defaultHeaders === void 0 ? {} : { defaultHeaders: host.defaultHeaders },
|
|
1789
|
+
...host.defaultQuery === void 0 ? {} : { defaultQuery: host.defaultQuery },
|
|
1790
|
+
...host.publicDefaultHeaderNames === void 0 ? {} : { publicDefaultHeaderNames: host.publicDefaultHeaderNames },
|
|
1791
|
+
...host.publicDefaultQueryNames === void 0 ? {} : { publicDefaultQueryNames: host.publicDefaultQueryNames },
|
|
1792
|
+
...host.apiKey === void 0 ? {} : { apiKey: host.apiKey },
|
|
1793
|
+
...host.apiKeyEnv === void 0 ? {} : { apiKeyEnv: host.apiKeyEnv }
|
|
1794
|
+
};
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
function applyModelCatalogDocument(settings, rawDocument) {
|
|
1798
|
+
const document = parseModelCatalogDocument(rawDocument);
|
|
1799
|
+
const defaultModel = document.defaultModel ?? document.builtInModels[0];
|
|
1800
|
+
const resolved = {
|
|
1801
|
+
...settings,
|
|
1802
|
+
openaiModel: defaultModel,
|
|
1803
|
+
// Keep the complete built-in membership, including the default. The worker
|
|
1804
|
+
// replaces openaiModel with the exact turn model; the run-scoped router
|
|
1805
|
+
// needs one stable built-in id in this allow-list so a bare provider model
|
|
1806
|
+
// is not temporarily claimed by OpenAI/Azure during name re-resolution.
|
|
1807
|
+
openaiAllowedModels: document.builtInModels.join(","),
|
|
1808
|
+
modelProvidersJson: JSON.stringify(
|
|
1809
|
+
deploymentRegistryProvidersWithHostCredentials(settings, document.registryProviders)
|
|
1810
|
+
),
|
|
1811
|
+
resolvedGatewayModelsJson: JSON.stringify(document.gatewayModels),
|
|
1812
|
+
resolvedOpenRouterModelsJson: JSON.stringify(document.openrouterModels),
|
|
1813
|
+
modelNotesJson: JSON.stringify(document.modelNotes)
|
|
1814
|
+
};
|
|
1815
|
+
return resolved;
|
|
1816
|
+
}
|
|
1478
1817
|
var IntegrationOAuthClientConfigSchema = z.object({
|
|
1479
1818
|
clientId: z.string().min(1),
|
|
1480
1819
|
clientSecret: z.string().min(1).optional(),
|
|
@@ -1482,11 +1821,10 @@ var IntegrationOAuthClientConfigSchema = z.object({
|
|
|
1482
1821
|
});
|
|
1483
1822
|
var VERCEL_AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh/v1";
|
|
1484
1823
|
var VERCEL_AI_GATEWAY_AI_SDK_BASE_URL = "https://ai-gateway.vercel.sh/v4/ai";
|
|
1485
|
-
var OPENGENI_GATEWAY_PROVIDER_ID = "opengeni-gateway";
|
|
1486
|
-
var WORKSPACE_GATEWAY_PROVIDER_ID = "workspace-gateway";
|
|
1487
|
-
var WORKSPACE_GATEWAY_MODEL_ID_PREFIX = "workspace-gateway/";
|
|
1488
1824
|
var VERCEL_AI_GATEWAY_CONNECTION_DOMAIN = "ai-gateway.vercel.sh";
|
|
1489
1825
|
var VERCEL_AI_GATEWAY_CONNECTION_ROLE = "vercel_ai_gateway";
|
|
1826
|
+
var WORKSPACE_OPENROUTER_CONNECTION_DOMAIN = "openrouter.ai";
|
|
1827
|
+
var WORKSPACE_OPENROUTER_CONNECTION_ROLE = "openrouter";
|
|
1490
1828
|
var CODEX_REALTIME_MODEL_ID = "gpt-live-1-boulder-alpha";
|
|
1491
1829
|
var SUPERGROK_REALTIME_MODEL_ID = "supergrok/grok-voice-think-fast-2.0";
|
|
1492
1830
|
var OPENGENI_REALTIME_MODEL_ID_PREFIX = "opengeni-gateway/";
|
|
@@ -1545,23 +1883,126 @@ var OPENGENI_GATEWAY_MODELS = {
|
|
|
1545
1883
|
implicitCaching: true
|
|
1546
1884
|
}
|
|
1547
1885
|
};
|
|
1886
|
+
var OPENGENI_OPENROUTER_MODELS = [
|
|
1887
|
+
OpenRouterCatalogModel.parse({
|
|
1888
|
+
upstreamModelId: "nvidia/nemotron-3-super-120b-a12b:free",
|
|
1889
|
+
label: "Nemotron 3 Super 120B",
|
|
1890
|
+
shortLabel: "Nemotron 3 Super",
|
|
1891
|
+
aliases: [],
|
|
1892
|
+
capabilities: {
|
|
1893
|
+
reasoning: {
|
|
1894
|
+
upstream: "supported",
|
|
1895
|
+
// OpenRouter advertises the reasoning controls, but the catalogue does
|
|
1896
|
+
// not publish this model's accepted effort vocabulary. Preserve that
|
|
1897
|
+
// upstream fact without exposing an unverified runnable selector.
|
|
1898
|
+
runnable: false,
|
|
1899
|
+
efforts: [],
|
|
1900
|
+
defaultEffort: null,
|
|
1901
|
+
required: false
|
|
1902
|
+
},
|
|
1903
|
+
functionCalling: { upstream: "supported", runnable: true },
|
|
1904
|
+
structuredOutput: { upstream: "supported", runnable: true },
|
|
1905
|
+
hostedTools: {
|
|
1906
|
+
webSearch: { upstream: "unknown", runnable: false },
|
|
1907
|
+
xSearch: { upstream: "unknown", runnable: false },
|
|
1908
|
+
codeExecution: { upstream: "unknown", runnable: false },
|
|
1909
|
+
imageGeneration: { upstream: "unknown", runnable: false }
|
|
1910
|
+
},
|
|
1911
|
+
inputModalities: ["text"],
|
|
1912
|
+
inputFileMediaTypes: [],
|
|
1913
|
+
outputModalities: ["text"],
|
|
1914
|
+
transports: {
|
|
1915
|
+
sse: { upstream: "supported", runnable: true },
|
|
1916
|
+
responsesWebSocket: { upstream: "unknown", runnable: false },
|
|
1917
|
+
realtimeAudio: { upstream: "unsupported", runnable: false }
|
|
1918
|
+
},
|
|
1919
|
+
latencyModes: [{ id: "standard", upstream: "unknown", runnable: true }]
|
|
1920
|
+
},
|
|
1921
|
+
contextWindowTokens: 262144,
|
|
1922
|
+
effectiveContextWindowTokens: 235929,
|
|
1923
|
+
autoCompactTokenLimit: 22e4
|
|
1924
|
+
})
|
|
1925
|
+
];
|
|
1926
|
+
function defaultGatewayCatalogModels() {
|
|
1927
|
+
return [
|
|
1928
|
+
{
|
|
1929
|
+
...OPENGENI_GATEWAY_MODELS.deepseek,
|
|
1930
|
+
vision: false,
|
|
1931
|
+
inputFileMediaTypes: [],
|
|
1932
|
+
contextWindowTokens: 1e6,
|
|
1933
|
+
effectiveContextWindowTokens: 9e5,
|
|
1934
|
+
autoCompactTokenLimit: 85e4
|
|
1935
|
+
},
|
|
1936
|
+
{
|
|
1937
|
+
...OPENGENI_GATEWAY_MODELS.kimi,
|
|
1938
|
+
vision: true,
|
|
1939
|
+
inputFileMediaTypes: ["application/pdf"],
|
|
1940
|
+
contextWindowTokens: 1e6,
|
|
1941
|
+
effectiveContextWindowTokens: 9e5,
|
|
1942
|
+
autoCompactTokenLimit: 85e4
|
|
1943
|
+
}
|
|
1944
|
+
].map((model) => GatewayCatalogModel.parse(model));
|
|
1945
|
+
}
|
|
1946
|
+
function configuredGatewayCatalogModels(settings) {
|
|
1947
|
+
if (settings.resolvedGatewayModelsJson === void 0) {
|
|
1948
|
+
return defaultGatewayCatalogModels();
|
|
1949
|
+
}
|
|
1950
|
+
return z.array(GatewayCatalogModel).parse(JSON.parse(settings.resolvedGatewayModelsJson));
|
|
1951
|
+
}
|
|
1952
|
+
function configuredGatewayUpstreamModelIds(settings) {
|
|
1953
|
+
return configuredGatewayCatalogModels(settings).map((model) => model.upstreamModelId);
|
|
1954
|
+
}
|
|
1955
|
+
function configuredGatewayWorkspaceProductModelIds(settings) {
|
|
1956
|
+
return configuredGatewayCatalogModels(settings).map((model) => model.workspaceProductId);
|
|
1957
|
+
}
|
|
1958
|
+
function configuredGatewayOrganizationProductModelIds(settings) {
|
|
1959
|
+
void settings;
|
|
1960
|
+
return [];
|
|
1961
|
+
}
|
|
1962
|
+
function configuredModelInputIdentities(settings) {
|
|
1963
|
+
return configuredModels(settings).flatMap((model) => [model.id, ...model.aliases]);
|
|
1964
|
+
}
|
|
1965
|
+
function configuredOpenRouterCatalogModels(settings) {
|
|
1966
|
+
if (settings.resolvedOpenRouterModelsJson === void 0) {
|
|
1967
|
+
return [...OPENGENI_OPENROUTER_MODELS];
|
|
1968
|
+
}
|
|
1969
|
+
return z.array(OpenRouterCatalogModel).parse(JSON.parse(settings.resolvedOpenRouterModelsJson));
|
|
1970
|
+
}
|
|
1971
|
+
function configuredOpenRouterUpstreamModelIds(settings) {
|
|
1972
|
+
return configuredOpenRouterCatalogModels(settings).map((model) => model.upstreamModelId);
|
|
1973
|
+
}
|
|
1974
|
+
function workspaceOpenRouterProductId(modelId) {
|
|
1975
|
+
return `${WORKSPACE_OPENROUTER_MODEL_ID_PREFIX}${modelId.startsWith(OPENROUTER_MODEL_ID_PREFIX) ? modelId.slice(OPENROUTER_MODEL_ID_PREFIX.length) : modelId}`;
|
|
1976
|
+
}
|
|
1977
|
+
function configuredOpenRouterWorkspaceProductModelIds(settings) {
|
|
1978
|
+
return configuredOpenRouterCatalogModels(settings).flatMap(
|
|
1979
|
+
(model) => [model.upstreamModelId, ...model.aliases].map(workspaceOpenRouterProductId)
|
|
1980
|
+
);
|
|
1981
|
+
}
|
|
1982
|
+
function configuredOpenRouterOrganizationProductModelIds(settings) {
|
|
1983
|
+
void settings;
|
|
1984
|
+
return [];
|
|
1985
|
+
}
|
|
1548
1986
|
var defaultModelPricing = {
|
|
1549
1987
|
"gpt-5.6-sol": {
|
|
1550
1988
|
default: {
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1989
|
+
// Promotional OpenAI pricing, guaranteed through at least 2026-11-21.
|
|
1990
|
+
inputMicrosPerMillionTokens: 4e6,
|
|
1991
|
+
cachedInputMicrosPerMillionTokens: 4e5,
|
|
1992
|
+
cacheWriteMicrosPerMillionTokens: 5e6,
|
|
1993
|
+
outputMicrosPerMillionTokens: 2e7,
|
|
1994
|
+
marginBps: 500
|
|
1555
1995
|
},
|
|
1556
1996
|
inputTokenTiers: [
|
|
1557
1997
|
{
|
|
1558
1998
|
// OpenAI: prompts with >272K input tokens use the long-context rate.
|
|
1559
1999
|
minimumInputTokens: 272001,
|
|
1560
2000
|
pricing: {
|
|
1561
|
-
inputMicrosPerMillionTokens:
|
|
1562
|
-
cachedInputMicrosPerMillionTokens:
|
|
1563
|
-
|
|
1564
|
-
|
|
2001
|
+
inputMicrosPerMillionTokens: 8e6,
|
|
2002
|
+
cachedInputMicrosPerMillionTokens: 8e5,
|
|
2003
|
+
cacheWriteMicrosPerMillionTokens: 1e7,
|
|
2004
|
+
outputMicrosPerMillionTokens: 3e7,
|
|
2005
|
+
marginBps: 500
|
|
1565
2006
|
}
|
|
1566
2007
|
}
|
|
1567
2008
|
]
|
|
@@ -1570,8 +2011,9 @@ var defaultModelPricing = {
|
|
|
1570
2011
|
default: {
|
|
1571
2012
|
inputMicrosPerMillionTokens: 2e6,
|
|
1572
2013
|
cachedInputMicrosPerMillionTokens: 2e5,
|
|
2014
|
+
cacheWriteMicrosPerMillionTokens: 25e5,
|
|
1573
2015
|
outputMicrosPerMillionTokens: 12e6,
|
|
1574
|
-
marginBps:
|
|
2016
|
+
marginBps: 500
|
|
1575
2017
|
},
|
|
1576
2018
|
inputTokenTiers: [
|
|
1577
2019
|
{
|
|
@@ -1579,8 +2021,9 @@ var defaultModelPricing = {
|
|
|
1579
2021
|
pricing: {
|
|
1580
2022
|
inputMicrosPerMillionTokens: 4e6,
|
|
1581
2023
|
cachedInputMicrosPerMillionTokens: 4e5,
|
|
2024
|
+
cacheWriteMicrosPerMillionTokens: 5e6,
|
|
1582
2025
|
outputMicrosPerMillionTokens: 18e6,
|
|
1583
|
-
marginBps:
|
|
2026
|
+
marginBps: 500
|
|
1584
2027
|
}
|
|
1585
2028
|
}
|
|
1586
2029
|
]
|
|
@@ -1589,8 +2032,9 @@ var defaultModelPricing = {
|
|
|
1589
2032
|
default: {
|
|
1590
2033
|
inputMicrosPerMillionTokens: 2e5,
|
|
1591
2034
|
cachedInputMicrosPerMillionTokens: 2e4,
|
|
2035
|
+
cacheWriteMicrosPerMillionTokens: 25e4,
|
|
1592
2036
|
outputMicrosPerMillionTokens: 12e5,
|
|
1593
|
-
marginBps:
|
|
2037
|
+
marginBps: 500
|
|
1594
2038
|
},
|
|
1595
2039
|
inputTokenTiers: [
|
|
1596
2040
|
{
|
|
@@ -1598,8 +2042,9 @@ var defaultModelPricing = {
|
|
|
1598
2042
|
pricing: {
|
|
1599
2043
|
inputMicrosPerMillionTokens: 4e5,
|
|
1600
2044
|
cachedInputMicrosPerMillionTokens: 4e4,
|
|
2045
|
+
cacheWriteMicrosPerMillionTokens: 5e5,
|
|
1601
2046
|
outputMicrosPerMillionTokens: 18e5,
|
|
1602
|
-
marginBps:
|
|
2047
|
+
marginBps: 500
|
|
1603
2048
|
}
|
|
1604
2049
|
}
|
|
1605
2050
|
]
|
|
@@ -1614,7 +2059,7 @@ var defaultModelPricing = {
|
|
|
1614
2059
|
inputMicrosPerMillionTokens: 14e4,
|
|
1615
2060
|
cachedInputMicrosPerMillionTokens: 28e3,
|
|
1616
2061
|
outputMicrosPerMillionTokens: 28e4,
|
|
1617
|
-
marginBps:
|
|
2062
|
+
marginBps: 500
|
|
1618
2063
|
}
|
|
1619
2064
|
},
|
|
1620
2065
|
[OPENGENI_GATEWAY_MODELS.kimi.productId]: {
|
|
@@ -1622,7 +2067,7 @@ var defaultModelPricing = {
|
|
|
1622
2067
|
inputMicrosPerMillionTokens: 3e6,
|
|
1623
2068
|
cachedInputMicrosPerMillionTokens: 3e5,
|
|
1624
2069
|
outputMicrosPerMillionTokens: 15e6,
|
|
1625
|
-
marginBps:
|
|
2070
|
+
marginBps: 500
|
|
1626
2071
|
}
|
|
1627
2072
|
},
|
|
1628
2073
|
// Fireworks AI / GLM 5.2 — the first shipped non-OpenAI registry model. A
|
|
@@ -1634,7 +2079,7 @@ var defaultModelPricing = {
|
|
|
1634
2079
|
inputMicrosPerMillionTokens: 14e5,
|
|
1635
2080
|
cachedInputMicrosPerMillionTokens: 14e4,
|
|
1636
2081
|
outputMicrosPerMillionTokens: 44e5,
|
|
1637
|
-
marginBps:
|
|
2082
|
+
marginBps: 500
|
|
1638
2083
|
}
|
|
1639
2084
|
}
|
|
1640
2085
|
};
|
|
@@ -1693,11 +2138,14 @@ function objectStorageConfiguredForWorkspaceArchives(settings) {
|
|
|
1693
2138
|
}
|
|
1694
2139
|
}
|
|
1695
2140
|
}
|
|
1696
|
-
function
|
|
1697
|
-
const value =
|
|
2141
|
+
function optionalEnvironmentValue(name, source) {
|
|
2142
|
+
const value = source[name];
|
|
1698
2143
|
return value && value.trim().length > 0 ? value : void 0;
|
|
1699
2144
|
}
|
|
1700
|
-
function getSettings() {
|
|
2145
|
+
function getSettings(source = process.env) {
|
|
2146
|
+
const optional = (name) => optionalEnvironmentValue(name, source);
|
|
2147
|
+
const modelCatalogSource = optional("OPENGENI_MODEL_CATALOG_SOURCE");
|
|
2148
|
+
const modelCostPolicyJson = optional("OPENGENI_MODEL_COST_POLICY_JSON") ?? (modelCatalogSource === "database" ? "{}" : DEFAULT_MODEL_COST_POLICY_JSON);
|
|
1701
2149
|
const raw = {
|
|
1702
2150
|
serviceName: optional("OPENGENI_SERVICE_NAME"),
|
|
1703
2151
|
environment: optional("OPENGENI_ENVIRONMENT"),
|
|
@@ -1813,6 +2261,9 @@ function getSettings() {
|
|
|
1813
2261
|
goalIdleBackoffMs: optional("OPENGENI_GOAL_IDLE_BACKOFF_MS"),
|
|
1814
2262
|
goalIdleBackoffMaxMs: optional("OPENGENI_GOAL_IDLE_BACKOFF_MAX_MS"),
|
|
1815
2263
|
childLifecycleNoticesEnabled: optional("OPENGENI_CHILD_LIFECYCLE_NOTICES_ENABLED"),
|
|
2264
|
+
hostMcpAuthoritySourceAdmissionEnabled: optional(
|
|
2265
|
+
"OPENGENI_HOST_MCP_AUTHORITY_SOURCE_ADMISSION_ENABLED"
|
|
2266
|
+
),
|
|
1816
2267
|
slackWorkspaceRoutingEnabled: optional("OPENGENI_SLACK_WORKSPACE_ROUTING_ENABLED"),
|
|
1817
2268
|
agentMaxModelCallsPerTurn: optional("OPENGENI_AGENT_MAX_MODEL_CALLS_PER_TURN"),
|
|
1818
2269
|
contextWindowTokens: optional("OPENGENI_CONTEXT_WINDOW_TOKENS"),
|
|
@@ -1882,6 +2333,10 @@ function getSettings() {
|
|
|
1882
2333
|
voiceInputAzureAdToken: optional("OPENGENI_VOICE_INPUT_AZURE_AD_TOKEN"),
|
|
1883
2334
|
voiceInputCodexExperimentalEnabled: optional("OPENGENI_VOICE_INPUT_CODEX_EXPERIMENTAL"),
|
|
1884
2335
|
modelPricingJson: optional("OPENGENI_MODEL_PRICING_JSON"),
|
|
2336
|
+
modelCatalogSource,
|
|
2337
|
+
modelCostPolicyJson,
|
|
2338
|
+
modelNotesJson: optional("OPENGENI_MODEL_NOTES_JSON"),
|
|
2339
|
+
openrouterApiKey: optional("OPENGENI_OPENROUTER_API_KEY"),
|
|
1885
2340
|
modelProvidersJson: optional("OPENGENI_MODEL_PROVIDERS_JSON"),
|
|
1886
2341
|
codexSubscriptionEnabled: optional("OPENGENI_CODEX_SUBSCRIPTION_ENABLED"),
|
|
1887
2342
|
supergrokSubscriptionEnabled: optional("OPENGENI_SUPERGROK_SUBSCRIPTION_ENABLED"),
|
|
@@ -2018,6 +2473,7 @@ function getSettings() {
|
|
|
2018
2473
|
sandboxIdleGraceMs: optional("OPENGENI_SANDBOX_IDLE_GRACE_MS"),
|
|
2019
2474
|
sandboxSnapshotIntervalMs: optional("OPENGENI_SANDBOX_SNAPSHOT_INTERVAL_MS"),
|
|
2020
2475
|
sandboxSnapshotTimeoutMs: optional("OPENGENI_SANDBOX_SNAPSHOT_TIMEOUT_MS"),
|
|
2476
|
+
sandboxDrainSnapshotTimeoutMs: optional("OPENGENI_SANDBOX_DRAIN_SNAPSHOT_TIMEOUT_MS"),
|
|
2021
2477
|
sandboxRotationLeadMs: optional("OPENGENI_SANDBOX_ROTATION_LEAD_MS"),
|
|
2022
2478
|
sandboxRotationBatchSize: optional("OPENGENI_SANDBOX_ROTATION_BATCH_SIZE"),
|
|
2023
2479
|
sandboxLeaseTtlMs: optional("OPENGENI_SANDBOX_LEASE_TTL_MS"),
|
|
@@ -2107,7 +2563,7 @@ function getSettings() {
|
|
|
2107
2563
|
sandboxRotationLeadMs: raw.sandboxRotationLeadMs === void 0 && parsed.sandboxBackend === "modal" ? Math.min(36e5, Math.floor(parsed.modalTimeoutSeconds * 1e3 / 2)) : parsed.sandboxRotationLeadMs,
|
|
2108
2564
|
mcpServers: ensureBuiltInMcpServers(parsed)
|
|
2109
2565
|
};
|
|
2110
|
-
validateSettings(settings);
|
|
2566
|
+
validateSettings(settings, source);
|
|
2111
2567
|
return settings;
|
|
2112
2568
|
}
|
|
2113
2569
|
var LOCAL_FIRST_PARTY_DELEGATION_SECRET = "opengeni-local-first-party-delegation-secret-v1";
|
|
@@ -2167,8 +2623,13 @@ function sandboxArchiveCaptureTimeoutMs(settings) {
|
|
|
2167
2623
|
settings.sandboxSnapshotTimeoutMs + SANDBOX_ARCHIVE_CAPTURE_SETTLEMENT_GRACE_MS
|
|
2168
2624
|
);
|
|
2169
2625
|
}
|
|
2626
|
+
function effectiveSandboxDrainSnapshotTimeoutMs(settings) {
|
|
2627
|
+
return settings.sandboxDrainSnapshotTimeoutMs ?? settings.sandboxSnapshotTimeoutMs;
|
|
2628
|
+
}
|
|
2170
2629
|
function sandboxLifecycleTransitionWaitMs(settings) {
|
|
2171
|
-
const captureTimeoutMs = sandboxArchiveCaptureTimeoutMs(
|
|
2630
|
+
const captureTimeoutMs = sandboxArchiveCaptureTimeoutMs({
|
|
2631
|
+
sandboxSnapshotTimeoutMs: effectiveSandboxDrainSnapshotTimeoutMs(settings)
|
|
2632
|
+
});
|
|
2172
2633
|
return Math.min(
|
|
2173
2634
|
SANDBOX_LIFECYCLE_TRANSITION_MAX_WAIT_MS,
|
|
2174
2635
|
settings.sandboxLeaseReaperPeriodMs + captureTimeoutMs + SANDBOX_LIFECYCLE_RETRY_HANDOFF_GRACE_MS
|
|
@@ -2422,10 +2883,8 @@ function legacyModelCapabilities(settings, input) {
|
|
|
2422
2883
|
latencyModes: [{ id: "standard", upstream: "unknown", runnable: true }]
|
|
2423
2884
|
});
|
|
2424
2885
|
}
|
|
2425
|
-
function gatewayRequestPolicyForUpstreamModel(upstreamModelId) {
|
|
2426
|
-
const model =
|
|
2427
|
-
(candidate) => candidate.upstreamModelId === upstreamModelId
|
|
2428
|
-
);
|
|
2886
|
+
function gatewayRequestPolicyForUpstreamModel(upstreamModelId, models = defaultGatewayCatalogModels()) {
|
|
2887
|
+
const model = models.find((candidate) => candidate.upstreamModelId === upstreamModelId);
|
|
2429
2888
|
if (!model) {
|
|
2430
2889
|
return void 0;
|
|
2431
2890
|
}
|
|
@@ -2456,30 +2915,83 @@ function gatewayModelCapabilities(settings, input) {
|
|
|
2456
2915
|
latencyModes: [{ id: "standard", upstream: "supported", runnable: true }]
|
|
2457
2916
|
});
|
|
2458
2917
|
}
|
|
2918
|
+
function openRouterCustomModelCapabilities(settings) {
|
|
2919
|
+
const legacy = legacyModelCapabilities(settings, {
|
|
2920
|
+
reasoningEffort: false,
|
|
2921
|
+
hostedWebSearch: false
|
|
2922
|
+
});
|
|
2923
|
+
return normalizeCapabilities({
|
|
2924
|
+
...legacy,
|
|
2925
|
+
functionCalling: { upstream: "supported", runnable: true },
|
|
2926
|
+
inputModalities: ["text"],
|
|
2927
|
+
inputFileMediaTypes: [],
|
|
2928
|
+
transports: {
|
|
2929
|
+
...legacy.transports,
|
|
2930
|
+
sse: { upstream: "supported", runnable: true }
|
|
2931
|
+
},
|
|
2932
|
+
promptCaching: { upstream: "unsupported", runnable: false, mode: "none" },
|
|
2933
|
+
latencyModes: [{ id: "standard", upstream: "supported", runnable: true }]
|
|
2934
|
+
});
|
|
2935
|
+
}
|
|
2459
2936
|
function gatewayRegistryProvider(settings, input) {
|
|
2460
2937
|
const workspace = input.kind === "vercel-gateway-workspace";
|
|
2461
|
-
const
|
|
2462
|
-
|
|
2938
|
+
const organization = input.kind === "vercel-gateway-organization";
|
|
2939
|
+
const scoped = workspace || organization;
|
|
2940
|
+
const curated = organization ? [] : configuredGatewayCatalogModels(settings);
|
|
2941
|
+
const upstreamIds = new Set(curated.map((model) => model.upstreamModelId));
|
|
2942
|
+
const productIds = new Set(
|
|
2943
|
+
parseModelProvidersJson(settings.modelProvidersJson).filter(
|
|
2944
|
+
(provider) => provider.id !== WORKSPACE_GATEWAY_PROVIDER_ID && provider.id !== ORGANIZATION_GATEWAY_PROVIDER_ID
|
|
2945
|
+
).flatMap(
|
|
2946
|
+
(provider) => provider.models.flatMap((model) => [model.id, ...model.aliases ?? []])
|
|
2947
|
+
)
|
|
2948
|
+
);
|
|
2949
|
+
const models = curated.map((model) => {
|
|
2950
|
+
const id = workspace ? model.workspaceProductId : organization ? `${ORGANIZATION_GATEWAY_MODEL_ID_PREFIX}${model.upstreamModelId}` : model.productId;
|
|
2951
|
+
productIds.add(id);
|
|
2463
2952
|
return {
|
|
2464
|
-
id
|
|
2953
|
+
id,
|
|
2465
2954
|
upstreamModelId: model.upstreamModelId,
|
|
2466
2955
|
label: model.label,
|
|
2467
|
-
shortLabel: model.shortLabel,
|
|
2956
|
+
...model.shortLabel ? { shortLabel: model.shortLabel } : {},
|
|
2468
2957
|
capabilities: gatewayModelCapabilities(settings, {
|
|
2469
2958
|
implicitCaching: model.implicitCaching,
|
|
2470
|
-
vision:
|
|
2471
|
-
inputFileMediaTypes:
|
|
2959
|
+
vision: model.vision,
|
|
2960
|
+
inputFileMediaTypes: model.inputFileMediaTypes
|
|
2472
2961
|
}),
|
|
2473
|
-
contextWindowTokens:
|
|
2474
|
-
effectiveContextWindowTokens:
|
|
2475
|
-
autoCompactTokenLimit:
|
|
2476
|
-
toolOutputTruncationTokens: settings.modelToolOutputTruncationTokens
|
|
2962
|
+
contextWindowTokens: model.contextWindowTokens,
|
|
2963
|
+
effectiveContextWindowTokens: model.effectiveContextWindowTokens,
|
|
2964
|
+
autoCompactTokenLimit: model.autoCompactTokenLimit,
|
|
2965
|
+
toolOutputTruncationTokens: settings.modelToolOutputTruncationTokens,
|
|
2966
|
+
...model.pricing === void 0 ? {} : { pricing: model.pricing }
|
|
2477
2967
|
};
|
|
2478
2968
|
});
|
|
2969
|
+
if (scoped) {
|
|
2970
|
+
for (const custom of input.customModels ?? []) {
|
|
2971
|
+
const productId = `${workspace ? WORKSPACE_GATEWAY_MODEL_ID_PREFIX : ORGANIZATION_GATEWAY_MODEL_ID_PREFIX}${custom.upstreamModelId}`;
|
|
2972
|
+
if (upstreamIds.has(custom.upstreamModelId) || productIds.has(productId)) continue;
|
|
2973
|
+
upstreamIds.add(custom.upstreamModelId);
|
|
2974
|
+
productIds.add(productId);
|
|
2975
|
+
models.push({
|
|
2976
|
+
id: productId,
|
|
2977
|
+
upstreamModelId: custom.upstreamModelId,
|
|
2978
|
+
label: custom.label?.trim() || custom.upstreamModelId,
|
|
2979
|
+
capabilities: gatewayModelCapabilities(settings, {
|
|
2980
|
+
implicitCaching: false,
|
|
2981
|
+
vision: false,
|
|
2982
|
+
inputFileMediaTypes: []
|
|
2983
|
+
}),
|
|
2984
|
+
contextWindowTokens: 1e6,
|
|
2985
|
+
effectiveContextWindowTokens: 9e5,
|
|
2986
|
+
autoCompactTokenLimit: 85e4,
|
|
2987
|
+
toolOutputTruncationTokens: settings.modelToolOutputTruncationTokens
|
|
2988
|
+
});
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2479
2991
|
return {
|
|
2480
2992
|
kind: input.kind,
|
|
2481
|
-
id: workspace ? WORKSPACE_GATEWAY_PROVIDER_ID : OPENGENI_GATEWAY_PROVIDER_ID,
|
|
2482
|
-
label: workspace ? "Your Gateway" : "OpenGeni",
|
|
2993
|
+
id: workspace ? WORKSPACE_GATEWAY_PROVIDER_ID : organization ? ORGANIZATION_GATEWAY_PROVIDER_ID : OPENGENI_GATEWAY_PROVIDER_ID,
|
|
2994
|
+
label: workspace ? "Your Gateway" : organization ? "Organization Gateway" : "OpenGeni",
|
|
2483
2995
|
// Responses preserves vision, reasoning items, and provider-native usage.
|
|
2484
2996
|
// Model-specific compatibility stays at the reviewed request fence rather
|
|
2485
2997
|
// than downgrading the whole provider wire.
|
|
@@ -2490,47 +3002,179 @@ function gatewayRegistryProvider(settings, input) {
|
|
|
2490
3002
|
models
|
|
2491
3003
|
};
|
|
2492
3004
|
}
|
|
3005
|
+
function openRouterRegistryProvider(settings, input) {
|
|
3006
|
+
const workspace = input.kind === "openrouter-workspace";
|
|
3007
|
+
const organization = input.kind === "openrouter-organization";
|
|
3008
|
+
const scoped = workspace || organization;
|
|
3009
|
+
const curated = organization ? [] : configuredOpenRouterCatalogModels(settings);
|
|
3010
|
+
const upstreamIds = new Set(curated.map((model) => model.upstreamModelId));
|
|
3011
|
+
const productIds = new Set(
|
|
3012
|
+
parseModelProvidersJson(settings.modelProvidersJson).filter(
|
|
3013
|
+
(provider) => provider.id !== WORKSPACE_OPENROUTER_PROVIDER_ID && provider.id !== ORGANIZATION_OPENROUTER_PROVIDER_ID
|
|
3014
|
+
).flatMap(
|
|
3015
|
+
(provider) => provider.models.flatMap((model) => [model.id, ...model.aliases ?? []])
|
|
3016
|
+
)
|
|
3017
|
+
);
|
|
3018
|
+
const models = curated.map((model) => {
|
|
3019
|
+
const id = workspace ? workspaceOpenRouterProductId(model.upstreamModelId) : organization ? `${ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX}${model.upstreamModelId}` : `${OPENROUTER_MODEL_ID_PREFIX}${model.upstreamModelId}`;
|
|
3020
|
+
const aliases = workspace ? model.aliases.map(workspaceOpenRouterProductId) : organization ? model.aliases.map((alias) => `${ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX}${alias}`) : model.aliases;
|
|
3021
|
+
productIds.add(id);
|
|
3022
|
+
for (const alias of aliases) productIds.add(alias);
|
|
3023
|
+
return {
|
|
3024
|
+
id,
|
|
3025
|
+
upstreamModelId: model.upstreamModelId,
|
|
3026
|
+
aliases,
|
|
3027
|
+
label: model.label,
|
|
3028
|
+
...model.shortLabel ? { shortLabel: model.shortLabel } : {},
|
|
3029
|
+
capabilities: model.capabilities,
|
|
3030
|
+
...model.contextWindowTokens === void 0 ? {} : { contextWindowTokens: model.contextWindowTokens },
|
|
3031
|
+
...model.effectiveContextWindowTokens === void 0 ? {} : { effectiveContextWindowTokens: model.effectiveContextWindowTokens },
|
|
3032
|
+
...model.autoCompactTokenLimit === void 0 ? {} : { autoCompactTokenLimit: model.autoCompactTokenLimit },
|
|
3033
|
+
toolOutputTruncationTokens: model.toolOutputTruncationTokens ?? settings.modelToolOutputTruncationTokens
|
|
3034
|
+
};
|
|
3035
|
+
});
|
|
3036
|
+
if (scoped) {
|
|
3037
|
+
for (const custom of input.customModels ?? []) {
|
|
3038
|
+
const productId = `${workspace ? WORKSPACE_OPENROUTER_MODEL_ID_PREFIX : ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX}${custom.upstreamModelId}`;
|
|
3039
|
+
if (upstreamIds.has(custom.upstreamModelId) || productIds.has(productId)) continue;
|
|
3040
|
+
upstreamIds.add(custom.upstreamModelId);
|
|
3041
|
+
productIds.add(productId);
|
|
3042
|
+
models.push({
|
|
3043
|
+
id: productId,
|
|
3044
|
+
upstreamModelId: custom.upstreamModelId,
|
|
3045
|
+
aliases: [],
|
|
3046
|
+
label: custom.label?.trim() || custom.upstreamModelId,
|
|
3047
|
+
capabilities: openRouterCustomModelCapabilities(settings),
|
|
3048
|
+
toolOutputTruncationTokens: settings.modelToolOutputTruncationTokens
|
|
3049
|
+
});
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
if (models.length === 0) return null;
|
|
3053
|
+
const defaultHeaders = {
|
|
3054
|
+
"x-title": "OpenGeni",
|
|
3055
|
+
...settings.publicBaseUrl ? { "http-referer": settings.publicBaseUrl } : {}
|
|
3056
|
+
};
|
|
3057
|
+
return {
|
|
3058
|
+
kind: input.kind,
|
|
3059
|
+
id: workspace ? WORKSPACE_OPENROUTER_PROVIDER_ID : organization ? ORGANIZATION_OPENROUTER_PROVIDER_ID : OPENROUTER_PROVIDER_ID,
|
|
3060
|
+
label: workspace ? "Your OpenRouter" : organization ? "Organization OpenRouter" : "OpenRouter",
|
|
3061
|
+
api: "chat",
|
|
3062
|
+
wireProfile: "openai",
|
|
3063
|
+
baseUrl: OPENROUTER_BASE_URL,
|
|
3064
|
+
...input.apiKey ? { apiKey: input.apiKey } : {},
|
|
3065
|
+
defaultHeaders,
|
|
3066
|
+
publicDefaultHeaderNames: Object.keys(defaultHeaders),
|
|
3067
|
+
models
|
|
3068
|
+
};
|
|
3069
|
+
}
|
|
2493
3070
|
function configuredRegistryProviders(settings) {
|
|
2494
3071
|
const providers = parseModelProvidersJson(settings.modelProvidersJson);
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
3072
|
+
const injected = [...providers];
|
|
3073
|
+
if (settings.vercelAiGatewayApiKey && configuredGatewayCatalogModels(settings).length > 0) {
|
|
3074
|
+
injected.push(
|
|
3075
|
+
gatewayRegistryProvider(settings, {
|
|
3076
|
+
kind: "vercel-gateway-managed",
|
|
3077
|
+
apiKey: settings.vercelAiGatewayApiKey
|
|
3078
|
+
})
|
|
2501
3079
|
);
|
|
2502
3080
|
}
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
];
|
|
3081
|
+
const openrouter = settings.openrouterApiKey ? openRouterRegistryProvider(settings, {
|
|
3082
|
+
kind: "openrouter-managed",
|
|
3083
|
+
apiKey: settings.openrouterApiKey
|
|
3084
|
+
}) : null;
|
|
3085
|
+
if (openrouter) injected.push(openrouter);
|
|
3086
|
+
return injected;
|
|
2510
3087
|
}
|
|
2511
|
-
function withWorkspaceGatewayCatalogProvider(settings) {
|
|
3088
|
+
function withWorkspaceGatewayCatalogProvider(settings, customModels = []) {
|
|
2512
3089
|
const providers = parseModelProvidersJson(settings.modelProvidersJson);
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
3090
|
+
const withoutWorkspace = providers.filter(
|
|
3091
|
+
(provider) => provider.id !== WORKSPACE_GATEWAY_PROVIDER_ID
|
|
3092
|
+
);
|
|
3093
|
+
const curatedCount = configuredGatewayCatalogModels(settings).length;
|
|
3094
|
+
if (curatedCount === 0 && customModels.length === 0) return settings;
|
|
2516
3095
|
return {
|
|
2517
3096
|
...settings,
|
|
2518
3097
|
modelProvidersJson: JSON.stringify([
|
|
2519
|
-
...
|
|
2520
|
-
gatewayRegistryProvider(settings, {
|
|
3098
|
+
...withoutWorkspace,
|
|
3099
|
+
gatewayRegistryProvider(settings, {
|
|
3100
|
+
kind: "vercel-gateway-workspace",
|
|
3101
|
+
customModels
|
|
3102
|
+
})
|
|
2521
3103
|
])
|
|
2522
3104
|
};
|
|
2523
3105
|
}
|
|
2524
|
-
function withWorkspaceGatewayCredential(settings, apiKey) {
|
|
3106
|
+
function withWorkspaceGatewayCredential(settings, apiKey, customModels = []) {
|
|
2525
3107
|
if (!apiKey.trim()) {
|
|
2526
3108
|
throw new Error("workspace AI Gateway credential is empty");
|
|
2527
3109
|
}
|
|
2528
|
-
const catalogSettings = withWorkspaceGatewayCatalogProvider(settings);
|
|
3110
|
+
const catalogSettings = withWorkspaceGatewayCatalogProvider(settings, customModels);
|
|
2529
3111
|
const providers = parseModelProvidersJson(catalogSettings.modelProvidersJson).map(
|
|
2530
3112
|
(provider) => provider.id === WORKSPACE_GATEWAY_PROVIDER_ID ? { ...provider, apiKey } : provider
|
|
2531
3113
|
);
|
|
2532
3114
|
return { ...catalogSettings, modelProvidersJson: JSON.stringify(providers) };
|
|
2533
3115
|
}
|
|
3116
|
+
function withWorkspaceOpenRouterCatalogProvider(settings, customModels = []) {
|
|
3117
|
+
const providers = parseModelProvidersJson(settings.modelProvidersJson);
|
|
3118
|
+
const withoutWorkspace = providers.filter(
|
|
3119
|
+
(provider2) => provider2.id !== WORKSPACE_OPENROUTER_PROVIDER_ID
|
|
3120
|
+
);
|
|
3121
|
+
const provider = openRouterRegistryProvider(settings, {
|
|
3122
|
+
kind: "openrouter-workspace",
|
|
3123
|
+
customModels
|
|
3124
|
+
});
|
|
3125
|
+
if (!provider) return settings;
|
|
3126
|
+
return {
|
|
3127
|
+
...settings,
|
|
3128
|
+
modelProvidersJson: JSON.stringify([...withoutWorkspace, provider])
|
|
3129
|
+
};
|
|
3130
|
+
}
|
|
3131
|
+
function withWorkspaceOpenRouterCredential(settings, apiKey, customModels = []) {
|
|
3132
|
+
if (!apiKey.trim()) {
|
|
3133
|
+
throw new Error("workspace OpenRouter credential is empty");
|
|
3134
|
+
}
|
|
3135
|
+
const catalogSettings = withWorkspaceOpenRouterCatalogProvider(settings, customModels);
|
|
3136
|
+
const providers = parseModelProvidersJson(catalogSettings.modelProvidersJson).map(
|
|
3137
|
+
(provider) => provider.id === WORKSPACE_OPENROUTER_PROVIDER_ID ? { ...provider, apiKey } : provider
|
|
3138
|
+
);
|
|
3139
|
+
return { ...catalogSettings, modelProvidersJson: JSON.stringify(providers) };
|
|
3140
|
+
}
|
|
3141
|
+
function withOrganizationGatewayCatalogProvider(settings, customModels = []) {
|
|
3142
|
+
if (customModels.length === 0) return settings;
|
|
3143
|
+
const providers = parseModelProvidersJson(settings.modelProvidersJson).filter(
|
|
3144
|
+
(provider2) => provider2.id !== ORGANIZATION_GATEWAY_PROVIDER_ID
|
|
3145
|
+
);
|
|
3146
|
+
const provider = gatewayRegistryProvider(settings, {
|
|
3147
|
+
kind: "vercel-gateway-organization",
|
|
3148
|
+
customModels
|
|
3149
|
+
});
|
|
3150
|
+
return { ...settings, modelProvidersJson: JSON.stringify([...providers, provider]) };
|
|
3151
|
+
}
|
|
3152
|
+
function withOrganizationGatewayCredential(settings, apiKey, customModels = []) {
|
|
3153
|
+
if (!apiKey.trim()) throw new Error("organization AI Gateway credential is empty");
|
|
3154
|
+
const catalog = withOrganizationGatewayCatalogProvider(settings, customModels);
|
|
3155
|
+
const providers = parseModelProvidersJson(catalog.modelProvidersJson).map(
|
|
3156
|
+
(provider) => provider.id === ORGANIZATION_GATEWAY_PROVIDER_ID ? { ...provider, apiKey } : provider
|
|
3157
|
+
);
|
|
3158
|
+
return { ...catalog, modelProvidersJson: JSON.stringify(providers) };
|
|
3159
|
+
}
|
|
3160
|
+
function withOrganizationOpenRouterCatalogProvider(settings, customModels = []) {
|
|
3161
|
+
const providers = parseModelProvidersJson(settings.modelProvidersJson).filter(
|
|
3162
|
+
(provider2) => provider2.id !== ORGANIZATION_OPENROUTER_PROVIDER_ID
|
|
3163
|
+
);
|
|
3164
|
+
const provider = openRouterRegistryProvider(settings, {
|
|
3165
|
+
kind: "openrouter-organization",
|
|
3166
|
+
customModels
|
|
3167
|
+
});
|
|
3168
|
+
return provider ? { ...settings, modelProvidersJson: JSON.stringify([...providers, provider]) } : settings;
|
|
3169
|
+
}
|
|
3170
|
+
function withOrganizationOpenRouterCredential(settings, apiKey, customModels = []) {
|
|
3171
|
+
if (!apiKey.trim()) throw new Error("organization OpenRouter credential is empty");
|
|
3172
|
+
const catalog = withOrganizationOpenRouterCatalogProvider(settings, customModels);
|
|
3173
|
+
const providers = parseModelProvidersJson(catalog.modelProvidersJson).map(
|
|
3174
|
+
(provider) => provider.id === ORGANIZATION_OPENROUTER_PROVIDER_ID ? { ...provider, apiKey } : provider
|
|
3175
|
+
);
|
|
3176
|
+
return { ...catalog, modelProvidersJson: JSON.stringify(providers) };
|
|
3177
|
+
}
|
|
2534
3178
|
var GPT56_FAST_BILLING_MULTIPLIER_BPS = 2e4;
|
|
2535
3179
|
function productLabelForModelId(modelId) {
|
|
2536
3180
|
const slug = modelId.startsWith(CODEX_MODEL_ID_PREFIX) ? modelId.slice(CODEX_MODEL_ID_PREFIX.length) : modelId;
|
|
@@ -2643,31 +3287,60 @@ function assertLatencyModeRunnable(settings, modelId, latencyMode) {
|
|
|
2643
3287
|
}
|
|
2644
3288
|
}
|
|
2645
3289
|
function registryCredentialSource(provider) {
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
3290
|
+
switch (provider.kind) {
|
|
3291
|
+
case "anonymous":
|
|
3292
|
+
return { kind: "deployment", mechanism: "none" };
|
|
3293
|
+
case "codex-subscription":
|
|
3294
|
+
return { kind: "connected_subscription", provider: "codex" };
|
|
3295
|
+
case "xai-subscription":
|
|
3296
|
+
return { kind: "connected_subscription", provider: "xai" };
|
|
3297
|
+
case "vercel-gateway-workspace":
|
|
3298
|
+
case "openrouter-workspace":
|
|
3299
|
+
return { kind: "workspace_connection", mechanism: "api_key" };
|
|
3300
|
+
case "vercel-gateway-organization":
|
|
3301
|
+
case "openrouter-organization":
|
|
3302
|
+
return { kind: "organization_connection", mechanism: "api_key" };
|
|
3303
|
+
case "api-key":
|
|
3304
|
+
case "vercel-gateway-managed":
|
|
3305
|
+
case "openrouter-managed":
|
|
3306
|
+
return { kind: "deployment", mechanism: "api_key" };
|
|
3307
|
+
default: {
|
|
3308
|
+
const _exhaustive = provider.kind;
|
|
3309
|
+
return _exhaustive;
|
|
3310
|
+
}
|
|
2657
3311
|
}
|
|
2658
|
-
return { kind: "deployment", mechanism: "api_key" };
|
|
2659
3312
|
}
|
|
2660
3313
|
function registryBilling(provider) {
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
3314
|
+
switch (provider.kind) {
|
|
3315
|
+
case "anonymous":
|
|
3316
|
+
case "openrouter-managed":
|
|
3317
|
+
return { upstreamPayer: "deployment", metering: "external" };
|
|
3318
|
+
case "codex-subscription":
|
|
3319
|
+
case "xai-subscription":
|
|
3320
|
+
return { upstreamPayer: "connected_subscription", metering: "external" };
|
|
3321
|
+
case "vercel-gateway-workspace":
|
|
3322
|
+
case "openrouter-workspace":
|
|
3323
|
+
return { upstreamPayer: "workspace", metering: "external" };
|
|
3324
|
+
case "vercel-gateway-organization":
|
|
3325
|
+
case "openrouter-organization":
|
|
3326
|
+
return { upstreamPayer: "organization", metering: "external" };
|
|
3327
|
+
case "api-key":
|
|
3328
|
+
case "vercel-gateway-managed":
|
|
3329
|
+
return { upstreamPayer: "deployment", metering: "opengeni_credits" };
|
|
3330
|
+
default: {
|
|
3331
|
+
const _exhaustive = provider.kind;
|
|
3332
|
+
return _exhaustive;
|
|
3333
|
+
}
|
|
2669
3334
|
}
|
|
2670
|
-
|
|
3335
|
+
}
|
|
3336
|
+
function configuredCostForModel(settings, productModelId, credentialSource) {
|
|
3337
|
+
if (credentialSource.kind === "workspace_connection") return "workspace";
|
|
3338
|
+
if (credentialSource.kind === "organization_connection") return "organization";
|
|
3339
|
+
if (credentialSource.kind === "connected_subscription") return "subscription";
|
|
3340
|
+
return parseModelCostPolicyJson(settings.modelCostPolicyJson)[productModelId] ?? "credits";
|
|
3341
|
+
}
|
|
3342
|
+
function modelCostClassForConfiguredModel(_settings, model) {
|
|
3343
|
+
return model.cost;
|
|
2671
3344
|
}
|
|
2672
3345
|
function builtinCredentialSource(settings) {
|
|
2673
3346
|
if (settings.openaiProvider === "azure" && !settings.azureOpenaiApiKey) {
|
|
@@ -2726,6 +3399,10 @@ function definitionVersionFor(model, provider, options = {}) {
|
|
|
2726
3399
|
billing: model.billing,
|
|
2727
3400
|
executionLimits: model.executionLimits,
|
|
2728
3401
|
capabilities: model.capabilities,
|
|
3402
|
+
// Workspace-facing free/credits classification is a separate live
|
|
3403
|
+
// deployment policy. Operators must drain/fence accepted turns before
|
|
3404
|
+
// changing it; it is intentionally not a second executable-definition
|
|
3405
|
+
// freeze inside TurnExecutionPolicyV1.
|
|
2729
3406
|
...model.requestPolicy ? { requestPolicy: model.requestPolicy } : {},
|
|
2730
3407
|
pricing: model.pricing ?? null
|
|
2731
3408
|
});
|
|
@@ -2734,7 +3411,9 @@ function definitionVersionFor(model, provider, options = {}) {
|
|
|
2734
3411
|
function legacyImplicitOpenAiDefinitionVersionFor(model, provider) {
|
|
2735
3412
|
if (provider.wireProfile !== "openai") return null;
|
|
2736
3413
|
const { definitionVersion: _definitionVersion, ...modelWithoutVersion } = model;
|
|
2737
|
-
return definitionVersionFor(modelWithoutVersion, provider, {
|
|
3414
|
+
return definitionVersionFor(modelWithoutVersion, provider, {
|
|
3415
|
+
includeWireProfile: false
|
|
3416
|
+
});
|
|
2738
3417
|
}
|
|
2739
3418
|
function builtinProviderId(settings) {
|
|
2740
3419
|
return settings.openaiProvider === "azure" ? "azure" : "openai";
|
|
@@ -2742,7 +3421,7 @@ function builtinProviderId(settings) {
|
|
|
2742
3421
|
function builtinProviderLabel(settings) {
|
|
2743
3422
|
return settings.openaiProvider === "azure" ? "Azure OpenAI" : "OpenAI";
|
|
2744
3423
|
}
|
|
2745
|
-
function configuredProviders(settings) {
|
|
3424
|
+
function configuredProviders(settings, source = process.env) {
|
|
2746
3425
|
const credentialSource = builtinCredentialSource(settings);
|
|
2747
3426
|
const builtin = {
|
|
2748
3427
|
id: builtinProviderId(settings),
|
|
@@ -2771,7 +3450,7 @@ function configuredProviders(settings) {
|
|
|
2771
3450
|
wireProfile: provider.wireProfile,
|
|
2772
3451
|
builtin: false,
|
|
2773
3452
|
baseUrl: provider.baseUrl,
|
|
2774
|
-
apiKey: resolveProviderApiKey(provider),
|
|
3453
|
+
apiKey: resolveProviderApiKey(provider, source),
|
|
2775
3454
|
defaultQuery: provider.defaultQuery,
|
|
2776
3455
|
defaultHeaders: provider.defaultHeaders,
|
|
2777
3456
|
publicDefaultQueryNames: provider.publicDefaultQueryNames,
|
|
@@ -2854,8 +3533,14 @@ function withXaiSubscriptionCatalogProvider(settings) {
|
|
|
2854
3533
|
{ id: "standard", upstream: "supported", runnable: true },
|
|
2855
3534
|
{ id: "fast", upstream: "supported", runnable: true }
|
|
2856
3535
|
];
|
|
2857
|
-
capabilities.hostedTools.xSearch = {
|
|
2858
|
-
|
|
3536
|
+
capabilities.hostedTools.xSearch = {
|
|
3537
|
+
upstream: "supported",
|
|
3538
|
+
runnable: true
|
|
3539
|
+
};
|
|
3540
|
+
capabilities.hostedTools.imageGeneration = {
|
|
3541
|
+
upstream: "supported",
|
|
3542
|
+
runnable: true
|
|
3543
|
+
};
|
|
2859
3544
|
return {
|
|
2860
3545
|
id: `${XAI_SUBSCRIPTION_MODEL_ID_PREFIX}${slug}`,
|
|
2861
3546
|
upstreamModelId: slug,
|
|
@@ -2871,7 +3556,10 @@ function withXaiSubscriptionCatalogProvider(settings) {
|
|
|
2871
3556
|
};
|
|
2872
3557
|
})
|
|
2873
3558
|
};
|
|
2874
|
-
return {
|
|
3559
|
+
return {
|
|
3560
|
+
...settings,
|
|
3561
|
+
modelProvidersJson: JSON.stringify([...providers, provider])
|
|
3562
|
+
};
|
|
2875
3563
|
}
|
|
2876
3564
|
function policyProviderIdForModel(settings, modelId) {
|
|
2877
3565
|
const canonicalModelId = canonicalizeConfiguredModelId(settings, modelId);
|
|
@@ -2884,6 +3572,9 @@ function policyProviderIdForModel(settings, modelId) {
|
|
|
2884
3572
|
if (canonicalModelId.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX)) {
|
|
2885
3573
|
return WORKSPACE_GATEWAY_PROVIDER_ID;
|
|
2886
3574
|
}
|
|
3575
|
+
if (canonicalModelId.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX)) {
|
|
3576
|
+
return WORKSPACE_OPENROUTER_PROVIDER_ID;
|
|
3577
|
+
}
|
|
2887
3578
|
const configured = configuredModels(settings).find((model) => model.id === canonicalModelId);
|
|
2888
3579
|
return configured?.providerId ?? builtinProviderId(settings);
|
|
2889
3580
|
}
|
|
@@ -2896,10 +3587,14 @@ function resolvedExecutionLimits(settings, model) {
|
|
|
2896
3587
|
};
|
|
2897
3588
|
}
|
|
2898
3589
|
function finalizeConfiguredModel(settings, provider, input) {
|
|
2899
|
-
const requestPolicy = provider.kind === "vercel-gateway-managed" || provider.kind === "vercel-gateway-workspace"
|
|
3590
|
+
const requestPolicy = provider.kind === "vercel-gateway-managed" || provider.kind === "vercel-gateway-workspace" || provider.kind === "vercel-gateway-organization" ? gatewayRequestPolicyForUpstreamModel(
|
|
3591
|
+
input.upstreamModelId,
|
|
3592
|
+
configuredGatewayCatalogModels(settings)
|
|
3593
|
+
) : void 0;
|
|
2900
3594
|
const modelWithoutVersion = {
|
|
2901
3595
|
schemaVersion: 1,
|
|
2902
3596
|
...input,
|
|
3597
|
+
cost: configuredCostForModel(settings, input.id, input.credentialSource),
|
|
2903
3598
|
...requestPolicy ? { requestPolicy } : {},
|
|
2904
3599
|
executionLimits: resolvedExecutionLimits(settings, input)
|
|
2905
3600
|
};
|
|
@@ -2939,10 +3634,10 @@ function assertUniqueModelIdentities(models) {
|
|
|
2939
3634
|
}
|
|
2940
3635
|
}
|
|
2941
3636
|
}
|
|
2942
|
-
function configuredModels(settings) {
|
|
3637
|
+
function configuredModels(settings, source = process.env) {
|
|
2943
3638
|
const builtinId = builtinProviderId(settings);
|
|
2944
3639
|
const builtinLabel = builtinProviderLabel(settings);
|
|
2945
|
-
const providers = configuredProviders(settings);
|
|
3640
|
+
const providers = configuredProviders(settings, source);
|
|
2946
3641
|
const providerById = new Map(providers.map((provider) => [provider.id, provider]));
|
|
2947
3642
|
const pricingSchedules = configuredModelPricingSchedules(settings);
|
|
2948
3643
|
const parsedRegistry = configuredRegistryProviders(settings);
|
|
@@ -3031,7 +3726,10 @@ function configuredModels(settings) {
|
|
|
3031
3726
|
}
|
|
3032
3727
|
}
|
|
3033
3728
|
assertUniqueModelIdentities(out);
|
|
3034
|
-
|
|
3729
|
+
const defaultIndex = out.findIndex(
|
|
3730
|
+
(model) => model.id === settings.openaiModel || model.aliases.includes(settings.openaiModel)
|
|
3731
|
+
);
|
|
3732
|
+
return defaultIndex > 0 ? [out[defaultIndex], ...out.slice(0, defaultIndex), ...out.slice(defaultIndex + 1)] : out;
|
|
3035
3733
|
}
|
|
3036
3734
|
function canonicalizeConfiguredModelId(settings, modelId) {
|
|
3037
3735
|
const models = configuredModels(settings);
|
|
@@ -3066,10 +3764,32 @@ function settingsForTurnExecutionPolicy(settings, modelId) {
|
|
|
3066
3764
|
return withXaiSubscriptionCatalogProvider(settings);
|
|
3067
3765
|
}
|
|
3068
3766
|
if (modelId.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX)) {
|
|
3767
|
+
if (resolveModelProvider(settings, modelId)) {
|
|
3768
|
+
return settings;
|
|
3769
|
+
}
|
|
3069
3770
|
return withWorkspaceGatewayCatalogProvider(settings);
|
|
3070
3771
|
}
|
|
3772
|
+
if (modelId.startsWith(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX)) {
|
|
3773
|
+
if (resolveModelProvider(settings, modelId)) {
|
|
3774
|
+
return settings;
|
|
3775
|
+
}
|
|
3776
|
+
return withWorkspaceOpenRouterCatalogProvider(settings);
|
|
3777
|
+
}
|
|
3778
|
+
if (modelId.startsWith(ORGANIZATION_GATEWAY_MODEL_ID_PREFIX)) {
|
|
3779
|
+
return resolveModelProvider(settings, modelId) ? settings : withOrganizationGatewayCatalogProvider(settings);
|
|
3780
|
+
}
|
|
3781
|
+
if (modelId.startsWith(ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX)) {
|
|
3782
|
+
return resolveModelProvider(settings, modelId) ? settings : withOrganizationOpenRouterCatalogProvider(settings);
|
|
3783
|
+
}
|
|
3071
3784
|
return settings;
|
|
3072
3785
|
}
|
|
3786
|
+
function resolveModelProviderForTurn(settings, modelId) {
|
|
3787
|
+
const catalogSettings = settingsForTurnExecutionPolicy(settings, modelId);
|
|
3788
|
+
return resolveModelProvider(
|
|
3789
|
+
catalogSettings,
|
|
3790
|
+
canonicalizeConfiguredModelId(catalogSettings, modelId)
|
|
3791
|
+
);
|
|
3792
|
+
}
|
|
3073
3793
|
function resolveTurnExecutionPolicyV1(settings, input) {
|
|
3074
3794
|
const catalogSettings = settingsForTurnExecutionPolicy(settings, input.modelId);
|
|
3075
3795
|
const productModelId = canonicalizeConfiguredModelId(catalogSettings, input.modelId);
|
|
@@ -3147,7 +3867,7 @@ function configuredModelPricingSchedules(settings) {
|
|
|
3147
3867
|
const configured = Object.fromEntries(
|
|
3148
3868
|
Object.entries(parseModelPricingJson(settings.modelPricingJson)).map(([model, pricing]) => [
|
|
3149
3869
|
model,
|
|
3150
|
-
|
|
3870
|
+
normalizeModelPricingSchedule(pricing)
|
|
3151
3871
|
])
|
|
3152
3872
|
);
|
|
3153
3873
|
return {
|
|
@@ -3260,12 +3980,7 @@ function calculateModelUsageCostBreakdown(settings, model, usage, options) {
|
|
|
3260
3980
|
function calculateGatewayReportedCostMicros(settings, model, inferenceCostUsd, options) {
|
|
3261
3981
|
return calculateGatewayReportedCostBreakdown(settings, model, inferenceCostUsd, options).creditCostMicros;
|
|
3262
3982
|
}
|
|
3263
|
-
function
|
|
3264
|
-
const schedule = configuredModelPricingSchedules(settings)[model];
|
|
3265
|
-
if (!schedule) {
|
|
3266
|
-
throw new Error(`Missing model pricing for ${model}`);
|
|
3267
|
-
}
|
|
3268
|
-
const pricing = selectModelPricing(schedule, positiveInt(options?.inputTokens));
|
|
3983
|
+
function parseGatewayReportedCostDecimal(inferenceCostUsd) {
|
|
3269
3984
|
const match = /^(0|[1-9]\d*)(?:\.(\d{1,18}))?$/.exec(inferenceCostUsd);
|
|
3270
3985
|
if (!match) {
|
|
3271
3986
|
throw new Error("Invalid AI Gateway inference cost");
|
|
@@ -3274,16 +3989,35 @@ function calculateGatewayReportedCostBreakdown(settings, model, inferenceCostUsd
|
|
|
3274
3989
|
const decimalDigits = BigInt(`${match[1]}${fraction}`);
|
|
3275
3990
|
const decimalScale = 10n ** BigInt(fraction.length);
|
|
3276
3991
|
const providerNumerator = decimalDigits * 1000000n;
|
|
3277
|
-
const
|
|
3992
|
+
const providerCostMicros = (providerNumerator + decimalScale - 1n) / decimalScale;
|
|
3993
|
+
if (providerCostMicros > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
3994
|
+
throw new Error("AI Gateway inference cost exceeds the supported billing range");
|
|
3995
|
+
}
|
|
3996
|
+
return {
|
|
3997
|
+
providerNumerator,
|
|
3998
|
+
decimalScale,
|
|
3999
|
+
providerCostMicros: Number(providerCostMicros)
|
|
4000
|
+
};
|
|
4001
|
+
}
|
|
4002
|
+
function calculateGatewayReportedProviderCostMicros(inferenceCostUsd) {
|
|
4003
|
+
return parseGatewayReportedCostDecimal(inferenceCostUsd).providerCostMicros;
|
|
4004
|
+
}
|
|
4005
|
+
function calculateGatewayReportedCostBreakdown(settings, model, inferenceCostUsd, options) {
|
|
4006
|
+
const schedule = configuredModelPricingSchedules(settings)[model];
|
|
4007
|
+
if (!schedule) {
|
|
4008
|
+
throw new Error(`Missing model pricing for ${model}`);
|
|
4009
|
+
}
|
|
4010
|
+
const pricing = selectModelPricing(schedule, positiveInt(options?.inputTokens));
|
|
4011
|
+
const { providerNumerator, decimalScale, providerCostMicros } = parseGatewayReportedCostDecimal(inferenceCostUsd);
|
|
3278
4012
|
const marginBps = BigInt(1e4 + (pricing.marginBps ?? 0));
|
|
3279
4013
|
const numerator = providerNumerator * marginBps;
|
|
3280
4014
|
const denominator = decimalScale * 10000n;
|
|
3281
4015
|
const creditMicros = (numerator + denominator - 1n) / denominator;
|
|
3282
|
-
if (
|
|
4016
|
+
if (creditMicros > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
3283
4017
|
throw new Error("AI Gateway inference cost exceeds the supported billing range");
|
|
3284
4018
|
}
|
|
3285
4019
|
return {
|
|
3286
|
-
providerCostMicros
|
|
4020
|
+
providerCostMicros,
|
|
3287
4021
|
creditCostMicros: Number(creditMicros)
|
|
3288
4022
|
};
|
|
3289
4023
|
}
|
|
@@ -3555,7 +4289,7 @@ function parseModelPricingJson(raw) {
|
|
|
3555
4289
|
if (!model.trim()) {
|
|
3556
4290
|
throw new Error("OPENGENI_MODEL_PRICING_JSON contains an empty model name");
|
|
3557
4291
|
}
|
|
3558
|
-
out[model] = ModelPricingSchema.parse(value);
|
|
4292
|
+
out[model] = z.union([ModelPricingSchema, ModelPricingScheduleSchema]).parse(value);
|
|
3559
4293
|
}
|
|
3560
4294
|
return out;
|
|
3561
4295
|
}
|
|
@@ -3739,9 +4473,14 @@ function calculateEntryCostMicros(pricing, entry) {
|
|
|
3739
4473
|
const inputTokens = positiveInt(entry.inputTokens);
|
|
3740
4474
|
const outputTokens = positiveInt(entry.outputTokens);
|
|
3741
4475
|
const cachedTokens = Math.min(inputTokens, cachedInputTokens(entry));
|
|
3742
|
-
const
|
|
4476
|
+
const cacheWriteTokens = Math.min(
|
|
4477
|
+
Math.max(0, inputTokens - cachedTokens),
|
|
4478
|
+
cacheWriteInputTokens(entry)
|
|
4479
|
+
);
|
|
4480
|
+
const uncachedInputTokens = Math.max(0, inputTokens - cachedTokens - cacheWriteTokens);
|
|
3743
4481
|
const cachedInputRate = pricing.cachedInputMicrosPerMillionTokens ?? pricing.inputMicrosPerMillionTokens;
|
|
3744
|
-
|
|
4482
|
+
const cacheWriteRate = pricing.cacheWriteMicrosPerMillionTokens ?? pricing.inputMicrosPerMillionTokens;
|
|
4483
|
+
return Math.ceil(uncachedInputTokens * pricing.inputMicrosPerMillionTokens / 1e6) + Math.ceil(cachedTokens * cachedInputRate / 1e6) + Math.ceil(cacheWriteTokens * cacheWriteRate / 1e6) + Math.ceil(outputTokens * pricing.outputMicrosPerMillionTokens / 1e6);
|
|
3745
4484
|
}
|
|
3746
4485
|
function cachedInputTokens(entry) {
|
|
3747
4486
|
const details = Array.isArray(entry.inputTokensDetails) ? entry.inputTokensDetails : entry.inputTokensDetails ? [entry.inputTokensDetails] : [];
|
|
@@ -3751,6 +4490,14 @@ function cachedInputTokens(entry) {
|
|
|
3751
4490
|
}
|
|
3752
4491
|
return total;
|
|
3753
4492
|
}
|
|
4493
|
+
function cacheWriteInputTokens(entry) {
|
|
4494
|
+
const details = Array.isArray(entry.inputTokensDetails) ? entry.inputTokensDetails : entry.inputTokensDetails ? [entry.inputTokensDetails] : [];
|
|
4495
|
+
let total = 0;
|
|
4496
|
+
for (const detail of details) {
|
|
4497
|
+
total += positiveInt(detail.cache_write_tokens ?? detail.cacheWriteTokens);
|
|
4498
|
+
}
|
|
4499
|
+
return total;
|
|
4500
|
+
}
|
|
3754
4501
|
function positiveInt(value) {
|
|
3755
4502
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
3756
4503
|
}
|
|
@@ -3863,7 +4610,7 @@ function isDigestPinnedModalDesktopImage(settings) {
|
|
|
3863
4610
|
if (settings.modalImageId) return true;
|
|
3864
4611
|
return typeof settings.modalImageRef === "string" && MODAL_DESKTOP_IMAGE_DIGEST_REF.test(settings.modalImageRef);
|
|
3865
4612
|
}
|
|
3866
|
-
function validateSettings(settings) {
|
|
4613
|
+
function validateSettings(settings, source = process.env) {
|
|
3867
4614
|
temporalConnectionOptions(settings);
|
|
3868
4615
|
if (settings.goalIdleBackoffMs.some((delayMs) => delayMs > settings.goalIdleBackoffMaxMs)) {
|
|
3869
4616
|
throw new Error(
|
|
@@ -4132,15 +4879,6 @@ function validateSettings(settings) {
|
|
|
4132
4879
|
if (settings.productAccessMode !== "managed" && settings.billingMode === "stripe") {
|
|
4133
4880
|
throw new Error("OPENGENI_BILLING_MODE=stripe requires OPENGENI_PRODUCT_ACCESS_MODE=managed");
|
|
4134
4881
|
}
|
|
4135
|
-
if (settings.billingMode === "stripe" || settings.usageLimitsMode === "managed") {
|
|
4136
|
-
const pricing = configuredModelPricing(settings);
|
|
4137
|
-
const missing = configuredAllowedModels(settings).filter((model) => !pricing[model]);
|
|
4138
|
-
if (missing.length > 0) {
|
|
4139
|
-
throw new Error(
|
|
4140
|
-
`Missing model pricing for managed billing model(s): ${missing.join(", ")}. Set OPENGENI_MODEL_PRICING_JSON.`
|
|
4141
|
-
);
|
|
4142
|
-
}
|
|
4143
|
-
}
|
|
4144
4882
|
if (settings.usageLimitsMode === "static") {
|
|
4145
4883
|
const limits = configuredStaticUsageLimits(settings);
|
|
4146
4884
|
if (Object.keys(limits).length === 0) {
|
|
@@ -4274,6 +5012,11 @@ function validateSettings(settings) {
|
|
|
4274
5012
|
throw new Error(`OPENGENI_MCP_SERVERS contains duplicate id ${server.id}`);
|
|
4275
5013
|
}
|
|
4276
5014
|
serverIds.add(server.id);
|
|
5015
|
+
if (server.connectionRef?.authoritySource === "host" && !settings.hostMcpAuthoritySourceAdmissionEnabled) {
|
|
5016
|
+
throw new Error(
|
|
5017
|
+
"OPENGENI_MCP_SERVERS host-owned connection refs require OPENGENI_HOST_MCP_AUTHORITY_SOURCE_ADMISSION_ENABLED=true after the whole API/worker fleet is upgraded"
|
|
5018
|
+
);
|
|
5019
|
+
}
|
|
4277
5020
|
}
|
|
4278
5021
|
{
|
|
4279
5022
|
const reaperPeriod = settings.sandboxLeaseReaperPeriodMs;
|
|
@@ -4289,11 +5032,35 @@ function validateSettings(settings) {
|
|
|
4289
5032
|
`OPENGENI_SANDBOX_LEASE_REAPER_PERIOD_MS (${reaperPeriod}) must be strictly less than OPENGENI_SANDBOX_INTERACTION_HOLDER_TTL_MS (${interactionTtl}): the reaper must run more often than the controller-heartbeat horizon.`
|
|
4290
5033
|
);
|
|
4291
5034
|
}
|
|
5035
|
+
if (settings.sandboxDrainSnapshotTimeoutMs !== void 0) {
|
|
5036
|
+
const drainCaptureTimeoutMs2 = sandboxArchiveCaptureTimeoutMs({
|
|
5037
|
+
sandboxSnapshotTimeoutMs: effectiveSandboxDrainSnapshotTimeoutMs(settings)
|
|
5038
|
+
});
|
|
5039
|
+
const requiredTransitionWaitMs = reaperPeriod + drainCaptureTimeoutMs2 + SANDBOX_LIFECYCLE_RETRY_HANDOFF_GRACE_MS;
|
|
5040
|
+
if (requiredTransitionWaitMs > SANDBOX_LIFECYCLE_TRANSITION_MAX_WAIT_MS) {
|
|
5041
|
+
throw new Error(
|
|
5042
|
+
`OPENGENI_SANDBOX_DRAIN_SNAPSHOT_TIMEOUT_MS (${settings.sandboxDrainSnapshotTimeoutMs}) requires a sandbox lifecycle transition wait of ${requiredTransitionWaitMs}ms after one reaper period and provider settlement, exceeding the ${SANDBOX_LIFECYCLE_TRANSITION_MAX_WAIT_MS}ms limit. Lower the drain snapshot timeout or OPENGENI_SANDBOX_LEASE_REAPER_PERIOD_MS.`
|
|
5043
|
+
);
|
|
5044
|
+
}
|
|
5045
|
+
}
|
|
5046
|
+
const rotationLeadMs = settings.sandboxRotationLeadMs;
|
|
5047
|
+
const ordinaryCaptureTimeoutMs = sandboxArchiveCaptureTimeoutMs(settings);
|
|
5048
|
+
const drainCaptureTimeoutMs = sandboxArchiveCaptureTimeoutMs({
|
|
5049
|
+
sandboxSnapshotTimeoutMs: effectiveSandboxDrainSnapshotTimeoutMs(settings)
|
|
5050
|
+
});
|
|
5051
|
+
const providerDeadlineCaptureTimeoutMs = Math.max(
|
|
5052
|
+
ordinaryCaptureTimeoutMs,
|
|
5053
|
+
drainCaptureTimeoutMs
|
|
5054
|
+
);
|
|
5055
|
+
if (!(rotationLeadMs > providerDeadlineCaptureTimeoutMs + reaperPeriod)) {
|
|
5056
|
+
throw new Error(
|
|
5057
|
+
`OPENGENI_SANDBOX_ROTATION_LEAD_MS (${rotationLeadMs}) must exceed the largest durable snapshot or drain capture timeout plus one reaper period (${providerDeadlineCaptureTimeoutMs + reaperPeriod}), including for persisted Modal leases after a default-backend rollout.`
|
|
5058
|
+
);
|
|
5059
|
+
}
|
|
4292
5060
|
if (settings.sandboxBackend === "modal") {
|
|
4293
5061
|
const idleGraceMs = settings.sandboxIdleGraceMs;
|
|
4294
5062
|
const lifecycle = effectiveSandboxLifecycle(settings, "modal");
|
|
4295
5063
|
const providerLifetimeMs = lifecycle.hardLifetimeMs;
|
|
4296
|
-
const rotationLeadMs = lifecycle.rotationLeadMs;
|
|
4297
5064
|
const idleTimeoutMs = lifecycle.providerIdleTimeoutMs;
|
|
4298
5065
|
if (!(idleTimeoutMs <= providerLifetimeMs)) {
|
|
4299
5066
|
throw new Error(
|
|
@@ -4305,12 +5072,6 @@ function validateSettings(settings) {
|
|
|
4305
5072
|
`OPENGENI_SANDBOX_ROTATION_LEAD_MS (${rotationLeadMs}) must be strictly less than OPENGENI_MODAL_TIMEOUT_SECONDS*1000 (${providerLifetimeMs}).`
|
|
4306
5073
|
);
|
|
4307
5074
|
}
|
|
4308
|
-
const captureTimeoutMs = sandboxArchiveCaptureTimeoutMs(settings);
|
|
4309
|
-
if (!(rotationLeadMs > captureTimeoutMs + reaperPeriod)) {
|
|
4310
|
-
throw new Error(
|
|
4311
|
-
`OPENGENI_SANDBOX_ROTATION_LEAD_MS (${rotationLeadMs}) must exceed the durable capture timeout plus one reaper period (${captureTimeoutMs + reaperPeriod}).`
|
|
4312
|
-
);
|
|
4313
|
-
}
|
|
4314
5075
|
if (!(viewerTtl < idleTimeoutMs)) {
|
|
4315
5076
|
throw new Error(
|
|
4316
5077
|
`OPENGENI_SANDBOX_VIEWER_HOLDER_TTL_MS (${viewerTtl}) must be strictly less than the effective box idle timeout (${idleTimeoutMs}): a viewer holder must be reapable before the box idles out from under it (the provider idle-timeout is the backstop).`
|
|
@@ -4340,15 +5101,29 @@ function validateSettings(settings) {
|
|
|
4340
5101
|
"[opengeni] OPENGENI_SANDBOX_DESKTOP_ENABLED=true but neither OPENGENI_STREAM_TOKEN_SECRET nor OPENGENI_DELEGATION_SECRET is set: the desktop pixel plane will GRACEFULLY DEGRADE (DesktopStream.transport=null \u2014 no scoped stream tokens can be minted). Set OPENGENI_STREAM_TOKEN_SECRET to enable the live desktop stream."
|
|
4341
5102
|
);
|
|
4342
5103
|
}
|
|
5104
|
+
if (settings.modelCatalogSource === "code") {
|
|
5105
|
+
validateModelCatalogSettings(settings, source);
|
|
5106
|
+
} else {
|
|
5107
|
+
parseModelCostPolicyJson(settings.modelCostPolicyJson);
|
|
5108
|
+
}
|
|
5109
|
+
}
|
|
5110
|
+
function validateModelCatalogSettings(settings, source = process.env) {
|
|
5111
|
+
const costPolicy = parseModelCostPolicyJson(settings.modelCostPolicyJson);
|
|
5112
|
+
const notes = parseModelNotesJson(settings.modelNotesJson);
|
|
4343
5113
|
const registryProviders = parseModelProvidersJson(settings.modelProvidersJson);
|
|
4344
5114
|
const builtinId = builtinProviderId(settings);
|
|
4345
5115
|
const providerIds = /* @__PURE__ */ new Set();
|
|
4346
5116
|
for (const provider of registryProviders) {
|
|
4347
|
-
if (provider.kind === "vercel-gateway-managed" || provider.kind === "vercel-gateway-workspace" || provider.kind === "xai-subscription") {
|
|
5117
|
+
if (provider.kind === "vercel-gateway-managed" || provider.kind === "vercel-gateway-workspace" || provider.kind === "vercel-gateway-organization" || provider.kind === "openrouter-workspace" || provider.kind === "openrouter-organization" || provider.kind === "xai-subscription") {
|
|
4348
5118
|
throw new Error(
|
|
4349
5119
|
`OPENGENI_MODEL_PROVIDERS_JSON provider kind ${provider.kind} is reserved for a reviewed OpenGeni credential broker`
|
|
4350
5120
|
);
|
|
4351
5121
|
}
|
|
5122
|
+
if (RESERVED_MODEL_PROVIDER_IDS.has(provider.id)) {
|
|
5123
|
+
throw new Error(
|
|
5124
|
+
`OPENGENI_MODEL_PROVIDERS_JSON provider id ${provider.id} is reserved for a reviewed OpenGeni provider`
|
|
5125
|
+
);
|
|
5126
|
+
}
|
|
4352
5127
|
if (provider.id === builtinId) {
|
|
4353
5128
|
throw new Error(
|
|
4354
5129
|
`OPENGENI_MODEL_PROVIDERS_JSON provider id ${provider.id} collides with the built-in provider id`
|
|
@@ -4360,13 +5135,66 @@ function validateSettings(settings) {
|
|
|
4360
5135
|
);
|
|
4361
5136
|
}
|
|
4362
5137
|
providerIds.add(provider.id);
|
|
4363
|
-
if (provider.kind !== "codex-subscription" && provider.kind !== "anonymous" && !resolveProviderApiKey(provider)) {
|
|
5138
|
+
if (provider.kind !== "codex-subscription" && provider.kind !== "anonymous" && !resolveProviderApiKey(provider, source)) {
|
|
4364
5139
|
throw new Error(
|
|
4365
5140
|
`OPENGENI_MODEL_PROVIDERS_JSON provider ${provider.id} requires a resolvable API key (set apiKey or apiKeyEnv)`
|
|
4366
5141
|
);
|
|
4367
5142
|
}
|
|
4368
5143
|
}
|
|
4369
|
-
configuredModels(settings);
|
|
5144
|
+
const models = configuredModels(settings, source);
|
|
5145
|
+
const defaultCatalogSettings = settingsForTurnExecutionPolicy(settings, settings.openaiModel);
|
|
5146
|
+
const defaultCatalogModels = defaultCatalogSettings === settings ? models : configuredModels(defaultCatalogSettings, source);
|
|
5147
|
+
if (models.length === 0 && defaultCatalogModels.length === 0) {
|
|
5148
|
+
throw new Error("The resolved model catalog contains no executable models");
|
|
5149
|
+
}
|
|
5150
|
+
const defaultModelId = canonicalizeConfiguredModelId(
|
|
5151
|
+
defaultCatalogSettings,
|
|
5152
|
+
settings.openaiModel
|
|
5153
|
+
);
|
|
5154
|
+
if (!defaultCatalogModels.some((model) => model.id === defaultModelId)) {
|
|
5155
|
+
throw new Error(
|
|
5156
|
+
`The default model ${settings.openaiModel} is not executable in the resolved model catalog`
|
|
5157
|
+
);
|
|
5158
|
+
}
|
|
5159
|
+
const deploymentProductIds = new Set(
|
|
5160
|
+
models.filter((model) => model.credentialSource.kind === "deployment").map((model) => model.id)
|
|
5161
|
+
);
|
|
5162
|
+
const noteProductIds = new Set(models.map((model) => model.id));
|
|
5163
|
+
for (const model of configuredGatewayCatalogModels(settings)) {
|
|
5164
|
+
deploymentProductIds.add(model.productId);
|
|
5165
|
+
noteProductIds.add(model.productId);
|
|
5166
|
+
noteProductIds.add(model.workspaceProductId);
|
|
5167
|
+
}
|
|
5168
|
+
for (const model of configuredOpenRouterCatalogModels(settings)) {
|
|
5169
|
+
const productId = `${OPENROUTER_MODEL_ID_PREFIX}${model.upstreamModelId}`;
|
|
5170
|
+
deploymentProductIds.add(productId);
|
|
5171
|
+
noteProductIds.add(productId);
|
|
5172
|
+
noteProductIds.add(`${WORKSPACE_OPENROUTER_MODEL_ID_PREFIX}${model.upstreamModelId}`);
|
|
5173
|
+
}
|
|
5174
|
+
if (settings.modelCatalogSource === "code") {
|
|
5175
|
+
for (const productId of Object.keys(costPolicy)) {
|
|
5176
|
+
if (!deploymentProductIds.has(productId)) {
|
|
5177
|
+
throw new Error(
|
|
5178
|
+
`OPENGENI_MODEL_COST_POLICY_JSON references unknown deployment model ${productId}`
|
|
5179
|
+
);
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5182
|
+
}
|
|
5183
|
+
for (const productId of Object.keys(notes)) {
|
|
5184
|
+
if (!noteProductIds.has(productId)) {
|
|
5185
|
+
throw new Error(`OPENGENI_MODEL_NOTES_JSON references unknown catalog model ${productId}`);
|
|
5186
|
+
}
|
|
5187
|
+
}
|
|
5188
|
+
if (settings.billingMode === "stripe" || settings.usageLimitsMode === "managed") {
|
|
5189
|
+
const pricing = configuredModelPricing(settings);
|
|
5190
|
+
const missing = models.filter((model) => model.cost === "credits" && !pricing[model.id]).map((model) => model.id);
|
|
5191
|
+
if (missing.length > 0) {
|
|
5192
|
+
throw new Error(
|
|
5193
|
+
`Missing model pricing for managed billing model(s): ${missing.join(", ")}. Set OPENGENI_MODEL_PRICING_JSON.`
|
|
5194
|
+
);
|
|
5195
|
+
}
|
|
5196
|
+
}
|
|
5197
|
+
return models;
|
|
4370
5198
|
}
|
|
4371
5199
|
function resolveStreamTokenSecret(settings) {
|
|
4372
5200
|
const explicit = settings.streamTokenSecret?.trim();
|
|
@@ -4456,19 +5284,34 @@ export {
|
|
|
4456
5284
|
CODEX_REALTIME_MODEL_ID,
|
|
4457
5285
|
CapabilityStateV1Schema,
|
|
4458
5286
|
CapabilitySupportV1,
|
|
5287
|
+
ConfiguredModelCostClass,
|
|
4459
5288
|
DEFAULT_AGENT_INSTRUCTIONS,
|
|
4460
5289
|
DEFAULT_GOAL_IDLE_BACKOFF_MAX_MS,
|
|
4461
5290
|
DEFAULT_GOAL_IDLE_BACKOFF_MS,
|
|
5291
|
+
DEFAULT_MODEL_COST_POLICY_JSON,
|
|
5292
|
+
DEFAULT_OPENROUTER_MODEL_ID,
|
|
4462
5293
|
GOOGLE_DRIVE_PROVIDER_REQUEST_TIMEOUT_MAX_MS,
|
|
4463
5294
|
GOOGLE_DRIVE_PROVIDER_RETRY_DELAY_MAX_MS,
|
|
5295
|
+
GatewayCatalogModel,
|
|
4464
5296
|
IntegrationOAuthClientConfigSchema,
|
|
4465
5297
|
McpServerConnectionRefSchema,
|
|
4466
5298
|
ModelCapabilitiesV1Schema,
|
|
5299
|
+
ModelCatalogDocument,
|
|
5300
|
+
ModelCostClass,
|
|
4467
5301
|
ModelProviderApi,
|
|
4468
5302
|
ModelProviderWireProfile,
|
|
4469
5303
|
OPENGENI_GATEWAY_MODELS,
|
|
4470
5304
|
OPENGENI_GATEWAY_PROVIDER_ID,
|
|
5305
|
+
OPENGENI_OPENROUTER_MODELS,
|
|
4471
5306
|
OPENGENI_REALTIME_MODEL_ID_PREFIX,
|
|
5307
|
+
OPENROUTER_BASE_URL,
|
|
5308
|
+
OPENROUTER_MODEL_ID_PREFIX,
|
|
5309
|
+
OPENROUTER_PROVIDER_ID,
|
|
5310
|
+
ORGANIZATION_GATEWAY_MODEL_ID_PREFIX,
|
|
5311
|
+
ORGANIZATION_GATEWAY_PROVIDER_ID,
|
|
5312
|
+
ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX,
|
|
5313
|
+
ORGANIZATION_OPENROUTER_PROVIDER_ID,
|
|
5314
|
+
OpenRouterCatalogModel,
|
|
4472
5315
|
RegistryProviderKind,
|
|
4473
5316
|
SANDBOX_ARCHIVE_CAPTURE_MAX_TIMEOUT_MS,
|
|
4474
5317
|
SANDBOX_ARCHIVE_CAPTURE_SETTLEMENT_GRACE_MS,
|
|
@@ -4484,14 +5327,20 @@ export {
|
|
|
4484
5327
|
VERCEL_AI_GATEWAY_CONNECTION_ROLE,
|
|
4485
5328
|
WORKSPACE_GATEWAY_MODEL_ID_PREFIX,
|
|
4486
5329
|
WORKSPACE_GATEWAY_PROVIDER_ID,
|
|
5330
|
+
WORKSPACE_OPENROUTER_CONNECTION_DOMAIN,
|
|
5331
|
+
WORKSPACE_OPENROUTER_CONNECTION_ROLE,
|
|
5332
|
+
WORKSPACE_OPENROUTER_MODEL_ID_PREFIX,
|
|
5333
|
+
WORKSPACE_OPENROUTER_PROVIDER_ID,
|
|
4487
5334
|
WORKSPACE_REALTIME_MODEL_ID_PREFIX,
|
|
4488
5335
|
XAI_SUBSCRIPTION_MODEL_ID_PREFIX2 as XAI_SUBSCRIPTION_MODEL_ID_PREFIX,
|
|
4489
5336
|
allowedFirstPartyMcpToolsForSession,
|
|
4490
5337
|
applyGitAuthPointerEnvironment,
|
|
5338
|
+
applyModelCatalogDocument,
|
|
4491
5339
|
assertTurnExecutionPolicyMatchesConfigV1,
|
|
4492
5340
|
builtinProviderId,
|
|
4493
5341
|
calculateGatewayReportedCostBreakdown,
|
|
4494
5342
|
calculateGatewayReportedCostMicros,
|
|
5343
|
+
calculateGatewayReportedProviderCostMicros,
|
|
4495
5344
|
calculateModelUsageCostBreakdown,
|
|
4496
5345
|
calculateModelUsageCostMicros,
|
|
4497
5346
|
calculateVideoGenerationCreditCostMicros,
|
|
@@ -4503,16 +5352,25 @@ export {
|
|
|
4503
5352
|
configuredAllowedModels,
|
|
4504
5353
|
configuredAllowedReasoningEfforts,
|
|
4505
5354
|
configuredEntitlements,
|
|
5355
|
+
configuredGatewayOrganizationProductModelIds,
|
|
5356
|
+
configuredGatewayUpstreamModelIds,
|
|
5357
|
+
configuredGatewayWorkspaceProductModelIds,
|
|
4506
5358
|
configuredGoogleDriveSyncLimits,
|
|
5359
|
+
configuredModelInputIdentities,
|
|
5360
|
+
configuredModelNotes,
|
|
4507
5361
|
configuredModelPricing,
|
|
4508
5362
|
configuredModelPricingSchedules,
|
|
4509
5363
|
configuredModels,
|
|
5364
|
+
configuredOpenRouterOrganizationProductModelIds,
|
|
5365
|
+
configuredOpenRouterUpstreamModelIds,
|
|
5366
|
+
configuredOpenRouterWorkspaceProductModelIds,
|
|
4510
5367
|
configuredProviders,
|
|
4511
5368
|
configuredStaticUsageLimits,
|
|
4512
5369
|
contextInputBudgetTokens,
|
|
4513
5370
|
dbSearchPath,
|
|
4514
5371
|
defaultModelPricing,
|
|
4515
5372
|
effectiveModalIdleTimeoutSeconds,
|
|
5373
|
+
effectiveSandboxDrainSnapshotTimeoutMs,
|
|
4516
5374
|
effectiveSandboxLifecycle,
|
|
4517
5375
|
environmentsEncryptionKeyBytes,
|
|
4518
5376
|
firstPartyMcpBaseUrl,
|
|
@@ -4527,9 +5385,13 @@ export {
|
|
|
4527
5385
|
hasGitHubRepositorySelection,
|
|
4528
5386
|
isDirectOpenAiApiBaseUrl,
|
|
4529
5387
|
isUsableVoiceInputSecret,
|
|
5388
|
+
modelCostClassForConfiguredModel,
|
|
4530
5389
|
parseExposedPorts,
|
|
4531
5390
|
parseIntegrationsOauthClientsJson,
|
|
4532
5391
|
parseMcpServers,
|
|
5392
|
+
parseModelCatalogDocument,
|
|
5393
|
+
parseModelCostPolicyJson,
|
|
5394
|
+
parseModelNotesJson,
|
|
4533
5395
|
parseModelPricingJson,
|
|
4534
5396
|
parseModelProvidersJson,
|
|
4535
5397
|
parseSandboxWarmRateJson,
|
|
@@ -4546,6 +5408,7 @@ export {
|
|
|
4546
5408
|
resolveFirstPartyDelegationSecret,
|
|
4547
5409
|
resolveFirstPartyMcpToolPolicy,
|
|
4548
5410
|
resolveModelProvider,
|
|
5411
|
+
resolveModelProviderForTurn,
|
|
4549
5412
|
resolveNatsCalloutConfig,
|
|
4550
5413
|
resolveNatsControlPlaneAuth,
|
|
4551
5414
|
resolveProviderApiKey,
|
|
@@ -4569,10 +5432,17 @@ export {
|
|
|
4569
5432
|
startupRetryOptions,
|
|
4570
5433
|
streamTokenDegraded,
|
|
4571
5434
|
temporalConnectionOptions,
|
|
5435
|
+
validateModelCatalogSettings,
|
|
4572
5436
|
voiceInputDeploymentConfigured,
|
|
4573
5437
|
withCodexCatalogProvider,
|
|
5438
|
+
withOrganizationGatewayCatalogProvider,
|
|
5439
|
+
withOrganizationGatewayCredential,
|
|
5440
|
+
withOrganizationOpenRouterCatalogProvider,
|
|
5441
|
+
withOrganizationOpenRouterCredential,
|
|
4574
5442
|
withWorkspaceGatewayCatalogProvider,
|
|
4575
5443
|
withWorkspaceGatewayCredential,
|
|
5444
|
+
withWorkspaceOpenRouterCatalogProvider,
|
|
5445
|
+
withWorkspaceOpenRouterCredential,
|
|
4576
5446
|
withXaiSubscriptionCatalogProvider
|
|
4577
5447
|
};
|
|
4578
5448
|
//# sourceMappingURL=index.js.map
|