@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.
- package/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/next.config.ts +0 -1
- package/package.json +2 -2
- package/packages/context-engine/src/processors/ToolCall.ts +1 -0
- package/packages/context-engine/src/processors/__tests__/ToolCall.test.ts +59 -0
- package/packages/context-engine/src/tools/ToolNameResolver.ts +1 -0
- package/packages/context-engine/src/tools/__tests__/ToolNameResolver.test.ts +57 -0
- package/packages/context-engine/src/types.ts +1 -0
- package/packages/fetch-sse/src/fetchSSE.ts +12 -2
- package/packages/model-runtime/src/core/contextBuilders/google.test.ts +479 -0
- package/packages/model-runtime/src/core/contextBuilders/google.ts +44 -1
- package/packages/model-runtime/src/core/streams/google/google-ai.test.ts +1115 -814
- package/packages/model-runtime/src/core/streams/google/index.ts +19 -5
- package/packages/model-runtime/src/core/streams/protocol.ts +1 -0
- package/packages/model-runtime/src/providers/google/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/google/index.ts +11 -9
- package/packages/model-runtime/src/types/toolsCalling.ts +3 -1
- package/packages/types/src/message/common/tools.ts +3 -0
- package/src/features/Conversation/Messages/Group/Error/index.tsx +3 -2
- package/src/features/Conversation/Messages/Group/GroupItem.tsx +2 -2
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +6 -5
- package/src/store/chat/slices/message/actions/optimisticUpdate.ts +6 -11
- package/src/store/chat/slices/plugin/actions/internals.ts +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GenerateContentResponse } from '@google/genai';
|
|
1
|
+
import { GenerateContentResponse, Part } from '@google/genai';
|
|
2
2
|
import { GroundingSearch } from '@lobechat/types';
|
|
3
3
|
|
|
4
4
|
import { ChatStreamCallbacks } from '../../../types';
|
|
@@ -74,19 +74,27 @@ const transformGoogleGenerativeAIStream = (
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
// Parse function calls from candidate.content.parts
|
|
78
|
+
const functionCalls =
|
|
79
|
+
candidate?.content?.parts
|
|
80
|
+
?.filter((part: any) => part.functionCall)
|
|
81
|
+
.map((part: Part) => ({
|
|
82
|
+
...part.functionCall,
|
|
83
|
+
thoughtSignature: part.thoughtSignature,
|
|
84
|
+
})) || [];
|
|
78
85
|
|
|
79
|
-
if (functionCalls) {
|
|
86
|
+
if (functionCalls.length > 0) {
|
|
80
87
|
return [
|
|
81
88
|
{
|
|
82
89
|
data: functionCalls.map(
|
|
83
|
-
(value, index): StreamToolCallChunkData => ({
|
|
90
|
+
(value, index: number): StreamToolCallChunkData => ({
|
|
84
91
|
function: {
|
|
85
92
|
arguments: JSON.stringify(value.args),
|
|
86
93
|
name: value.name,
|
|
87
94
|
},
|
|
88
95
|
id: generateToolCallId(index, value.name),
|
|
89
96
|
index: index,
|
|
97
|
+
thoughtSignature: value.thoughtSignature,
|
|
90
98
|
type: 'function',
|
|
91
99
|
}),
|
|
92
100
|
),
|
|
@@ -97,7 +105,13 @@ const transformGoogleGenerativeAIStream = (
|
|
|
97
105
|
];
|
|
98
106
|
}
|
|
99
107
|
|
|
100
|
-
|
|
108
|
+
// Parse text from candidate.content.parts
|
|
109
|
+
// Filter out thought content (thought: true) and thoughtSignature
|
|
110
|
+
const text =
|
|
111
|
+
candidate?.content?.parts
|
|
112
|
+
?.filter((part: any) => part.text && !part.thought && !part.thoughtSignature)
|
|
113
|
+
.map((part: any) => part.text)
|
|
114
|
+
.join('') || '';
|
|
101
115
|
|
|
102
116
|
if (candidate) {
|
|
103
117
|
// 首先检查是否为 reasoning 内容 (thought: true)
|
|
@@ -267,19 +267,21 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
267
267
|
|
|
268
268
|
const inputStartAt = Date.now();
|
|
269
269
|
|
|
270
|
-
const
|
|
271
|
-
config,
|
|
272
|
-
contents,
|
|
273
|
-
model,
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
const googleStream = this.createEnhancedStream(geminiStreamResponse, controller.signal);
|
|
277
|
-
const [prod, useForDebug] = googleStream.tee();
|
|
278
|
-
|
|
270
|
+
const finalPayload = { config, contents, model };
|
|
279
271
|
const key = this.isVertexAi
|
|
280
272
|
? 'DEBUG_VERTEX_AI_CHAT_COMPLETION'
|
|
281
273
|
: 'DEBUG_GOOGLE_CHAT_COMPLETION';
|
|
282
274
|
|
|
275
|
+
if (process.env[key] === '1') {
|
|
276
|
+
console.log('[requestPayload]');
|
|
277
|
+
console.log(JSON.stringify(finalPayload), '\n');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const geminiStreamResponse = await this.client.models.generateContentStream(finalPayload);
|
|
281
|
+
|
|
282
|
+
const googleStream = this.createEnhancedStream(geminiStreamResponse, controller.signal);
|
|
283
|
+
const [prod, useForDebug] = googleStream.tee();
|
|
284
|
+
|
|
283
285
|
if (process.env[key] === '1') {
|
|
284
286
|
debugStream(useForDebug).catch();
|
|
285
287
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import type { PartialDeep } from 'type-fest';
|
|
2
|
+
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The function that the model called.
|
|
@@ -30,6 +30,7 @@ export interface MessageToolCall {
|
|
|
30
30
|
*/
|
|
31
31
|
id: string;
|
|
32
32
|
|
|
33
|
+
thoughtSignature?: string;
|
|
33
34
|
/**
|
|
34
35
|
* The type of the tool. Currently, only `function` is supported.
|
|
35
36
|
*/
|
|
@@ -42,6 +43,7 @@ export const MessageToolCallSchema = z.object({
|
|
|
42
43
|
name: z.string(),
|
|
43
44
|
}),
|
|
44
45
|
id: z.string(),
|
|
46
|
+
thoughtSignature: z.string().optional(),
|
|
45
47
|
type: z.string(),
|
|
46
48
|
});
|
|
47
49
|
|
|
@@ -30,6 +30,7 @@ export interface ChatToolPayload {
|
|
|
30
30
|
identifier: string;
|
|
31
31
|
intervention?: ToolIntervention;
|
|
32
32
|
result_msg_id?: string;
|
|
33
|
+
thoughtSignature?: string;
|
|
33
34
|
type: LobeToolRenderType;
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -84,6 +85,7 @@ export interface MessageToolCall {
|
|
|
84
85
|
*/
|
|
85
86
|
id: string;
|
|
86
87
|
|
|
88
|
+
thoughtSignature?: string;
|
|
87
89
|
/**
|
|
88
90
|
* The type of the tool. Currently, only `function` is supported.
|
|
89
91
|
*/
|
|
@@ -108,6 +110,7 @@ export const ChatToolPayloadSchema = z.object({
|
|
|
108
110
|
identifier: z.string(),
|
|
109
111
|
intervention: ToolInterventionSchema.optional(),
|
|
110
112
|
result_msg_id: z.string().optional(),
|
|
113
|
+
thoughtSignature: z.string().optional(),
|
|
111
114
|
type: z.string(),
|
|
112
115
|
});
|
|
113
116
|
|
|
@@ -15,12 +15,13 @@ export interface ErrorContentProps {
|
|
|
15
15
|
|
|
16
16
|
const ErrorContent = memo<ErrorContentProps>(({ error, id }) => {
|
|
17
17
|
const { t } = useTranslation('common');
|
|
18
|
-
const errorProps = useErrorContent(error);
|
|
19
18
|
|
|
20
19
|
const [deleteMessage] = useChatStore((s) => [s.deleteDBMessage]);
|
|
21
20
|
const message = <ErrorMessageExtra block data={{ error, id }} />;
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
const errorProps = useErrorContent(error);
|
|
23
|
+
|
|
24
|
+
if (!errorProps?.message) {
|
|
24
25
|
if (!message) return null;
|
|
25
26
|
return <Flexbox>{message}</Flexbox>;
|
|
26
27
|
}
|
|
@@ -30,10 +30,10 @@ const GroupItem = memo<GroupItemProps>(
|
|
|
30
30
|
});
|
|
31
31
|
}}
|
|
32
32
|
>
|
|
33
|
-
<ContentBlock index={index} {...item} />
|
|
33
|
+
<ContentBlock index={index} {...item} error={error} />
|
|
34
34
|
</Flexbox>
|
|
35
35
|
) : (
|
|
36
|
-
<ContentBlock index={index} {...item} />
|
|
36
|
+
<ContentBlock index={index} {...item} error={error} />
|
|
37
37
|
);
|
|
38
38
|
},
|
|
39
39
|
isEqual,
|
|
@@ -76,7 +76,7 @@ export interface StreamingExecutorAction {
|
|
|
76
76
|
tool_calls?: MessageToolCall[];
|
|
77
77
|
content: string;
|
|
78
78
|
traceId?: string;
|
|
79
|
-
finishType?:
|
|
79
|
+
finishType?: string;
|
|
80
80
|
usage?: ModelUsage;
|
|
81
81
|
}>;
|
|
82
82
|
/**
|
|
@@ -283,13 +283,13 @@ export const streamingExecutor: StateCreator<
|
|
|
283
283
|
let thinkingStartAt: number;
|
|
284
284
|
let duration: number | undefined;
|
|
285
285
|
let reasoningOperationId: string | undefined;
|
|
286
|
-
let finishType:
|
|
286
|
+
let finishType: string | undefined;
|
|
287
287
|
// to upload image
|
|
288
288
|
const uploadTasks: Map<string, Promise<{ id?: string; url?: string }>> = new Map();
|
|
289
289
|
|
|
290
290
|
// Throttle tool_calls updates to prevent excessive re-renders (max once per 300ms)
|
|
291
291
|
const throttledUpdateToolCalls = throttle(
|
|
292
|
-
(toolCalls:
|
|
292
|
+
(toolCalls: MessageToolCall[]) => {
|
|
293
293
|
internal_dispatchMessage(
|
|
294
294
|
{
|
|
295
295
|
id: messageId,
|
|
@@ -366,7 +366,6 @@ export const streamingExecutor: StateCreator<
|
|
|
366
366
|
throttledUpdateToolCalls.flush();
|
|
367
367
|
internal_toggleToolCallingStreaming(messageId, undefined);
|
|
368
368
|
|
|
369
|
-
tools = get().internal_transformToolCalls(parsedToolCalls);
|
|
370
369
|
tool_calls = toolCalls;
|
|
371
370
|
|
|
372
371
|
parsedToolCalls = parsedToolCalls.map((item) => ({
|
|
@@ -377,6 +376,8 @@ export const streamingExecutor: StateCreator<
|
|
|
377
376
|
},
|
|
378
377
|
}));
|
|
379
378
|
|
|
379
|
+
tools = get().internal_transformToolCalls(parsedToolCalls);
|
|
380
|
+
|
|
380
381
|
isFunctionCall = true;
|
|
381
382
|
}
|
|
382
383
|
|
|
@@ -395,7 +396,7 @@ export const streamingExecutor: StateCreator<
|
|
|
395
396
|
messageId,
|
|
396
397
|
content,
|
|
397
398
|
{
|
|
398
|
-
|
|
399
|
+
tools,
|
|
399
400
|
reasoning: !!reasoning
|
|
400
401
|
? { ...reasoning, duration: duration && !isNaN(duration) ? duration : undefined }
|
|
401
402
|
: undefined,
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
ChatImageItem,
|
|
4
4
|
ChatMessageError,
|
|
5
5
|
ChatMessagePluginError,
|
|
6
|
+
ChatToolPayload,
|
|
6
7
|
CreateMessageParams,
|
|
7
8
|
GroundingSearch,
|
|
8
9
|
MessageMetadata,
|
|
9
10
|
MessagePluginItem,
|
|
10
|
-
MessageToolCall,
|
|
11
11
|
ModelReasoning,
|
|
12
12
|
UIChatMessage,
|
|
13
13
|
UpdateMessageRAGParams,
|
|
@@ -69,7 +69,7 @@ export interface MessageOptimisticUpdateAction {
|
|
|
69
69
|
provider?: string;
|
|
70
70
|
reasoning?: ModelReasoning;
|
|
71
71
|
search?: GroundingSearch;
|
|
72
|
-
|
|
72
|
+
tools?: ChatToolPayload[];
|
|
73
73
|
},
|
|
74
74
|
context?: OptimisticUpdateContext,
|
|
75
75
|
) => Promise<void>;
|
|
@@ -204,22 +204,17 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
204
204
|
},
|
|
205
205
|
|
|
206
206
|
optimisticUpdateMessageContent: async (id, content, extra, context) => {
|
|
207
|
-
const {
|
|
208
|
-
internal_dispatchMessage,
|
|
209
|
-
refreshMessages,
|
|
210
|
-
internal_transformToolCalls,
|
|
211
|
-
replaceMessages,
|
|
212
|
-
} = get();
|
|
207
|
+
const { internal_dispatchMessage, refreshMessages, replaceMessages } = get();
|
|
213
208
|
|
|
214
209
|
// Due to the async update method and refresh need about 100ms
|
|
215
210
|
// we need to update the message content at the frontend to avoid the update flick
|
|
216
211
|
// refs: https://medium.com/@kyledeguzmanx/what-are-optimistic-updates-483662c3e171
|
|
217
|
-
if (extra?.
|
|
212
|
+
if (extra?.tools) {
|
|
218
213
|
internal_dispatchMessage(
|
|
219
214
|
{
|
|
220
215
|
id,
|
|
221
216
|
type: 'updateMessage',
|
|
222
|
-
value: { tools:
|
|
217
|
+
value: { tools: extra?.tools },
|
|
223
218
|
},
|
|
224
219
|
context,
|
|
225
220
|
);
|
|
@@ -246,7 +241,7 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
246
241
|
provider: extra?.provider,
|
|
247
242
|
reasoning: extra?.reasoning,
|
|
248
243
|
search: extra?.search,
|
|
249
|
-
tools: extra?.
|
|
244
|
+
tools: extra?.tools,
|
|
250
245
|
},
|
|
251
246
|
{ sessionId, topicId },
|
|
252
247
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
|
|
2
2
|
import { ToolNameResolver } from '@lobechat/context-engine';
|
|
3
|
-
import { MessageToolCall, ToolsCallingContext } from '@lobechat/types';
|
|
3
|
+
import { ChatToolPayload, MessageToolCall, ToolsCallingContext } from '@lobechat/types';
|
|
4
4
|
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
5
5
|
import { StateCreator } from 'zustand/vanilla';
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ export interface PluginInternalsAction {
|
|
|
19
19
|
/**
|
|
20
20
|
* Transform tool calls from runtime format to storage format
|
|
21
21
|
*/
|
|
22
|
-
internal_transformToolCalls: (toolCalls: MessageToolCall[]) =>
|
|
22
|
+
internal_transformToolCalls: (toolCalls: MessageToolCall[]) => ChatToolPayload[];
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Construct tools calling context for plugin invocation
|