@jeffusion/bungee-core 5.23.1 → 5.23.2
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/config-storage-worker.js +3 -1
- package/dist/main.js +65 -53
- package/dist/plugins/codex-router/control.js +1 -1
- package/dist/plugins/codex-router/control.js.map +3 -3
- package/dist/plugins/codex-router/index.js +2289 -3
- package/dist/plugins/codex-router/index.js.map +17 -6
- package/dist/plugins/llm-protocol-adapter/control.js +93 -19
- package/dist/plugins/llm-protocol-adapter/control.js.map +7 -6
- package/dist/plugins/llm-protocol-adapter/index.js +131 -36
- package/dist/plugins/llm-protocol-adapter/index.js.map +10 -9
- package/dist/plugins/model-mapping/control.js +1 -1
- package/dist/plugins/model-mapping/control.js.map +3 -3
- package/dist/plugins/model-mapping/index.js +48 -17
- package/dist/plugins/model-mapping/index.js.map +6 -5
- package/dist/plugins/model-mapping/manifest.json +50 -6
- package/dist/plugins/models-dev/control.js +1 -1
- package/dist/plugins/models-dev/control.js.map +3 -3
- package/dist/plugins/models-dev/index.js +1 -1
- package/dist/plugins/models-dev/index.js.map +3 -3
- package/dist/plugins/token-stats/control.js +1 -1
- package/dist/plugins/token-stats/control.js.map +3 -3
- package/dist/plugins/token-stats/index.js +1 -1
- package/dist/plugins/token-stats/index.js.map +3 -3
- package/package.json +2 -2
|
@@ -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-
|
|
6514
|
+
var REASONING_RULES_VERSION = "2026-10-12.1";
|
|
6485
6515
|
var concrete = new Set(["none", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
6486
|
-
function
|
|
6487
|
-
|
|
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
|
|
6564
|
-
const
|
|
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
|
-
|
|
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
|
|
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 &&
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
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 {
|
|
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.
|
|
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 (
|
|
7005
|
-
|
|
7006
|
-
|
|
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
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
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 (
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
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
|
|
7110
|
+
session?.dispose();
|
|
7022
7111
|
adapterError(error);
|
|
7023
7112
|
}
|
|
7024
|
-
const handler = responseHandler({
|
|
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=
|
|
7146
|
+
//# debugId=40CBB2F3F4855EA864756E2164756E21
|