@jeffusion/bungee-core 5.23.0 → 5.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // plugins/codex-router/server/index.ts
3
- import { createHash as createHash2 } from "crypto";
3
+ import { createHash as createHash3 } from "crypto";
4
4
 
5
5
  // packages/core/src/plugin-logger.ts
6
6
  var sinkKey = Symbol.for("@jeffusion/bungee/plugin-log-sink");
@@ -704,25 +704,6 @@ function protocolAdapter(input) {
704
704
  });
705
705
  } };
706
706
  }
707
-
708
- // plugins/models-dev/contract.ts
709
- var MODELS_DEV_CATALOG_SNAPSHOT_ID = "models-dev.catalog.snapshot.v1";
710
- var MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT_VERSION = 1;
711
- var MODELS_DEV_CATALOG_SNAPSHOT_SCHEMA = Object.freeze({
712
- type: "object",
713
- properties: {
714
- version: { type: "number", integer: true, minimum: 1 },
715
- fetchedAt: { type: "number", minimum: 0 },
716
- catalog: { type: "json", maxBytes: 32 * 1024 * 1024 }
717
- }
718
- });
719
- var MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT = Object.freeze({
720
- id: MODELS_DEV_CATALOG_SNAPSHOT_ID,
721
- version: MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT_VERSION,
722
- content: MODELS_DEV_CATALOG_SNAPSHOT_SCHEMA
723
- });
724
- var MODELS_DEV_CAPABILITIES_SERVICE_ID = "models-dev.capabilities.v1";
725
- var MODELS_DEV_CAPABILITIES_CONTRACT_VERSION = 1;
726
707
  // plugins/codex-router/manifest.json
727
708
  var manifest_default = {
728
709
  name: "codex-router",
@@ -763,13 +744,6 @@ var manifest_default = {
763
744
  process: "control",
764
745
  kind: "local"
765
746
  },
766
- {
767
- plugin: "models-dev",
768
- id: "models-dev.catalog.v1",
769
- version: 1,
770
- process: "worker",
771
- kind: "local"
772
- },
773
747
  {
774
748
  plugin: "models-dev",
775
749
  id: "models-dev.capabilities.v1",
@@ -777,13 +751,6 @@ var manifest_default = {
777
751
  process: "control",
778
752
  kind: "local"
779
753
  },
780
- {
781
- plugin: "models-dev",
782
- id: "models-dev.capabilities.v1",
783
- version: 1,
784
- process: "worker",
785
- kind: "local"
786
- },
787
754
  {
788
755
  plugin: "llm-protocol-adapter",
789
756
  id: "llm-protocol-adapter.conversion.v1",
@@ -804,9 +771,23 @@ var manifest_default = {
804
771
  version: 1,
805
772
  process: "worker",
806
773
  kind: "rpc"
774
+ },
775
+ {
776
+ plugin: "codex-router",
777
+ id: "codex-router.catalog-validators.v1",
778
+ version: 1,
779
+ process: "worker",
780
+ kind: "rpc"
807
781
  }
808
782
  ],
809
- provides: []
783
+ provides: [
784
+ {
785
+ id: "codex-router.catalog-validators.v1",
786
+ version: 1,
787
+ process: "control",
788
+ kind: "rpc"
789
+ }
790
+ ]
810
791
  },
811
792
  configSchema: [
812
793
  {
@@ -1218,8 +1199,61 @@ function mergeCatalog(native, bindings, catalog) {
1218
1199
  }
1219
1200
  return { ...body, [rich ? "models" : "data"]: [...existing.filter((entry) => !unavailable.has(rich ? entry.slug : entry.id)).map((entry) => replacements.get(rich ? entry.slug : entry.id) ?? entry), ...added] };
1220
1201
  }
1221
- function catalogEtag(body, version, clientVersion) {
1222
- return `"${createHash("sha256").update(JSON.stringify([body, version, clientVersion])).digest("hex")}"`;
1202
+ function catalogEtag(body) {
1203
+ return `"${createHash("sha256").update(body, "utf8").digest("hex")}"`;
1204
+ }
1205
+
1206
+ // plugins/codex-router/contract.ts
1207
+ var key2 = { type: "string", minLength: 64, maxLength: 64 };
1208
+ var etag = { type: "string", minLength: 66, maxLength: 66 };
1209
+ var catalogValidatorsRpc = defineRpcService({
1210
+ id: "codex-router.catalog-validators.v1",
1211
+ version: 1,
1212
+ methods: {
1213
+ get: {
1214
+ kind: "query",
1215
+ input: { type: "object", properties: { key: key2 } },
1216
+ output: { type: "union", variants: [etag, { type: "null" }] },
1217
+ purposes: ["request", "attempt"]
1218
+ },
1219
+ put: {
1220
+ kind: "command",
1221
+ input: { type: "object", properties: { key: key2, etag } },
1222
+ output: { type: "null" },
1223
+ purposes: ["request", "attempt"],
1224
+ command: { deduplication: "none", resultRetentionMs: 1, quotaBytes: 1024, maxResultBytes: 1024 }
1225
+ }
1226
+ }
1227
+ });
1228
+ function catalogValidatorsClient(services) {
1229
+ return services.rpc.consume("codex-router", catalogValidatorsRpc);
1230
+ }
1231
+
1232
+ // plugins/codex-router/server/catalog-validators.ts
1233
+ import { createHash as createHash2 } from "crypto";
1234
+ function header(headers, name) {
1235
+ return Object.entries(headers).find(([key]) => key.toLowerCase() === name)?.[1] ?? "";
1236
+ }
1237
+ function catalogValidatorKey({ context, principal, servingRevision }, bindings) {
1238
+ const directory = context.method === "GET" && /\/models$/.test(context.originalUrl.pathname);
1239
+ const generation = context.method === "POST" && /\/responses$/.test(context.originalUrl.pathname);
1240
+ if (!directory && !generation || !context.routeId)
1241
+ return null;
1242
+ const versions = context.originalUrl.searchParams.getAll("client_version");
1243
+ const version = directory ? versions.length === 1 ? versions[0] : "" : header(context.headers, "version");
1244
+ if (!version || version.length > 128 || /[\u0000-\u0020\u007f]/.test(version))
1245
+ return null;
1246
+ return createHash2("sha256").update(JSON.stringify([
1247
+ context.routeId,
1248
+ servingRevision ?? null,
1249
+ bindings,
1250
+ principal ? [principal.domain, principal.keyId, principal.credentialVersion] : ["anonymous", "", 0],
1251
+ header(context.headers, "authorization"),
1252
+ header(context.headers, "x-api-key"),
1253
+ header(context.headers, "api-key"),
1254
+ header(context.headers, "chatgpt-account-id"),
1255
+ version
1256
+ ])).digest("hex");
1223
1257
  }
1224
1258
 
1225
1259
  // plugins/codex-router/server/index.ts
@@ -1230,7 +1264,8 @@ var CodexRouterPlugin = definePlugin(class {
1230
1264
  bindings;
1231
1265
  relay;
1232
1266
  history;
1233
- catalog;
1267
+ validators;
1268
+ catalogRequests = new Map;
1234
1269
  conversion;
1235
1270
  constructor(options) {
1236
1271
  this.bindings = parseBindings(options?.models);
@@ -1241,19 +1276,29 @@ var CodexRouterPlugin = definePlugin(class {
1241
1276
  throw new Error("codex_router_requires_route_scope");
1242
1277
  this.history = historyClient(context.services.rpc.consume(ADAPTER_PLUGIN, historyRpc));
1243
1278
  this.conversion = context.services.consume(ADAPTER_PLUGIN, CONVERSION_SERVICE_ID, CONVERSION_VERSION);
1244
- this.catalog = context.services.consume("models-dev", MODELS_DEV_CAPABILITIES_SERVICE_ID, MODELS_DEV_CAPABILITIES_CONTRACT_VERSION);
1279
+ try {
1280
+ this.validators = catalogValidatorsClient(context.services);
1281
+ } catch {}
1282
+ context.services.onDispose?.(() => this.catalogRequests.clear());
1245
1283
  }
1246
1284
  bodyRequirements(context) {
1247
1285
  return { request: context.method === "POST" && /\/responses$/.test(context.url.pathname) ? "json-write" : "none", response: context.method === "GET" && /\/models$/.test(context.url.pathname) ? ["json"] : [] };
1248
1286
  }
1249
1287
  register(hooks) {
1250
1288
  hooks.onWebSocketSessionMode.tap("codex-router.session", (url) => /\/responses$/.test(url.pathname) ? "responses" : undefined);
1289
+ hooks.onDispatchRequest.tap("codex-router.catalog-identity", (input) => {
1290
+ const key = catalogValidatorKey(input, this.bindings);
1291
+ if (key)
1292
+ this.catalogRequests.set(input.context.requestId, { key, signal: input.signal });
1293
+ });
1251
1294
  hooks.onDispatchRequest.tapPromise("codex-router.binding", async ({ context, targets }) => {
1252
1295
  if (context.method !== "POST" || !/\/responses$/.test(context.originalUrl.pathname))
1253
1296
  return;
1254
1297
  const binding = this.bindings.find((binding) => bindingSource(binding) === context.body?.model);
1255
1298
  if (!binding)
1256
1299
  return;
1300
+ const notification = this.catalogRequests.get(context.requestId);
1301
+ this.catalogRequests.delete(context.requestId);
1257
1302
  if (!targets.some((target) => target.type === binding.target.type && target.id === binding.target.id))
1258
1303
  throw new DataAdmissionError(422, "codex_router_target_unavailable");
1259
1304
  const protocol = binding.target.protocol;
@@ -1262,8 +1307,8 @@ var CodexRouterPlugin = definePlugin(class {
1262
1307
  throw new DataAdmissionError(503, "codex_router_model_unavailable");
1263
1308
  context.body = { ...context.body, model: binding.model };
1264
1309
  return { target: binding.target, protocol, prepareRequest: async ({ context, principal, servingRevision, signal, executeAuxiliary, webSocketConnection }) => {
1265
- const entryScope = createHash2("sha256").update(JSON.stringify([context.routeId, servingRevision ?? null, this.bindings, this.relay])).digest("hex");
1266
- const scope = principal?.domain !== "anonymous" && principal?.keyId ? createHash2("sha256").update(JSON.stringify([principal, entryScope])).digest("hex") : null;
1310
+ const entryScope = createHash3("sha256").update(JSON.stringify([context.routeId, servingRevision ?? null, this.bindings, this.relay])).digest("hex");
1311
+ const scope = principal?.domain !== "anonymous" && principal?.keyId ? createHash3("sha256").update(JSON.stringify([principal, entryScope])).digest("hex") : null;
1267
1312
  let input = structuredClone(context.body);
1268
1313
  let requiredUpstreamId;
1269
1314
  let opaqueRestored = false;
@@ -1346,9 +1391,7 @@ var CodexRouterPlugin = definePlugin(class {
1346
1391
  throw new DataAdmissionError(422, `llm_adapter_${e.code}`, undefined, { message: e.message, param: e.param });
1347
1392
  throw error;
1348
1393
  }
1349
- if (protocol !== "responses")
1350
- context.url.pathname = context.url.pathname.replace(/\/responses$/, protocol === "chat_completions" ? "/chat/completions" : "/messages");
1351
- const adapter = protocolAdapter({
1394
+ const converted = protocolAdapter({
1352
1395
  session,
1353
1396
  protocol,
1354
1397
  model: bindingSource(binding),
@@ -1358,6 +1401,13 @@ var CodexRouterPlugin = definePlugin(class {
1358
1401
  await this.history.put({ scope, id: response.id, value: { target: binding.target, origin: { provider: binding.provider, model: binding.model, upstreamId: responseContext?.upstreamId }, items: [...logicalInput, ...response.output] } }, { signal, operationId: crypto.randomUUID() });
1359
1402
  }
1360
1403
  });
1404
+ const adapter = { bodyRequirements: converted.bodyRequirements.bind(converted), register: (hooks) => {
1405
+ converted.register(hooks);
1406
+ hooks.onRawResponse.tapPromise("codex-router.catalog-notification", async (result) => {
1407
+ await this.rewriteCatalogNotification(result.response, notification);
1408
+ return result;
1409
+ });
1410
+ } };
1361
1411
  return { requiredUpstreamId, adapter, ...protocol !== "responses" ? { canonicalInput: logicalInput, diagnostics } : {} };
1362
1412
  } };
1363
1413
  });
@@ -1369,20 +1419,49 @@ var CodexRouterPlugin = definePlugin(class {
1369
1419
  }
1370
1420
  return context;
1371
1421
  });
1422
+ hooks.onRawResponse.tapPromise("codex-router.catalog-notification", async (result, context) => {
1423
+ if (context.method === "POST" && /\/responses$/.test(context.originalUrl.pathname)) {
1424
+ await this.rewriteCatalogNotification(result.response, this.catalogRequests.get(context.requestId));
1425
+ }
1426
+ return result;
1427
+ });
1372
1428
  hooks.onResponse.tapPromise("codex-router.catalog", async (response, context) => {
1429
+ const record = this.catalogRequests.get(context.requestId);
1373
1430
  if (context.method !== "GET" || !/\/models$/.test(context.originalUrl.pathname) || !response.ok)
1374
1431
  return response;
1375
1432
  const native = await context.bodyHandle.json({ id: "codex-router.catalog", mandatory: true });
1376
- const body = mergeCatalog(native, this.bindings, this.conversion);
1433
+ const body = JSON.stringify(mergeCatalog(native, this.bindings, this.conversion));
1434
+ const etag = catalogEtag(body);
1377
1435
  const headers = new Headers(response.headers);
1378
1436
  for (const key of ["content-length", "content-encoding", "etag", "last-modified"])
1379
1437
  headers.delete(key);
1380
1438
  headers.set("content-type", "application/json");
1381
1439
  headers.set("cache-control", "private, no-store");
1382
- headers.set("etag", catalogEtag(body, this.catalog.status().version, context.originalUrl.searchParams.get("client_version") ?? ""));
1383
- return new Response(JSON.stringify(body), { status: response.status, headers });
1440
+ headers.set("etag", etag);
1441
+ if (record && this.validators) {
1442
+ try {
1443
+ await this.validators.put({ key: record.key, etag }, { signal: record.signal, timeoutMs: 1000, operationId: crypto.randomUUID() });
1444
+ } catch {}
1445
+ }
1446
+ return new Response(body, { status: response.status, headers });
1447
+ });
1448
+ hooks.onFinally.tap("codex-router.catalog-cleanup", (context) => {
1449
+ this.catalogRequests.delete(context.requestId);
1384
1450
  });
1385
1451
  }
1452
+ async rewriteCatalogNotification(response, record) {
1453
+ response.headers.delete("x-models-etag");
1454
+ if (record && this.validators) {
1455
+ try {
1456
+ const etag = await this.validators.get({ key: record.key }, { signal: record.signal, timeoutMs: 1000 });
1457
+ if (etag && !record.signal.aborted)
1458
+ response.headers.set("x-models-etag", etag);
1459
+ } catch {}
1460
+ }
1461
+ }
1462
+ reset() {
1463
+ this.catalogRequests.clear();
1464
+ }
1386
1465
  });
1387
1466
  var server_default = CodexRouterPlugin;
1388
1467
  export {
@@ -1390,4 +1469,4 @@ export {
1390
1469
  server_default as default
1391
1470
  };
1392
1471
 
1393
- //# debugId=15F3624284EDF84064756E2164756E21
1472
+ //# debugId=C5F01ADAD6007FBF64756E2164756E21