@lobehub/lobehub 2.0.0-next.136 → 2.0.0-next.137

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 CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.137](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.136...v2.0.0-next.137)
6
+
7
+ <sup>Released on **2025-11-30**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Update apiMode handling in ChatService to prioritize user preferences.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Update apiMode handling in ChatService to prioritize user preferences, closes [#10487](https://github.com/lobehub/lobe-chat/issues/10487) ([5483d91](https://github.com/lobehub/lobe-chat/commit/5483d91))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ## [Version 2.0.0-next.136](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.135...v2.0.0-next.136)
6
31
 
7
32
  <sup>Released on **2025-11-30**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Update apiMode handling in ChatService to prioritize user preferences."
6
+ ]
7
+ },
8
+ "date": "2025-11-30",
9
+ "version": "2.0.0-next.137"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "fixes": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.136",
3
+ "version": "2.0.0-next.137",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent 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",
@@ -235,18 +235,45 @@ export const createOpenAICompatibleRuntime = <T extends Record<string, any> = an
235
235
 
236
236
  const log = debug(`${this.logPrefix}:shouldUseResponsesAPI`);
237
237
 
238
- // Priority 1: User explicitly set apiMode via switch
239
- if (userApiMode === 'responses') {
240
- log('using Responses API: explicit userApiMode=%s', userApiMode);
238
+ // Priority 0: Check built-in responsesAPIModels FIRST (highest priority)
239
+ // These models MUST use Responses API regardless of user settings
240
+ if (model && responsesAPIModels.has(model)) {
241
+ log('using Responses API: model %s in built-in responsesAPIModels (forced)', model);
241
242
  return true;
242
243
  }
243
244
 
244
- // Priority 2: userApiMode is explicitly set to something else
245
- if (userApiMode !== undefined) {
245
+ // Priority 1: userApiMode is explicitly set to 'chatCompletion' (user disabled the switch)
246
+ if (userApiMode === 'chatCompletion') {
246
247
  log('using Chat Completions API: userApiMode=%s', userApiMode);
247
248
  return false;
248
249
  }
249
250
 
251
+ // Priority 2: When user enables the switch (userApiMode === 'responses')
252
+ // Check if useResponseModels is configured - if so, only matching models use Responses API
253
+ // If useResponseModels is not configured, all models use Responses API
254
+ if (userApiMode === 'responses') {
255
+ if (model && flagUseResponseModels?.length) {
256
+ const matches = flagUseResponseModels.some((m: string | RegExp) =>
257
+ typeof m === 'string' ? model.includes(m) : (m as RegExp).test(model),
258
+ );
259
+ if (matches) {
260
+ log(
261
+ 'using Responses API: userApiMode=responses and model %s matches useResponseModels',
262
+ model,
263
+ );
264
+ return true;
265
+ }
266
+ log(
267
+ 'using Chat Completions API: userApiMode=responses but model %s does not match useResponseModels',
268
+ model,
269
+ );
270
+ return false;
271
+ }
272
+ // No useResponseModels configured, use Responses API for all models
273
+ log('using Responses API: userApiMode=responses (no useResponseModels filter)');
274
+ return true;
275
+ }
276
+
250
277
  // Priority 3: Explicit responseApi flag
251
278
  if (responseApi) {
252
279
  log('using Responses API: explicit responseApi flag for %s', context);
@@ -259,7 +286,7 @@ export const createOpenAICompatibleRuntime = <T extends Record<string, any> = an
259
286
  return true;
260
287
  }
261
288
 
262
- // Priority 5: Check if model matches useResponseModels patterns
289
+ // Priority 5: Check if model matches useResponseModels patterns (without user switch)
263
290
  if (model && flagUseResponseModels?.length) {
264
291
  const matches = flagUseResponseModels.some((m: string | RegExp) =>
265
292
  typeof m === 'string' ? model.includes(m) : (m as RegExp).test(model),
@@ -270,12 +297,6 @@ export const createOpenAICompatibleRuntime = <T extends Record<string, any> = an
270
297
  }
271
298
  }
272
299
 
273
- // Priority 6: Check built-in responsesAPIModels
274
- if (model && responsesAPIModels.has(model)) {
275
- log('using Responses API: model %s in built-in responsesAPIModels', model);
276
- return true;
277
- }
278
-
279
300
  log('using Chat Completions API for %s', context);
280
301
  return false;
281
302
  }
@@ -1062,7 +1062,7 @@ describe('ChatService', () => {
1062
1062
  );
1063
1063
  });
1064
1064
 
1065
- it('should make a POST request without response in non-openai provider payload', async () => {
1065
+ it('should make a POST request with chatCompletion apiMode in non-openai provider payload', async () => {
1066
1066
  const params: Partial<ChatStreamPayload> = {
1067
1067
  model: 'deepseek-reasoner',
1068
1068
  provider: 'deepseek',
@@ -1076,6 +1076,7 @@ describe('ChatService', () => {
1076
1076
  stream: true,
1077
1077
  ...DEFAULT_AGENT_CONFIG.params,
1078
1078
  messages: [],
1079
+ apiMode: 'chatCompletion',
1079
1080
  provider: undefined,
1080
1081
  };
1081
1082
 
@@ -267,11 +267,14 @@ class ChatService {
267
267
  model = findDeploymentName(model, provider);
268
268
  }
269
269
 
270
- const apiMode = aiProviderSelectors.isProviderEnableResponseApi(provider)(
271
- getAiInfraStoreState(),
272
- )
270
+ // When user explicitly disables Responses API, set apiMode to 'chatCompletion'
271
+ // This ensures the user's preference takes priority over provider's useResponseModels config
272
+ // When user enables Responses API, set to 'responses' to force use Responses API
273
+ const apiMode: 'responses' | 'chatCompletion' = aiProviderSelectors.isProviderEnableResponseApi(
274
+ provider,
275
+ )(getAiInfraStoreState())
273
276
  ? 'responses'
274
- : undefined;
277
+ : 'chatCompletion';
275
278
 
276
279
  // Get the chat config to check streaming preference
277
280
  const chatConfig = agentChatConfigSelectors.currentChatConfig(getAgentStoreState());