@opengeni/config 0.10.1 → 0.10.6
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 +55 -7
- package/dist/index.js +122 -38
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +136 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/config",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.6",
|
|
4
4
|
"description": "OpenGeni runtime configuration: settings resolution, deployment knobs, and config validation shared across the server packages.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"prepublishOnly": "bash ../../scripts/prepublish-guard"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@opengeni/codex": "^0.2.
|
|
37
|
-
"@opengeni/contracts": "^0.
|
|
36
|
+
"@opengeni/codex": "^0.2.10",
|
|
37
|
+
"@opengeni/contracts": "^0.35.0",
|
|
38
38
|
"zod": "^4.2.1"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
package/src/index.ts
CHANGED
|
@@ -108,7 +108,7 @@ export const DEFAULT_AGENT_INSTRUCTIONS = [
|
|
|
108
108
|
"Follow the user's task and any enabled pack or skill instructions for the current role.",
|
|
109
109
|
"Work inside the sandbox workspace and use filesystem and shell tools when useful.",
|
|
110
110
|
"Repository resources are mounted under repos/<host>/<owner>/<repo> unless the session specifies another collision-free mount path.",
|
|
111
|
-
"File resources are mounted under files/<file-id>/ unless the session specifies another mount path.",
|
|
111
|
+
"File resources are mounted under .opengeni/files/<file-id>/ unless the session specifies another mount path.",
|
|
112
112
|
"Attached files are mounted read-only; copy them before modifying.",
|
|
113
113
|
"Bundled skills are under .agents/ and can include infrastructure, marketing, or other role-specific guidance.",
|
|
114
114
|
"Use Checkov, Terraform, Azure CLI, git provider CLIs, and repository tools when relevant; gh, glab, and az repos are pre-authenticated when the host brokers matching git credentials.",
|
|
@@ -432,7 +432,7 @@ const SettingsSchema = z.object({
|
|
|
432
432
|
// match the UI danger flip (UsageBar danger at pct >= 90). OPENGENI_CODEX_ROTATION_NEAR_EXHAUSTION_PCT.
|
|
433
433
|
codexRotationNearExhaustionPct: z.coerce.number().int().min(1).max(100).default(90),
|
|
434
434
|
openaiReasoningEffort: ReasoningEffort.default("low"),
|
|
435
|
-
openaiAllowedReasoningEfforts: z.string().default("low,medium,high,xhigh"),
|
|
435
|
+
openaiAllowedReasoningEfforts: z.string().default("low,medium,high,xhigh,max"),
|
|
436
436
|
openaiResponsesTransport: z.enum(["http", "websocket"]).default("http"),
|
|
437
437
|
// Provider-assigned item ids (rs_/msg_/fc_…) in Responses API input are
|
|
438
438
|
// resolved against the provider's server-side response store. That store is
|
|
@@ -1176,6 +1176,8 @@ export const ModelCapabilitiesV1Schema = z
|
|
|
1176
1176
|
codeExecution: CapabilityStateV1Schema,
|
|
1177
1177
|
}),
|
|
1178
1178
|
inputModalities: z.array(ModelModalityV1).min(1),
|
|
1179
|
+
/** Exact MIME types accepted as typed `input_file`; `text/*` is allowed. */
|
|
1180
|
+
inputFileMediaTypes: z.array(z.string()).default([]),
|
|
1179
1181
|
outputModalities: z.array(ModelModalityV1).min(1),
|
|
1180
1182
|
transports: z.object({
|
|
1181
1183
|
sse: CapabilityStateV1Schema,
|
|
@@ -1415,7 +1417,7 @@ export interface ConfiguredModel {
|
|
|
1415
1417
|
capabilities: ModelCapabilitiesV1;
|
|
1416
1418
|
requestPolicy?: {
|
|
1417
1419
|
gateway: {
|
|
1418
|
-
only: [string];
|
|
1420
|
+
only: [string, ...string[]];
|
|
1419
1421
|
caching: "auto" | "none";
|
|
1420
1422
|
};
|
|
1421
1423
|
};
|
|
@@ -1430,27 +1432,74 @@ export interface ConfiguredModel {
|
|
|
1430
1432
|
}
|
|
1431
1433
|
|
|
1432
1434
|
export const VERCEL_AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh/v1" as const;
|
|
1435
|
+
export const VERCEL_AI_GATEWAY_AI_SDK_BASE_URL = "https://ai-gateway.vercel.sh/v4/ai" as const;
|
|
1433
1436
|
export const OPENGENI_GATEWAY_PROVIDER_ID = "opengeni-gateway" as const;
|
|
1434
1437
|
export const WORKSPACE_GATEWAY_PROVIDER_ID = "workspace-gateway" as const;
|
|
1435
1438
|
export const WORKSPACE_GATEWAY_MODEL_ID_PREFIX = "workspace-gateway/" as const;
|
|
1436
1439
|
export const VERCEL_AI_GATEWAY_CONNECTION_DOMAIN = "ai-gateway.vercel.sh" as const;
|
|
1437
1440
|
export const VERCEL_AI_GATEWAY_CONNECTION_ROLE = "vercel_ai_gateway" as const;
|
|
1438
1441
|
|
|
1442
|
+
export const CODEX_REALTIME_MODEL_ID = "gpt-live-1-boulder-alpha" as const;
|
|
1443
|
+
export const OPENGENI_REALTIME_MODEL_ID_PREFIX = "opengeni-gateway/" as const;
|
|
1444
|
+
export const WORKSPACE_REALTIME_MODEL_ID_PREFIX = "workspace-gateway/" as const;
|
|
1445
|
+
|
|
1446
|
+
/** Curated voice models exposed through AI Gateway's normalized realtime API. */
|
|
1447
|
+
export const AI_GATEWAY_REALTIME_MODELS = {
|
|
1448
|
+
openaiRealtime21: {
|
|
1449
|
+
upstreamModelId: "openai/gpt-realtime-2.1",
|
|
1450
|
+
managedModelId: `${OPENGENI_REALTIME_MODEL_ID_PREFIX}openai/gpt-realtime-2.1`,
|
|
1451
|
+
workspaceModelId: `${WORKSPACE_REALTIME_MODEL_ID_PREFIX}openai/gpt-realtime-2.1`,
|
|
1452
|
+
label: "GPT Realtime 2.1",
|
|
1453
|
+
description: "Best overall voice intelligence",
|
|
1454
|
+
},
|
|
1455
|
+
openaiRealtimeMini: {
|
|
1456
|
+
upstreamModelId: "openai/gpt-realtime-mini",
|
|
1457
|
+
managedModelId: `${OPENGENI_REALTIME_MODEL_ID_PREFIX}openai/gpt-realtime-mini`,
|
|
1458
|
+
workspaceModelId: `${WORKSPACE_REALTIME_MODEL_ID_PREFIX}openai/gpt-realtime-mini`,
|
|
1459
|
+
label: "GPT Realtime Mini",
|
|
1460
|
+
description: "Faster, lighter live voice",
|
|
1461
|
+
},
|
|
1462
|
+
grokVoiceThinkFast20: {
|
|
1463
|
+
upstreamModelId: "xai/grok-voice-think-fast-2.0",
|
|
1464
|
+
managedModelId: `${OPENGENI_REALTIME_MODEL_ID_PREFIX}xai/grok-voice-think-fast-2.0`,
|
|
1465
|
+
workspaceModelId: `${WORKSPACE_REALTIME_MODEL_ID_PREFIX}xai/grok-voice-think-fast-2.0`,
|
|
1466
|
+
label: "Grok Voice Think Fast 2.0",
|
|
1467
|
+
description: "Fast, natural xAI voice",
|
|
1468
|
+
},
|
|
1469
|
+
} as const;
|
|
1470
|
+
|
|
1471
|
+
export type AiGatewayRealtimeModel =
|
|
1472
|
+
(typeof AI_GATEWAY_REALTIME_MODELS)[keyof typeof AI_GATEWAY_REALTIME_MODELS];
|
|
1473
|
+
|
|
1474
|
+
export function resolveAiGatewayRealtimeModel(
|
|
1475
|
+
modelId: string,
|
|
1476
|
+
): { source: "managed" | "workspace"; upstreamModelId: string } | null {
|
|
1477
|
+
for (const model of Object.values(AI_GATEWAY_REALTIME_MODELS)) {
|
|
1478
|
+
if (model.managedModelId === modelId) {
|
|
1479
|
+
return { source: "managed", upstreamModelId: model.upstreamModelId };
|
|
1480
|
+
}
|
|
1481
|
+
if (model.workspaceModelId === modelId) {
|
|
1482
|
+
return { source: "workspace", upstreamModelId: model.upstreamModelId };
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
return null;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1439
1488
|
export const OPENGENI_GATEWAY_MODELS = {
|
|
1440
1489
|
deepseek: {
|
|
1441
1490
|
productId: "deepseek-v4-flash-0731",
|
|
1442
1491
|
workspaceProductId: `${WORKSPACE_GATEWAY_MODEL_ID_PREFIX}deepseek-v4-flash-0731`,
|
|
1443
1492
|
upstreamModelId: "deepseek/deepseek-v4-flash-0731",
|
|
1444
1493
|
label: "DeepSeek V4 Flash 0731",
|
|
1445
|
-
|
|
1494
|
+
providers: ["baseten", "novita", "deepinfra"],
|
|
1446
1495
|
implicitCaching: true,
|
|
1447
1496
|
},
|
|
1448
1497
|
kimi: {
|
|
1449
|
-
productId: "kimi-k3
|
|
1450
|
-
workspaceProductId: `${WORKSPACE_GATEWAY_MODEL_ID_PREFIX}kimi-k3
|
|
1451
|
-
upstreamModelId: "moonshotai/kimi-k3
|
|
1452
|
-
label: "Kimi K3
|
|
1453
|
-
|
|
1498
|
+
productId: "kimi-k3",
|
|
1499
|
+
workspaceProductId: `${WORKSPACE_GATEWAY_MODEL_ID_PREFIX}kimi-k3`,
|
|
1500
|
+
upstreamModelId: "moonshotai/kimi-k3",
|
|
1501
|
+
label: "Kimi K3",
|
|
1502
|
+
providers: ["baseten", "fireworks"],
|
|
1454
1503
|
implicitCaching: true,
|
|
1455
1504
|
},
|
|
1456
1505
|
} as const;
|
|
@@ -1529,24 +1578,24 @@ export const defaultModelPricing: Record<string, ModelPricingScheduleV1> = {
|
|
|
1529
1578
|
},
|
|
1530
1579
|
],
|
|
1531
1580
|
},
|
|
1532
|
-
// Vercel AI Gateway
|
|
1533
|
-
//
|
|
1534
|
-
//
|
|
1535
|
-
//
|
|
1536
|
-
//
|
|
1581
|
+
// Conservative Vercel AI Gateway fallback prices. Normal managed Gateway
|
|
1582
|
+
// billing uses the exact response Gateway `cost` / `inferenceCost` and applies
|
|
1583
|
+
// the same margin. These token rates are used only if that
|
|
1584
|
+
// metadata is absent. DeepSeek therefore carries the highest approved route
|
|
1585
|
+
// (Novita); both approved Kimi routes have the same list price.
|
|
1537
1586
|
[OPENGENI_GATEWAY_MODELS.deepseek.productId]: {
|
|
1538
1587
|
default: {
|
|
1539
|
-
inputMicrosPerMillionTokens:
|
|
1540
|
-
cachedInputMicrosPerMillionTokens:
|
|
1541
|
-
outputMicrosPerMillionTokens:
|
|
1588
|
+
inputMicrosPerMillionTokens: 140_000,
|
|
1589
|
+
cachedInputMicrosPerMillionTokens: 28_000,
|
|
1590
|
+
outputMicrosPerMillionTokens: 280_000,
|
|
1542
1591
|
marginBps: 2_500,
|
|
1543
1592
|
},
|
|
1544
1593
|
},
|
|
1545
1594
|
[OPENGENI_GATEWAY_MODELS.kimi.productId]: {
|
|
1546
1595
|
default: {
|
|
1547
|
-
inputMicrosPerMillionTokens:
|
|
1548
|
-
cachedInputMicrosPerMillionTokens:
|
|
1549
|
-
outputMicrosPerMillionTokens:
|
|
1596
|
+
inputMicrosPerMillionTokens: 3_000_000,
|
|
1597
|
+
cachedInputMicrosPerMillionTokens: 300_000,
|
|
1598
|
+
outputMicrosPerMillionTokens: 15_000_000,
|
|
1550
1599
|
marginBps: 2_500,
|
|
1551
1600
|
},
|
|
1552
1601
|
},
|
|
@@ -2224,6 +2273,7 @@ function normalizeCapabilities(capabilities: ModelCapabilitiesV1): ModelCapabili
|
|
|
2224
2273
|
inputModalities: [...parsed.inputModalities].sort(
|
|
2225
2274
|
(left, right) => (MODALITY_ORDER.get(left) ?? 0) - (MODALITY_ORDER.get(right) ?? 0),
|
|
2226
2275
|
),
|
|
2276
|
+
inputFileMediaTypes: [...new Set(parsed.inputFileMediaTypes)].sort(),
|
|
2227
2277
|
outputModalities: [...parsed.outputModalities].sort(
|
|
2228
2278
|
(left, right) => (MODALITY_ORDER.get(left) ?? 0) - (MODALITY_ORDER.get(right) ?? 0),
|
|
2229
2279
|
),
|
|
@@ -2236,7 +2286,7 @@ function normalizeCapabilities(capabilities: ModelCapabilitiesV1): ModelCapabili
|
|
|
2236
2286
|
|
|
2237
2287
|
function legacyModelCapabilities(
|
|
2238
2288
|
settings: Settings,
|
|
2239
|
-
input: { reasoningEffort: boolean; hostedWebSearch: boolean },
|
|
2289
|
+
input: { reasoningEffort: boolean; hostedWebSearch: boolean; vision?: boolean },
|
|
2240
2290
|
): ModelCapabilitiesV1 {
|
|
2241
2291
|
const reasoningEfforts = input.reasoningEffort ? configuredAllowedReasoningEfforts(settings) : [];
|
|
2242
2292
|
return normalizeCapabilities({
|
|
@@ -2257,7 +2307,14 @@ function legacyModelCapabilities(
|
|
|
2257
2307
|
xSearch: { upstream: "unknown", runnable: false },
|
|
2258
2308
|
codeExecution: { upstream: "unknown", runnable: false },
|
|
2259
2309
|
},
|
|
2260
|
-
inputModalities: ["text"],
|
|
2310
|
+
inputModalities: input.vision ? ["text", "image"] : ["text"],
|
|
2311
|
+
inputFileMediaTypes: [
|
|
2312
|
+
"application/json",
|
|
2313
|
+
"application/pdf",
|
|
2314
|
+
"application/x-yaml",
|
|
2315
|
+
"application/yaml",
|
|
2316
|
+
"text/*",
|
|
2317
|
+
],
|
|
2261
2318
|
outputModalities: ["text"],
|
|
2262
2319
|
transports: {
|
|
2263
2320
|
sse: { upstream: "unknown", runnable: true },
|
|
@@ -2279,7 +2336,7 @@ export function gatewayRequestPolicyForUpstreamModel(
|
|
|
2279
2336
|
}
|
|
2280
2337
|
return {
|
|
2281
2338
|
gateway: {
|
|
2282
|
-
only: [model.
|
|
2339
|
+
only: [...model.providers] as [string, ...string[]],
|
|
2283
2340
|
caching: model.implicitCaching ? "auto" : "none",
|
|
2284
2341
|
},
|
|
2285
2342
|
};
|
|
@@ -2287,7 +2344,7 @@ export function gatewayRequestPolicyForUpstreamModel(
|
|
|
2287
2344
|
|
|
2288
2345
|
function gatewayModelCapabilities(
|
|
2289
2346
|
settings: Settings,
|
|
2290
|
-
input: { implicitCaching: boolean; vision: boolean },
|
|
2347
|
+
input: { implicitCaching: boolean; vision: boolean; inputFileMediaTypes?: string[] },
|
|
2291
2348
|
): ModelCapabilitiesV1 {
|
|
2292
2349
|
const legacy = legacyModelCapabilities(settings, {
|
|
2293
2350
|
reasoningEffort: true,
|
|
@@ -2297,6 +2354,7 @@ function gatewayModelCapabilities(
|
|
|
2297
2354
|
...legacy,
|
|
2298
2355
|
functionCalling: { upstream: "supported", runnable: true },
|
|
2299
2356
|
inputModalities: input.vision ? ["text", "image"] : ["text"],
|
|
2357
|
+
inputFileMediaTypes: input.inputFileMediaTypes ?? [],
|
|
2300
2358
|
transports: {
|
|
2301
2359
|
...legacy.transports,
|
|
2302
2360
|
sse: { upstream: "supported", runnable: true },
|
|
@@ -2304,8 +2362,8 @@ function gatewayModelCapabilities(
|
|
|
2304
2362
|
promptCaching: input.implicitCaching
|
|
2305
2363
|
? { upstream: "supported", runnable: true, mode: "implicit" }
|
|
2306
2364
|
: { upstream: "unsupported", runnable: false, mode: "none" },
|
|
2307
|
-
//
|
|
2308
|
-
// latency mode.
|
|
2365
|
+
// Both Gateway products expose one reviewed route policy and no separately
|
|
2366
|
+
// billed latency mode.
|
|
2309
2367
|
latencyModes: [{ id: "standard", upstream: "supported", runnable: true }],
|
|
2310
2368
|
});
|
|
2311
2369
|
}
|
|
@@ -2317,19 +2375,23 @@ function gatewayRegistryProvider(
|
|
|
2317
2375
|
| { kind: "vercel-gateway-workspace"; apiKey?: string },
|
|
2318
2376
|
): RegistryProvider {
|
|
2319
2377
|
const workspace = input.kind === "vercel-gateway-workspace";
|
|
2320
|
-
const models = [OPENGENI_GATEWAY_MODELS.deepseek, OPENGENI_GATEWAY_MODELS.kimi].map((model) =>
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2378
|
+
const models = [OPENGENI_GATEWAY_MODELS.deepseek, OPENGENI_GATEWAY_MODELS.kimi].map((model) => {
|
|
2379
|
+
const kimi = model === OPENGENI_GATEWAY_MODELS.kimi;
|
|
2380
|
+
return {
|
|
2381
|
+
id: workspace ? model.workspaceProductId : model.productId,
|
|
2382
|
+
upstreamModelId: model.upstreamModelId,
|
|
2383
|
+
label: model.label,
|
|
2384
|
+
capabilities: gatewayModelCapabilities(settings, {
|
|
2385
|
+
implicitCaching: model.implicitCaching,
|
|
2386
|
+
vision: kimi,
|
|
2387
|
+
inputFileMediaTypes: kimi ? ["application/pdf"] : [],
|
|
2388
|
+
}),
|
|
2389
|
+
contextWindowTokens: 1_000_000,
|
|
2390
|
+
effectiveContextWindowTokens: 900_000,
|
|
2391
|
+
autoCompactTokenLimit: 850_000,
|
|
2392
|
+
toolOutputTruncationTokens: settings.modelToolOutputTruncationTokens,
|
|
2393
|
+
};
|
|
2394
|
+
});
|
|
2333
2395
|
return {
|
|
2334
2396
|
kind: input.kind,
|
|
2335
2397
|
id: workspace ? WORKSPACE_GATEWAY_PROVIDER_ID : OPENGENI_GATEWAY_PROVIDER_ID,
|
|
@@ -2705,6 +2767,7 @@ export function withCodexCatalogProvider(settings: Settings): Settings {
|
|
|
2705
2767
|
...legacyModelCapabilities(settings, {
|
|
2706
2768
|
reasoningEffort: true,
|
|
2707
2769
|
hostedWebSearch: true,
|
|
2770
|
+
vision: slug.startsWith("gpt-5.6-"),
|
|
2708
2771
|
}),
|
|
2709
2772
|
...(builtinPromptCachingForModel(`${CODEX_MODEL_ID_PREFIX}${slug}`)
|
|
2710
2773
|
? {
|
|
@@ -2891,6 +2954,7 @@ export function configuredModels(settings: Settings): ConfiguredModel[] {
|
|
|
2891
2954
|
...legacyModelCapabilities(settings, {
|
|
2892
2955
|
reasoningEffort: true,
|
|
2893
2956
|
hostedWebSearch: settings.webSearchEnabled,
|
|
2957
|
+
vision: id.startsWith("gpt-5.6-"),
|
|
2894
2958
|
}),
|
|
2895
2959
|
...(builtinPromptCachingForModel(id)
|
|
2896
2960
|
? { promptCaching: builtinPromptCachingForModel(id)! }
|
|
@@ -3316,6 +3380,39 @@ export function calculateModelUsageCostMicros(
|
|
|
3316
3380
|
return total;
|
|
3317
3381
|
}
|
|
3318
3382
|
|
|
3383
|
+
/**
|
|
3384
|
+
* Convert AI Gateway's exact USD inference cost to OpenGeni credit micros and
|
|
3385
|
+
* apply the configured model margin. Decimal arithmetic is integer-only so a
|
|
3386
|
+
* sub-micro provider charge cannot be lost to floating-point rounding.
|
|
3387
|
+
*/
|
|
3388
|
+
export function calculateGatewayReportedCostMicros(
|
|
3389
|
+
settings: Settings,
|
|
3390
|
+
model: string,
|
|
3391
|
+
inferenceCostUsd: string,
|
|
3392
|
+
options?: { inputTokens?: number },
|
|
3393
|
+
): number {
|
|
3394
|
+
const schedule = configuredModelPricingSchedules(settings)[model];
|
|
3395
|
+
if (!schedule) {
|
|
3396
|
+
throw new Error(`Missing model pricing for ${model}`);
|
|
3397
|
+
}
|
|
3398
|
+
const pricing = selectModelPricing(schedule, positiveInt(options?.inputTokens));
|
|
3399
|
+
const match = /^(0|[1-9]\d*)(?:\.(\d{1,18}))?$/.exec(inferenceCostUsd);
|
|
3400
|
+
if (!match) {
|
|
3401
|
+
throw new Error("Invalid AI Gateway inference cost");
|
|
3402
|
+
}
|
|
3403
|
+
const fraction = match[2] ?? "";
|
|
3404
|
+
const decimalDigits = BigInt(`${match[1]}${fraction}`);
|
|
3405
|
+
const decimalScale = 10n ** BigInt(fraction.length);
|
|
3406
|
+
const marginBps = BigInt(10_000 + (pricing.marginBps ?? 0));
|
|
3407
|
+
const numerator = decimalDigits * 1_000_000n * marginBps;
|
|
3408
|
+
const denominator = decimalScale * 10_000n;
|
|
3409
|
+
const micros = (numerator + denominator - 1n) / denominator;
|
|
3410
|
+
if (micros > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
3411
|
+
throw new Error("AI Gateway inference cost exceeds the supported billing range");
|
|
3412
|
+
}
|
|
3413
|
+
return Number(micros);
|
|
3414
|
+
}
|
|
3415
|
+
|
|
3319
3416
|
export function configuredAllowedReasoningEfforts(
|
|
3320
3417
|
settings: Settings,
|
|
3321
3418
|
): Array<z.infer<typeof ReasoningEffort>> {
|