@lobehub/lobehub 2.0.0-next.88 → 2.0.0-next.89

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.
Files changed (24) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/next.config.ts +0 -1
  4. package/package.json +2 -2
  5. package/packages/context-engine/src/processors/ToolCall.ts +1 -0
  6. package/packages/context-engine/src/processors/__tests__/ToolCall.test.ts +59 -0
  7. package/packages/context-engine/src/tools/ToolNameResolver.ts +1 -0
  8. package/packages/context-engine/src/tools/__tests__/ToolNameResolver.test.ts +57 -0
  9. package/packages/context-engine/src/types.ts +1 -0
  10. package/packages/fetch-sse/src/fetchSSE.ts +12 -2
  11. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +479 -0
  12. package/packages/model-runtime/src/core/contextBuilders/google.ts +44 -1
  13. package/packages/model-runtime/src/core/streams/google/google-ai.test.ts +1115 -814
  14. package/packages/model-runtime/src/core/streams/google/index.ts +19 -5
  15. package/packages/model-runtime/src/core/streams/protocol.ts +1 -0
  16. package/packages/model-runtime/src/providers/google/index.test.ts +1 -1
  17. package/packages/model-runtime/src/providers/google/index.ts +11 -9
  18. package/packages/model-runtime/src/types/toolsCalling.ts +3 -1
  19. package/packages/types/src/message/common/tools.ts +3 -0
  20. package/src/features/Conversation/Messages/Group/Error/index.tsx +3 -2
  21. package/src/features/Conversation/Messages/Group/GroupItem.tsx +2 -2
  22. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +6 -5
  23. package/src/store/chat/slices/message/actions/optimisticUpdate.ts +6 -11
  24. package/src/store/chat/slices/plugin/actions/internals.ts +2 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.89](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.88...v2.0.0-next.89)
6
+
7
+ <sup>Released on **2025-11-19**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: Support gemini 3.0 tools calling.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: Support gemini 3.0 tools calling, closes [#10301](https://github.com/lobehub/lobe-chat/issues/10301) ([7114fc1](https://github.com/lobehub/lobe-chat/commit/7114fc1))
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.88](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.87...v2.0.0-next.88)
6
31
 
7
32
  <sup>Released on **2025-11-19**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "features": [
5
+ "Support gemini 3.0 tools calling."
6
+ ]
7
+ },
8
+ "date": "2025-11-19",
9
+ "version": "2.0.0-next.89"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
package/next.config.ts CHANGED
@@ -42,7 +42,6 @@ const nextConfig: NextConfig = {
42
42
  // so we need to disable it
43
43
  // refs: https://github.com/lobehub/lobe-chat/pull/7430
44
44
  serverMinification: false,
45
- turbopackFileSystemCacheForDev: true,
46
45
  webVitalsAttribution: ['CLS', 'LCP'],
47
46
  webpackBuildWorker: true,
48
47
  webpackMemoryOptimizations: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.88",
3
+ "version": "2.0.0-next.89",
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",
@@ -141,7 +141,7 @@
141
141
  "@emotion/react": "^11.14.0",
142
142
  "@fal-ai/client": "^1.7.2",
143
143
  "@formkit/auto-animate": "^0.9.0",
144
- "@google/genai": "^1.29.1",
144
+ "@google/genai": "^1.30.0",
145
145
  "@huggingface/inference": "^4.13.3",
146
146
  "@icons-pack/react-simple-icons": "^13.8.0",
147
147
  "@khmyznikov/pwa-install": "0.3.9",
@@ -130,6 +130,7 @@ export class ToolCallProcessor extends BaseProcessor {
130
130
  : `${tool.identifier}.${tool.apiName}`,
131
131
  },
132
132
  id: tool.id,
133
+ thoughtSignature: tool.thoughtSignature,
133
134
  type: 'function',
134
135
  }),
135
136
  );
@@ -72,6 +72,65 @@ describe('ToolCallProcessor', () => {
72
72
  ]);
73
73
  });
74
74
 
75
+ it('should pass through thoughtSignature when present', async () => {
76
+ const processor = new ToolCallProcessor(defaultConfig);
77
+ const context = createContext([
78
+ {
79
+ content: '',
80
+ id: 'msg1',
81
+ role: 'assistant',
82
+ tools: [
83
+ {
84
+ apiName: 'search',
85
+ arguments: '{"query":"test"}',
86
+ id: 'call_1',
87
+ identifier: 'web',
88
+ thoughtSignature: 'Let me search for this information',
89
+ type: 'builtin',
90
+ },
91
+ ],
92
+ },
93
+ ]);
94
+
95
+ const result = await processor.process(context);
96
+
97
+ expect(result.messages[0].tool_calls).toEqual([
98
+ {
99
+ function: {
100
+ arguments: '{"query":"test"}',
101
+ name: 'web.search',
102
+ },
103
+ id: 'call_1',
104
+ thoughtSignature: 'Let me search for this information',
105
+ type: 'function',
106
+ },
107
+ ]);
108
+ });
109
+
110
+ it('should handle missing thoughtSignature', async () => {
111
+ const processor = new ToolCallProcessor(defaultConfig);
112
+ const context = createContext([
113
+ {
114
+ content: '',
115
+ id: 'msg1',
116
+ role: 'assistant',
117
+ tools: [
118
+ {
119
+ apiName: 'search',
120
+ arguments: '{"query":"test"}',
121
+ id: 'call_1',
122
+ identifier: 'web',
123
+ type: 'builtin',
124
+ },
125
+ ],
126
+ },
127
+ ]);
128
+
129
+ const result = await processor.process(context);
130
+
131
+ expect(result.messages[0].tool_calls[0].thoughtSignature).toBeUndefined();
132
+ });
133
+
75
134
  it('should use custom genToolCallingName function', async () => {
76
135
  const genToolCallingName = vi.fn(
77
136
  (identifier, apiName, type) => `custom_${identifier}_${apiName}_${type}`,
@@ -82,6 +82,7 @@ export class ToolNameResolver {
82
82
  arguments: toolCall.function.arguments,
83
83
  id: toolCall.id,
84
84
  identifier,
85
+ thoughtSignature: toolCall.thoughtSignature,
85
86
  type: (type ?? 'default') as any,
86
87
  };
87
88
 
@@ -455,6 +455,63 @@ describe('ToolNameResolver', () => {
455
455
  });
456
456
  });
457
457
 
458
+ describe('resolve - thoughtSignature', () => {
459
+ it('should pass through thoughtSignature when present', () => {
460
+ const toolCalls = [
461
+ {
462
+ function: {
463
+ arguments: '{"query": "test"}',
464
+ name: 'test-plugin____myAction____builtin',
465
+ },
466
+ id: 'call_1',
467
+ thoughtSignature: 'thinking about this...',
468
+ type: 'function',
469
+ },
470
+ ];
471
+
472
+ const manifests = {
473
+ 'test-plugin': {
474
+ api: [{ description: 'My action', name: 'myAction', parameters: {} }],
475
+ identifier: 'test-plugin',
476
+ meta: {},
477
+ type: 'builtin' as const,
478
+ },
479
+ };
480
+
481
+ const result = resolver.resolve(toolCalls, manifests);
482
+
483
+ expect(result).toHaveLength(1);
484
+ expect(result[0].thoughtSignature).toBe('thinking about this...');
485
+ });
486
+
487
+ it('should handle missing thoughtSignature', () => {
488
+ const toolCalls = [
489
+ {
490
+ function: {
491
+ arguments: '{"query": "test"}',
492
+ name: 'test-plugin____myAction____builtin',
493
+ },
494
+ id: 'call_1',
495
+ type: 'function',
496
+ },
497
+ ];
498
+
499
+ const manifests = {
500
+ 'test-plugin': {
501
+ api: [{ description: 'My action', name: 'myAction', parameters: {} }],
502
+ identifier: 'test-plugin',
503
+ meta: {},
504
+ type: 'builtin' as const,
505
+ },
506
+ };
507
+
508
+ const result = resolver.resolve(toolCalls, manifests);
509
+
510
+ expect(result).toHaveLength(1);
511
+ expect(result[0].thoughtSignature).toBeUndefined();
512
+ });
513
+ });
514
+
458
515
  describe('resolve - edge cases', () => {
459
516
  it('should filter out invalid tool calls with missing apiName', () => {
460
517
  const toolCalls = [
@@ -30,6 +30,7 @@ export interface MessageToolCall {
30
30
  name: string;
31
31
  };
32
32
  id: string;
33
+ thoughtSignature?: string;
33
34
  type: 'function';
34
35
  }
35
36
  export interface Message {
@@ -17,7 +17,7 @@ import { nanoid } from '@lobechat/utils/uuid';
17
17
 
18
18
  import { getMessageError } from './parseError';
19
19
 
20
- type SSEFinishType = 'done' | 'error' | 'abort';
20
+ type SSEFinishType = 'done' | 'error' | 'abort' | string;
21
21
 
22
22
  export type OnFinishHandler = (
23
23
  text: string,
@@ -48,6 +48,10 @@ export interface MessageTextChunk {
48
48
  text: string;
49
49
  type: 'text';
50
50
  }
51
+ export interface MessageStopChunk {
52
+ reason: string;
53
+ type: 'stop';
54
+ }
51
55
 
52
56
  export interface MessageBase64ImageChunk {
53
57
  id: string;
@@ -86,7 +90,8 @@ export interface FetchSSEOptions {
86
90
  | MessageGroundingChunk
87
91
  | MessageUsageChunk
88
92
  | MessageBase64ImageChunk
89
- | MessageSpeedChunk,
93
+ | MessageSpeedChunk
94
+ | MessageStopChunk,
90
95
  ) => void;
91
96
  responseAnimation?: ResponseAnimation;
92
97
  }
@@ -387,6 +392,11 @@ export const fetchSSE = async (url: string, options: RequestInit & FetchSSEOptio
387
392
  break;
388
393
  }
389
394
 
395
+ case 'stop': {
396
+ options.onMessageHandle?.({ reason: data, type: 'stop' });
397
+ break;
398
+ }
399
+
390
400
  case 'reasoning': {
391
401
  if (textSmoothing) {
392
402
  thinkingController.pushToQueue(data);