@jeffusion/bungee-llms 5.12.0 → 5.13.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.js +14 -14
- package/dist/plugin-api.js +14 -14
- package/dist/protocol-converters/base.d.ts +7 -0
- package/dist/token-accounting/types.d.ts +3 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4407,7 +4407,7 @@ class AnthropicToOpenAIConverter {
|
|
|
4407
4407
|
}
|
|
4408
4408
|
}
|
|
4409
4409
|
async processStreamChunk(chunk, ctx) {
|
|
4410
|
-
if (this.isResponsesStreamChunk(chunk)) {
|
|
4410
|
+
if (this.isResponsesStreamChunk(chunk, ctx)) {
|
|
4411
4411
|
return this.processResponsesStreamChunk(chunk, ctx);
|
|
4412
4412
|
}
|
|
4413
4413
|
const events = [];
|
|
@@ -4671,8 +4671,8 @@ class AnthropicToOpenAIConverter {
|
|
|
4671
4671
|
}
|
|
4672
4672
|
return [];
|
|
4673
4673
|
}
|
|
4674
|
-
isResponsesStreamChunk(chunk) {
|
|
4675
|
-
const eventType =
|
|
4674
|
+
isResponsesStreamChunk(chunk, ctx) {
|
|
4675
|
+
const eventType = ctx.sseEvent?.event ?? "";
|
|
4676
4676
|
const type = typeof chunk?.type === "string" ? chunk.type : "";
|
|
4677
4677
|
if (eventType.startsWith("response."))
|
|
4678
4678
|
return true;
|
|
@@ -4682,7 +4682,7 @@ class AnthropicToOpenAIConverter {
|
|
|
4682
4682
|
}
|
|
4683
4683
|
async processResponsesStreamChunk(chunk, ctx) {
|
|
4684
4684
|
const events = [];
|
|
4685
|
-
const eventType =
|
|
4685
|
+
const eventType = ctx.sseEvent?.event || chunk.type;
|
|
4686
4686
|
const ensureMessageStarted = () => {
|
|
4687
4687
|
if (!ctx.streamState.has("message_started")) {
|
|
4688
4688
|
events.push({
|
|
@@ -7597,7 +7597,7 @@ function isDeferredFailure(body) {
|
|
|
7597
7597
|
const type = asString2(body.type)?.toLowerCase();
|
|
7598
7598
|
return isErrorResponse(body) || status === "incomplete" || type === "incomplete" || type?.endsWith(".incomplete") === true;
|
|
7599
7599
|
}
|
|
7600
|
-
function observeOpenAIOutput(state, chunk, includeResponseSnapshot = true) {
|
|
7600
|
+
function observeOpenAIOutput(state, chunk, includeResponseSnapshot = true, event) {
|
|
7601
7601
|
if (state.outputAuthority === "official")
|
|
7602
7602
|
return;
|
|
7603
7603
|
let nodes = MAX_INPUT_ESTIMATE_NODES;
|
|
@@ -7605,7 +7605,7 @@ function observeOpenAIOutput(state, chunk, includeResponseSnapshot = true) {
|
|
|
7605
7605
|
if (isDeferred(state))
|
|
7606
7606
|
state.estimateTruncated = true;
|
|
7607
7607
|
};
|
|
7608
|
-
const type = asString2(chunk.type);
|
|
7608
|
+
const type = event ?? asString2(chunk.type);
|
|
7609
7609
|
if (type === "response.output_text.delta") {
|
|
7610
7610
|
if (isDeferred(state))
|
|
7611
7611
|
observeBoundedOutput(state, chunk.delta);
|
|
@@ -7969,7 +7969,7 @@ function createOpenAIAdapter() {
|
|
|
7969
7969
|
outputAuthority: state.outputAuthority
|
|
7970
7970
|
}, isIncomplete || isFailed ? "failed" : "completed");
|
|
7971
7971
|
},
|
|
7972
|
-
consumeStreamChunk(state, chunk) {
|
|
7972
|
+
consumeStreamChunk(state, chunk, event) {
|
|
7973
7973
|
if (state.finalReceived || isDoneSentinel(chunk))
|
|
7974
7974
|
return null;
|
|
7975
7975
|
const response = readRecord(chunk, "response");
|
|
@@ -7989,10 +7989,10 @@ function createOpenAIAdapter() {
|
|
|
7989
7989
|
const reportedCache = readNumber(promptDetails, "cached_tokens");
|
|
7990
7990
|
if (reportedCache !== undefined)
|
|
7991
7991
|
state.cacheReadTokens = reportedCache;
|
|
7992
|
-
const responseType = asString2(chunk.type);
|
|
7992
|
+
const responseType = event ?? asString2(chunk.type);
|
|
7993
7993
|
const responseStatus = asString2(response?.status);
|
|
7994
7994
|
const responseCompleted = responseType === "response.completed" || responseStatus === "completed";
|
|
7995
|
-
observeOpenAIOutput(state, chunk, !responseCompleted);
|
|
7995
|
+
observeOpenAIOutput(state, chunk, !responseCompleted, event);
|
|
7996
7996
|
const choices = Array.isArray(chunk.choices) ? chunk.choices : [];
|
|
7997
7997
|
if (choices.some((choice) => isRecord6(choice) && asString2(choice.finish_reason) !== undefined && choice.finish_reason !== null)) {
|
|
7998
7998
|
state.protocolTerminalSeen = true;
|
|
@@ -8160,10 +8160,10 @@ function createAnthropicAdapter() {
|
|
|
8160
8160
|
outputAuthority: estimatedOutput === undefined ? "none" : "local"
|
|
8161
8161
|
});
|
|
8162
8162
|
},
|
|
8163
|
-
consumeStreamChunk(state, chunk) {
|
|
8163
|
+
consumeStreamChunk(state, chunk, event) {
|
|
8164
8164
|
if (state.finalReceived || isDoneSentinel(chunk))
|
|
8165
8165
|
return null;
|
|
8166
|
-
const type = asString2(chunk.type);
|
|
8166
|
+
const type = event ?? asString2(chunk.type);
|
|
8167
8167
|
if (isDeferred(state) && type === "error") {
|
|
8168
8168
|
state.protocolTerminalSeen = true;
|
|
8169
8169
|
state.deferredOutcome = "failed";
|
|
@@ -8373,7 +8373,7 @@ function createGeminiAdapter() {
|
|
|
8373
8373
|
outputAuthority: state.outputAuthority
|
|
8374
8374
|
});
|
|
8375
8375
|
},
|
|
8376
|
-
consumeStreamChunk(state, chunk) {
|
|
8376
|
+
consumeStreamChunk(state, chunk, event) {
|
|
8377
8377
|
if (state.finalReceived || isDoneSentinel(chunk))
|
|
8378
8378
|
return null;
|
|
8379
8379
|
observeGeminiOutput(state, chunk);
|
|
@@ -8504,8 +8504,8 @@ function createTokenAccountingSession(input, options = {}) {
|
|
|
8504
8504
|
terminalEvent = event;
|
|
8505
8505
|
return event;
|
|
8506
8506
|
},
|
|
8507
|
-
consumeStreamChunk({ chunk }) {
|
|
8508
|
-
const event = adapter.consumeStreamChunk(state, chunk);
|
|
8507
|
+
consumeStreamChunk({ chunk, event: eventName }) {
|
|
8508
|
+
const event = adapter.consumeStreamChunk(state, chunk, eventName);
|
|
8509
8509
|
if (event && (event.final || event.outcome !== "completed"))
|
|
8510
8510
|
terminalEvent = event;
|
|
8511
8511
|
return event;
|
package/dist/plugin-api.js
CHANGED
|
@@ -1925,7 +1925,7 @@ class AnthropicToOpenAIConverter {
|
|
|
1925
1925
|
}
|
|
1926
1926
|
}
|
|
1927
1927
|
async processStreamChunk(chunk, ctx) {
|
|
1928
|
-
if (this.isResponsesStreamChunk(chunk)) {
|
|
1928
|
+
if (this.isResponsesStreamChunk(chunk, ctx)) {
|
|
1929
1929
|
return this.processResponsesStreamChunk(chunk, ctx);
|
|
1930
1930
|
}
|
|
1931
1931
|
const events = [];
|
|
@@ -2189,8 +2189,8 @@ class AnthropicToOpenAIConverter {
|
|
|
2189
2189
|
}
|
|
2190
2190
|
return [];
|
|
2191
2191
|
}
|
|
2192
|
-
isResponsesStreamChunk(chunk) {
|
|
2193
|
-
const eventType =
|
|
2192
|
+
isResponsesStreamChunk(chunk, ctx) {
|
|
2193
|
+
const eventType = ctx.sseEvent?.event ?? "";
|
|
2194
2194
|
const type = typeof chunk?.type === "string" ? chunk.type : "";
|
|
2195
2195
|
if (eventType.startsWith("response."))
|
|
2196
2196
|
return true;
|
|
@@ -2200,7 +2200,7 @@ class AnthropicToOpenAIConverter {
|
|
|
2200
2200
|
}
|
|
2201
2201
|
async processResponsesStreamChunk(chunk, ctx) {
|
|
2202
2202
|
const events = [];
|
|
2203
|
-
const eventType =
|
|
2203
|
+
const eventType = ctx.sseEvent?.event || chunk.type;
|
|
2204
2204
|
const ensureMessageStarted = () => {
|
|
2205
2205
|
if (!ctx.streamState.has("message_started")) {
|
|
2206
2206
|
events.push({
|
|
@@ -7603,7 +7603,7 @@ function isDeferredFailure(body) {
|
|
|
7603
7603
|
const type = asString2(body.type)?.toLowerCase();
|
|
7604
7604
|
return isErrorResponse(body) || status === "incomplete" || type === "incomplete" || type?.endsWith(".incomplete") === true;
|
|
7605
7605
|
}
|
|
7606
|
-
function observeOpenAIOutput(state, chunk, includeResponseSnapshot = true) {
|
|
7606
|
+
function observeOpenAIOutput(state, chunk, includeResponseSnapshot = true, event) {
|
|
7607
7607
|
if (state.outputAuthority === "official")
|
|
7608
7608
|
return;
|
|
7609
7609
|
let nodes = MAX_INPUT_ESTIMATE_NODES;
|
|
@@ -7611,7 +7611,7 @@ function observeOpenAIOutput(state, chunk, includeResponseSnapshot = true) {
|
|
|
7611
7611
|
if (isDeferred(state))
|
|
7612
7612
|
state.estimateTruncated = true;
|
|
7613
7613
|
};
|
|
7614
|
-
const type = asString2(chunk.type);
|
|
7614
|
+
const type = event ?? asString2(chunk.type);
|
|
7615
7615
|
if (type === "response.output_text.delta") {
|
|
7616
7616
|
if (isDeferred(state))
|
|
7617
7617
|
observeBoundedOutput(state, chunk.delta);
|
|
@@ -7975,7 +7975,7 @@ function createOpenAIAdapter() {
|
|
|
7975
7975
|
outputAuthority: state.outputAuthority
|
|
7976
7976
|
}, isIncomplete || isFailed ? "failed" : "completed");
|
|
7977
7977
|
},
|
|
7978
|
-
consumeStreamChunk(state, chunk) {
|
|
7978
|
+
consumeStreamChunk(state, chunk, event) {
|
|
7979
7979
|
if (state.finalReceived || isDoneSentinel(chunk))
|
|
7980
7980
|
return null;
|
|
7981
7981
|
const response = readRecord(chunk, "response");
|
|
@@ -7995,10 +7995,10 @@ function createOpenAIAdapter() {
|
|
|
7995
7995
|
const reportedCache = readNumber(promptDetails, "cached_tokens");
|
|
7996
7996
|
if (reportedCache !== undefined)
|
|
7997
7997
|
state.cacheReadTokens = reportedCache;
|
|
7998
|
-
const responseType = asString2(chunk.type);
|
|
7998
|
+
const responseType = event ?? asString2(chunk.type);
|
|
7999
7999
|
const responseStatus = asString2(response?.status);
|
|
8000
8000
|
const responseCompleted = responseType === "response.completed" || responseStatus === "completed";
|
|
8001
|
-
observeOpenAIOutput(state, chunk, !responseCompleted);
|
|
8001
|
+
observeOpenAIOutput(state, chunk, !responseCompleted, event);
|
|
8002
8002
|
const choices = Array.isArray(chunk.choices) ? chunk.choices : [];
|
|
8003
8003
|
if (choices.some((choice) => isRecord6(choice) && asString2(choice.finish_reason) !== undefined && choice.finish_reason !== null)) {
|
|
8004
8004
|
state.protocolTerminalSeen = true;
|
|
@@ -8166,10 +8166,10 @@ function createAnthropicAdapter() {
|
|
|
8166
8166
|
outputAuthority: estimatedOutput === undefined ? "none" : "local"
|
|
8167
8167
|
});
|
|
8168
8168
|
},
|
|
8169
|
-
consumeStreamChunk(state, chunk) {
|
|
8169
|
+
consumeStreamChunk(state, chunk, event) {
|
|
8170
8170
|
if (state.finalReceived || isDoneSentinel(chunk))
|
|
8171
8171
|
return null;
|
|
8172
|
-
const type = asString2(chunk.type);
|
|
8172
|
+
const type = event ?? asString2(chunk.type);
|
|
8173
8173
|
if (isDeferred(state) && type === "error") {
|
|
8174
8174
|
state.protocolTerminalSeen = true;
|
|
8175
8175
|
state.deferredOutcome = "failed";
|
|
@@ -8379,7 +8379,7 @@ function createGeminiAdapter() {
|
|
|
8379
8379
|
outputAuthority: state.outputAuthority
|
|
8380
8380
|
});
|
|
8381
8381
|
},
|
|
8382
|
-
consumeStreamChunk(state, chunk) {
|
|
8382
|
+
consumeStreamChunk(state, chunk, event) {
|
|
8383
8383
|
if (state.finalReceived || isDoneSentinel(chunk))
|
|
8384
8384
|
return null;
|
|
8385
8385
|
observeGeminiOutput(state, chunk);
|
|
@@ -8510,8 +8510,8 @@ function createTokenAccountingSession(input, options = {}) {
|
|
|
8510
8510
|
terminalEvent = event;
|
|
8511
8511
|
return event;
|
|
8512
8512
|
},
|
|
8513
|
-
consumeStreamChunk({ chunk }) {
|
|
8514
|
-
const event = adapter.consumeStreamChunk(state, chunk);
|
|
8513
|
+
consumeStreamChunk({ chunk, event: eventName }) {
|
|
8514
|
+
const event = adapter.consumeStreamChunk(state, chunk, eventName);
|
|
8515
8515
|
if (event && (event.final || event.outcome !== "completed"))
|
|
8516
8516
|
terminalEvent = event;
|
|
8517
8517
|
return event;
|
|
@@ -9,6 +9,13 @@ export interface ResponseContext {
|
|
|
9
9
|
[key: string]: any;
|
|
10
10
|
}
|
|
11
11
|
export interface StreamChunkContext {
|
|
12
|
+
/** SSE metadata belongs to the transport envelope, not the JSON object. */
|
|
13
|
+
sseEvent?: {
|
|
14
|
+
event?: string;
|
|
15
|
+
id?: string;
|
|
16
|
+
retry?: string;
|
|
17
|
+
comments?: string[];
|
|
18
|
+
};
|
|
12
19
|
streamState: Map<string, any>;
|
|
13
20
|
chunkIndex?: number;
|
|
14
21
|
isFirstChunk?: boolean;
|
|
@@ -39,6 +39,8 @@ export interface TokenAccountingResponseInput {
|
|
|
39
39
|
body: Record<string, unknown>;
|
|
40
40
|
}
|
|
41
41
|
export interface TokenAccountingStreamChunkInput {
|
|
42
|
+
/** Independent SSE event name; never injected into JSON. */
|
|
43
|
+
event?: string;
|
|
42
44
|
chunk: Record<string, unknown>;
|
|
43
45
|
}
|
|
44
46
|
export interface TokenAccountingSession {
|
|
@@ -93,7 +95,7 @@ export interface ProviderTokenAccountingAdapter {
|
|
|
93
95
|
readonly capabilities: ProviderTokenAccountingCapabilities;
|
|
94
96
|
consumeRequest(state: TokenAccountingSessionState, body: Record<string, unknown>): void;
|
|
95
97
|
consumeResponse(state: TokenAccountingSessionState, body: Record<string, unknown>): CanonicalTokenAccountingEventV2;
|
|
96
|
-
consumeStreamChunk(state: TokenAccountingSessionState, chunk: Record<string, unknown
|
|
98
|
+
consumeStreamChunk(state: TokenAccountingSessionState, chunk: Record<string, unknown>, event?: string): CanonicalTokenAccountingEventV2 | null;
|
|
97
99
|
finalizeCompletedStream(state: TokenAccountingSessionState): CanonicalTokenAccountingEventV2;
|
|
98
100
|
finalizeAbortedStream(state: TokenAccountingSessionState): CanonicalTokenAccountingEventV2;
|
|
99
101
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jeffusion/bungee-llms",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.13.0",
|
|
4
4
|
"description": "Extensible LLM adapters and protocol conversion package for Bungee",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"prepublishOnly": "bun run build"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@jeffusion/bungee-types": "^5.
|
|
14
|
+
"@jeffusion/bungee-types": "^5.13.0"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"bun-types": "^1.3.2",
|