@lobehub/chat 1.127.3 → 1.127.4
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/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/package.json +2 -2
- package/packages/model-runtime/package.json +2 -1
- package/packages/model-runtime/src/const/modelProvider.ts +1 -0
- package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +2 -0
- package/packages/model-runtime/src/core/RouterRuntime/index.ts +1 -0
- package/packages/model-runtime/src/core/streams/openai/openai.test.ts +36 -2
- package/packages/model-runtime/src/core/streams/openai/openai.ts +3 -2
- package/packages/model-runtime/src/index.ts +1 -0
- package/packages/types/src/user/settings/keyVaults.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 1.127.4](https://github.com/lobehub/lobe-chat/compare/v1.127.3...v1.127.4)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-09-11**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Improve OpenAIStream processing to emit usage data for chunks lacking choices.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Improve OpenAIStream processing to emit usage data for chunks lacking choices, closes [#9220](https://github.com/lobehub/lobe-chat/issues/9220) ([8ba662c](https://github.com/lobehub/lobe-chat/commit/8ba662c))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
### [Version 1.127.3](https://github.com/lobehub/lobe-chat/compare/v1.127.2...v1.127.3)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2025-09-11**</sup>
|
package/changelog/v1.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "1.127.
|
|
3
|
+
"version": "1.127.4",
|
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -363,7 +363,7 @@
|
|
|
363
363
|
"typescript": "^5.9.2",
|
|
364
364
|
"unified": "^11.0.5",
|
|
365
365
|
"unist-util-visit": "^5.0.0",
|
|
366
|
-
"vite": "^
|
|
366
|
+
"vite": "^7.1.5",
|
|
367
367
|
"vitest": "^3.2.4"
|
|
368
368
|
},
|
|
369
369
|
"packageManager": "pnpm@10.15.1",
|
|
@@ -295,6 +295,40 @@ describe('OpenAIStream', () => {
|
|
|
295
295
|
]);
|
|
296
296
|
});
|
|
297
297
|
|
|
298
|
+
it('should emit usage when choices are missing but usage exists', async () => {
|
|
299
|
+
const mockOpenAIStream = new ReadableStream({
|
|
300
|
+
start(controller) {
|
|
301
|
+
controller.enqueue({
|
|
302
|
+
id: '99',
|
|
303
|
+
usage: {
|
|
304
|
+
prompt_tokens: 1,
|
|
305
|
+
completion_tokens: 2,
|
|
306
|
+
total_tokens: 3,
|
|
307
|
+
prompt_cache_miss_tokens: 1,
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
controller.close();
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
const protocolStream = OpenAIStream(mockOpenAIStream);
|
|
316
|
+
|
|
317
|
+
const decoder = new TextDecoder();
|
|
318
|
+
const chunks: string[] = [];
|
|
319
|
+
|
|
320
|
+
// @ts-ignore
|
|
321
|
+
for await (const chunk of protocolStream) {
|
|
322
|
+
chunks.push(decoder.decode(chunk, { stream: true }));
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
expect(chunks).toEqual([
|
|
326
|
+
'id: 99\n',
|
|
327
|
+
'event: usage\n',
|
|
328
|
+
`data: {"inputCacheMissTokens":1,"inputTextTokens":1,"outputTextTokens":2,"totalInputTokens":1,"totalOutputTokens":2,"totalTokens":3}\n\n`,
|
|
329
|
+
]);
|
|
330
|
+
});
|
|
331
|
+
|
|
298
332
|
it('should handle error when there is not correct error', async () => {
|
|
299
333
|
const mockOpenAIStream = new ReadableStream({
|
|
300
334
|
start(controller) {
|
|
@@ -331,8 +365,8 @@ describe('OpenAIStream', () => {
|
|
|
331
365
|
'event: text',
|
|
332
366
|
`data: "Hello"\n`,
|
|
333
367
|
'id: 1',
|
|
334
|
-
'event:
|
|
335
|
-
`data: {"
|
|
368
|
+
'event: data',
|
|
369
|
+
`data: {"id":"1"}\n`,
|
|
336
370
|
].map((i) => `${i}\n`),
|
|
337
371
|
);
|
|
338
372
|
});
|
|
@@ -64,8 +64,7 @@ const transformOpenAIStream = (
|
|
|
64
64
|
|
|
65
65
|
try {
|
|
66
66
|
// maybe need another structure to add support for multiple choices
|
|
67
|
-
|
|
68
|
-
if (!item) {
|
|
67
|
+
if (!Array.isArray(chunk.choices) || chunk.choices.length === 0) {
|
|
69
68
|
if (chunk.usage) {
|
|
70
69
|
const usage = chunk.usage;
|
|
71
70
|
return { data: convertUsage(usage, provider), id: chunk.id, type: 'usage' };
|
|
@@ -74,6 +73,8 @@ const transformOpenAIStream = (
|
|
|
74
73
|
return { data: chunk, id: chunk.id, type: 'data' };
|
|
75
74
|
}
|
|
76
75
|
|
|
76
|
+
const item = chunk.choices[0];
|
|
77
|
+
|
|
77
78
|
if (item && typeof item.delta?.tool_calls === 'object' && item.delta.tool_calls?.length > 0) {
|
|
78
79
|
// tools calling
|
|
79
80
|
const tool_calls = item.delta.tool_calls.filter(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './core/BaseAI';
|
|
2
2
|
export { ModelRuntime } from './core/ModelRuntime';
|
|
3
3
|
export { createOpenAICompatibleRuntime } from './core/openaiCompatibleFactory';
|
|
4
|
+
export * from './core/RouterRuntime';
|
|
4
5
|
export * from './helpers';
|
|
5
6
|
export { LobeAkashChatAI } from './providers/akashchat';
|
|
6
7
|
export { LobeAnthropicAI } from './providers/anthropic';
|
|
@@ -47,6 +47,7 @@ export interface UserKeyVaults extends SearchEngineKeyVaults {
|
|
|
47
47
|
azureai?: AzureOpenAIKeyVault;
|
|
48
48
|
baichuan?: OpenAICompatibleKeyVault;
|
|
49
49
|
bedrock?: AWSBedrockKeyVault;
|
|
50
|
+
bfl?: any;
|
|
50
51
|
cloudflare?: CloudflareKeyVault;
|
|
51
52
|
cohere?: OpenAICompatibleKeyVault;
|
|
52
53
|
cometapi?: OpenAICompatibleKeyVault;
|