@jeffusion/bungee-core 5.23.1 → 5.23.3

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.
@@ -851,6 +851,7 @@ var retryActionBrand = Symbol.for("@jeffusion/bungee/request-retry-action");
851
851
  var HOUR = 3600000;
852
852
  var TOKEN_STATS_RETENTION_MS = 31 * 24 * HOUR;
853
853
  // plugins/models-dev/contract.ts
854
+ var MODEL_IDENTITY_ANNOTATION_KEY = "models-dev.model-identity";
854
855
  var MODELS_DEV_CATALOG_SNAPSHOT_ID = "models-dev.catalog.snapshot.v1";
855
856
  var MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT_VERSION = 1;
856
857
  var MODELS_DEV_CATALOG_SNAPSHOT_SCHEMA = Object.freeze({
@@ -909,6 +910,9 @@ function historyClient(rpc) {
909
910
  }
910
911
  };
911
912
  }
913
+ function readModelIdentity(annotations) {
914
+ return annotations?.[MODEL_IDENTITY_ANNOTATION_KEY];
915
+ }
912
916
  // node_modules/base64-js/index.js
913
917
  var $toByteArray = toByteArray;
914
918
  var lookup = [];
@@ -6031,6 +6035,32 @@ function validateStreamEnvelope(raw, protocol) {
6031
6035
  validateUsage(e.usage, protocol);
6032
6036
  }
6033
6037
  }
6038
+ // packages/llms/src/protocol-session/endpoint.ts
6039
+ function protocolRequestModel(protocol, body, url) {
6040
+ if (protocol === "gemini_generate_content") {
6041
+ let path;
6042
+ try {
6043
+ path = new URL(url).pathname;
6044
+ } catch {
6045
+ return fail("invalid_payload", "A valid Gemini target URL is required", "url");
6046
+ }
6047
+ const match = path.match(/\/models\/([^/]+):(?:streamGenerateContent|generateContent)$/);
6048
+ if (!match)
6049
+ return fail("invalid_payload", "Gemini target URL has no terminal model", "url");
6050
+ try {
6051
+ const model = decodeURIComponent(match[1]);
6052
+ if (model)
6053
+ return model;
6054
+ } catch {
6055
+ return fail("invalid_payload", "Gemini target model encoding is invalid", "url");
6056
+ }
6057
+ return fail("invalid_payload", "Gemini target model is required", "url");
6058
+ }
6059
+ const model = body?.model;
6060
+ if (typeof model !== "string" || !model)
6061
+ return fail("invalid_payload", "Target model is required", "model");
6062
+ return model;
6063
+ }
6034
6064
  // plugins/llm-protocol-adapter/server/relay.ts
6035
6065
  import { createHash } from "crypto";
6036
6066
 
@@ -6481,10 +6511,25 @@ class AgentRelay {
6481
6511
  }
6482
6512
 
6483
6513
  // plugins/llm-protocol-adapter/server/service.ts
6484
- var REASONING_RULES_VERSION = "2026-10-10.3";
6514
+ var REASONING_RULES_VERSION = "2026-10-12.1";
6485
6515
  var concrete = new Set(["none", "minimal", "low", "medium", "high", "xhigh", "max"]);
6486
- function catalogModel(provider, model) {
6487
- return provider === "zai" && model === "GLM-5.3-Flash" ? "glm-5.3-flash" : model;
6516
+ function identityError(code, message) {
6517
+ throw new ResponsesCodecError(code, message, "modelIdentity");
6518
+ }
6519
+ function parseModelIdentity(value) {
6520
+ if (value === undefined)
6521
+ return;
6522
+ const object = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
6523
+ const identifier = (v) => typeof v === "string" && v.length > 0 && v === v.trim();
6524
+ if (!object(value) || Object.keys(value).length !== 2 || !Object.keys(value).every((key) => ["wireModel", "catalogModel"].includes(key)) || !identifier(value.wireModel) || !object(value.catalogModel) || Object.keys(value.catalogModel).length !== 2 || !Object.keys(value.catalogModel).every((key) => ["provider", "model"].includes(key)) || !identifier(value.catalogModel.provider) || !identifier(value.catalogModel.model))
6525
+ throw new ResponsesCodecError("invalid_model_identity", "Model identity declaration is invalid", "modelIdentity");
6526
+ return { wireModel: value.wireModel, catalogModel: { provider: value.catalogModel.provider, model: value.catalogModel.model } };
6527
+ }
6528
+ function checkedIdentity(value, model) {
6529
+ const identity = parseModelIdentity(value);
6530
+ if (identity && identity.wireModel !== model)
6531
+ identityError("model_identity_mismatch", "Declared wire model differs from the actual target");
6532
+ return identity;
6488
6533
  }
6489
6534
  function rule(provider, model, protocol) {
6490
6535
  if (provider === "zai" && ["glm-5.3", "glm-5.3-flash"].includes(model) && protocol === "chat_completions")
@@ -6498,7 +6543,6 @@ function rule(provider, model, protocol) {
6498
6543
  return null;
6499
6544
  }
6500
6545
  function resolveCapabilities(catalog, context) {
6501
- context = { ...context, model: catalogModel(context.provider, context.model) };
6502
6546
  const info = catalog.model(context);
6503
6547
  if (!info)
6504
6548
  return null;
@@ -6560,8 +6604,15 @@ function conversionService(catalog, worker, history, runBackground) {
6560
6604
  createSession(context) {
6561
6605
  if (!worker)
6562
6606
  throw new Error("llm_adapter_conversion_requires_worker");
6563
- const info = context.profile ?? catalog.model({ provider: context.provider, model: catalogModel(context.provider, context.model) });
6564
- const profile = context.profile ? structuredClone(context.profile) : info ? resolveCapabilities(catalog, { provider: info.provider, model: context.model, targetProtocol: context.targetProtocol }) : undefined;
6607
+ const declaration = checkedIdentity(context.modelIdentity, context.model);
6608
+ const restrictions = context.restrictions ? structuredClone(context.restrictions) : undefined;
6609
+ const reference = declaration?.catalogModel ?? { provider: context.provider, model: context.model };
6610
+ const info = context.profile ?? catalog.model(reference);
6611
+ let profile = context.profile ? structuredClone(context.profile) : info ? resolveCapabilities(catalog, { provider: info.provider, model: info.model, targetProtocol: context.targetProtocol, restrictions }) : null;
6612
+ if (declaration && (!profile || profile.provider !== reference.provider || profile.model !== reference.model))
6613
+ identityError("model_identity_unavailable", "Declared catalog model is unavailable");
6614
+ const entryProfile = profile;
6615
+ let catalogVersion = profile?.catalogVersion ?? null;
6565
6616
  let selected = context.selectedEffort;
6566
6617
  const passthrough = context.sourceProtocol === context.targetProtocol;
6567
6618
  if (!passthrough && selected !== undefined && (!profile || !profile.supportedEfforts.includes(selected)))
@@ -6594,29 +6645,56 @@ function conversionService(catalog, worker, history, runBackground) {
6594
6645
  engine.dispose();
6595
6646
  }
6596
6647
  },
6597
- validateAttempt({ model, protocol, body, url }) {
6648
+ validateAttempt({ model, protocol, body, url, modelIdentity }) {
6598
6649
  if (disposed)
6599
6650
  throw new Error("llm_adapter_session_disposed");
6600
6651
  if (protocol !== context.targetProtocol)
6601
6652
  throw new ResponsesCodecError("target_protocol_mismatch", "Actual target protocol differs from the session", "url");
6602
6653
  if (url) {
6603
- const path = new URL(url).pathname;
6654
+ let path;
6655
+ try {
6656
+ path = new URL(url).pathname;
6657
+ } catch {
6658
+ throw new ResponsesCodecError("target_protocol_mismatch", "Actual target URL is invalid", "url");
6659
+ }
6604
6660
  const valid = protocol === "responses" ? /\/responses$/.test(path) : protocol === "chat_completions" ? /\/chat\/completions$/.test(path) : protocol === "anthropic_messages" ? /\/messages$/.test(path) : /:(?:streamGenerateContent|generateContent)$/.test(path);
6605
6661
  if (!valid)
6606
6662
  throw new ResponsesCodecError("target_protocol_mismatch", "Actual target URL does not implement the session protocol", "url");
6607
6663
  }
6608
- const actual = profile && profile.model === catalogModel(profile.provider, model) ? profile : profile ? resolveCapabilities(catalog, { provider: profile.provider, model, targetProtocol: protocol }) : null;
6664
+ const actualModel = protocolRequestModel(protocol, body, url);
6665
+ const identity = checkedIdentity(modelIdentity, actualModel);
6666
+ if (model !== actualModel)
6667
+ identityError("model_identity_mismatch", "Model argument differs from the actual target");
6668
+ model = actualModel;
6669
+ const reference = identity?.catalogModel ?? { provider: profile?.provider ?? context.provider, model };
6670
+ const sameIdentity = !!profile && reference.provider === profile.provider && reference.model === profile.model;
6671
+ const info = sameIdentity ? profile : catalog.model(reference);
6672
+ const actual = sameIdentity ? profile : info ? resolveCapabilities(catalog, { provider: info.provider, model: info.model, targetProtocol: protocol, restrictions }) : null;
6673
+ if (identity && !actual)
6674
+ identityError("model_identity_unavailable", "Declared catalog model is unavailable");
6675
+ if (actual && catalogVersion !== null && actual.catalogVersion !== catalogVersion)
6676
+ identityError("model_identity_catalog_changed", "Target catalog version differs from the generation snapshot");
6677
+ const sameNativeIdentity = entryProfile ? !!actual && actual.provider === entryProfile.provider && actual.model === entryProfile.model : !identity && model === context.model;
6609
6678
  if (selected !== undefined) {
6610
- if (passthrough && model === context.model && wireEffort(body, protocol) === selected)
6611
- return { model, effort: selected, catalogVersion: profile?.catalogVersion ?? null, rulesVersion: REASONING_RULES_VERSION };
6612
- if (!actual || actual.catalogVersion !== profile?.catalogVersion || actual.rulesVersion !== profile?.rulesVersion || !actual.supportedEfforts.includes(selected) || wireEffort(body, protocol) !== selected)
6613
- fail2("reasoning.effort");
6614
- if (protocol === "anthropic_messages" && body?.thinking?.type !== "adaptive")
6615
- fail2("thinking.type");
6616
- if (protocol === "chat_completions" && profile?.provider === "zai" && body?.thinking?.type !== "enabled")
6617
- fail2("thinking.type");
6679
+ if (!(passthrough && sameNativeIdentity && wireEffort(body, protocol) === selected)) {
6680
+ if (!entryProfile || !actual || actual.rulesVersion !== entryProfile.rulesVersion || !actual.supportedEfforts.includes(selected) || wireEffort(body, protocol) !== selected)
6681
+ fail2("reasoning.effort");
6682
+ if (protocol === "anthropic_messages" && body?.thinking?.type !== "adaptive")
6683
+ fail2("thinking.type");
6684
+ if (protocol === "chat_completions" && actual.provider === "zai" && body?.thinking?.type !== "enabled")
6685
+ fail2("thinking.type");
6686
+ }
6687
+ } else if (!profile && actual && identity) {
6688
+ profile = structuredClone(actual);
6689
+ catalogVersion = actual.catalogVersion;
6618
6690
  }
6619
- return { model, effort: selected ?? null, catalogVersion: profile?.catalogVersion ?? null, rulesVersion: REASONING_RULES_VERSION };
6691
+ return {
6692
+ model,
6693
+ catalogModel: actual ? { provider: actual.provider, model: actual.model } : null,
6694
+ effort: selected ?? null,
6695
+ catalogVersion,
6696
+ rulesVersion: REASONING_RULES_VERSION
6697
+ };
6620
6698
  }
6621
6699
  };
6622
6700
  return session;
@@ -6651,7 +6729,7 @@ function responseHandler(input) {
6651
6729
  hooks.onValidateOutbound.tapPromise("llm-adapter.target", async (outbound) => {
6652
6730
  check();
6653
6731
  try {
6654
- const result = input.session.validateAttempt({ model: outbound.model ?? input.model, protocol: input.targetProtocol, body: outbound.body, url: outbound.url });
6732
+ const result = input.session.validateAttempt({ model: protocolRequestModel(input.targetProtocol, outbound.body, outbound.url), modelIdentity: readModelIdentity(outbound.annotations), protocol: input.targetProtocol, body: outbound.body, url: outbound.url });
6655
6733
  logger.info({ requestId: outbound.requestId, attemptId: outbound.attemptId, ...result }, "llm_adapter_target_validated");
6656
6734
  input.log?.(result);
6657
6735
  } catch (e) {
@@ -6659,6 +6737,8 @@ function responseHandler(input) {
6659
6737
  }
6660
6738
  return outbound;
6661
6739
  });
6740
+ if (input.validationOnly)
6741
+ return;
6662
6742
  hooks.onResponse.tapPromise("llm-adapter.response", async (response, ctx) => {
6663
6743
  context = ctx;
6664
6744
  if (!response.ok || !response.headers.get("content-type")?.includes("json"))
@@ -6985,7 +7065,7 @@ var server_default = definePlugin(class {
6985
7065
  });
6986
7066
  }
6987
7067
  bodyRequirements(ctx) {
6988
- return this.applied && ctx.method === "POST" && protocolForPath(ctx.url.pathname) !== null ? { request: "json-write", response: ["json", "sse-json"] } : { request: "none" };
7068
+ return this.applied && ctx.method === "POST" && protocolForPath(ctx.url.pathname) !== null ? { request: "json-write", ...this.options?.sourceProtocol !== this.options?.targetProtocol ? { response: ["json", "sse-json"] } : {} } : { request: "none" };
6989
7069
  }
6990
7070
  register(hooks) {
6991
7071
  if (!this.applied)
@@ -7001,27 +7081,42 @@ var server_default = definePlugin(class {
7001
7081
  }
7002
7082
  if (source !== this.options.sourceProtocol)
7003
7083
  throw new DataAdmissionError(422, "llm_adapter_source_protocol_mismatch");
7004
- if (source === this.options.targetProtocol)
7005
- return ctx;
7006
- if (this.active.has(ctx.requestId))
7084
+ if (this.active.has(ctx.requestId)) {
7085
+ if (source === this.options.targetProtocol)
7086
+ return ctx;
7007
7087
  throw new DataAdmissionError(422, "llm_adapter_duplicate_conversion");
7008
- const model = source === "gemini_generate_content" ? decodeURIComponent(ctx.url.pathname.match(/\/models\/([^/]+):/)[1]) : ctx.body?.model;
7009
- if (typeof model !== "string" || !model)
7010
- throw new DataAdmissionError(422, "llm_adapter_model_required");
7011
- const session = this.service.createSession({ sourceProtocol: source, targetProtocol: this.options.targetProtocol, model, ...source === "gemini_generate_content" ? { streaming: ctx.url.pathname.endsWith(":streamGenerateContent") } : {} });
7088
+ }
7089
+ let session;
7090
+ let model;
7012
7091
  try {
7092
+ model = protocolRequestModel(source, ctx.body, ctx.url);
7093
+ session = this.service.createSession({
7094
+ sourceProtocol: source,
7095
+ targetProtocol: this.options.targetProtocol,
7096
+ model,
7097
+ modelIdentity: readModelIdentity(ctx.annotations),
7098
+ ...source === "gemini_generate_content" ? { streaming: ctx.url.pathname.endsWith(":streamGenerateContent") } : {}
7099
+ });
7013
7100
  const result = session.convertRequest(ctx.body);
7014
- if (result.diagnostics.length)
7015
- logger.info({ requestId: ctx.requestId, diagnostics: structuredClone(result.diagnostics) }, "llm_adapter_request_diagnostics");
7016
- ctx.body = structuredClone(result.body);
7017
- ctx.url.pathname = targetPath(ctx.url.pathname, this.options.targetProtocol, model, result.streaming);
7018
- if (this.options.targetProtocol === "gemini_generate_content" && result.streaming)
7019
- ctx.url.searchParams.set("alt", "sse");
7101
+ if (source !== this.options.targetProtocol) {
7102
+ if (result.diagnostics.length)
7103
+ logger.info({ requestId: ctx.requestId, diagnostics: structuredClone(result.diagnostics) }, "llm_adapter_request_diagnostics");
7104
+ ctx.body = structuredClone(result.body);
7105
+ ctx.url.pathname = targetPath(ctx.url.pathname, this.options.targetProtocol, model, result.streaming);
7106
+ if (this.options.targetProtocol === "gemini_generate_content" && result.streaming)
7107
+ ctx.url.searchParams.set("alt", "sse");
7108
+ }
7020
7109
  } catch (error) {
7021
- session.dispose();
7110
+ session?.dispose();
7022
7111
  adapterError(error);
7023
7112
  }
7024
- const handler = responseHandler({ session, sourceProtocol: source, targetProtocol: this.options.targetProtocol, model });
7113
+ const handler = responseHandler({
7114
+ session,
7115
+ sourceProtocol: source,
7116
+ targetProtocol: this.options.targetProtocol,
7117
+ model,
7118
+ validationOnly: source === this.options.targetProtocol
7119
+ });
7025
7120
  this.active.set(ctx.requestId, { handler, session });
7026
7121
  return ctx;
7027
7122
  });
@@ -7048,4 +7143,4 @@ export {
7048
7143
  targetPath
7049
7144
  };
7050
7145
 
7051
- //# debugId=518F8C65B84A06CF64756E2164756E21
7146
+ //# debugId=40CBB2F3F4855EA864756E2164756E21