@lobehub/chat 1.19.30 → 1.19.32
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 +50 -0
- package/locales/ar/models.json +12 -0
- package/locales/bg-BG/models.json +12 -0
- package/locales/de-DE/models.json +12 -0
- package/locales/en-US/models.json +12 -0
- package/locales/es-ES/models.json +12 -0
- package/locales/fr-FR/models.json +12 -0
- package/locales/it-IT/models.json +12 -0
- package/locales/ja-JP/models.json +12 -0
- package/locales/ko-KR/models.json +12 -0
- package/locales/nl-NL/models.json +12 -0
- package/locales/pl-PL/models.json +12 -0
- package/locales/pt-BR/models.json +12 -0
- package/locales/ru-RU/models.json +12 -0
- package/locales/tr-TR/models.json +12 -0
- package/locales/vi-VN/models.json +12 -0
- package/locales/zh-CN/models.json +13 -1
- package/locales/zh-TW/models.json +12 -0
- package/next.config.mjs +5 -7
- package/package.json +3 -2
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/TextArea.test.tsx +1 -0
- package/src/app/sw.ts +26 -0
- package/src/config/modelProviders/google.ts +54 -2
- package/src/config/modelProviders/taichu.ts +5 -2
- package/src/features/FileViewer/Renderer/Image/index.tsx +1 -0
- package/src/features/PWAInstall/Install.tsx +80 -0
- package/src/features/PWAInstall/index.tsx +6 -61
- package/src/libs/agent-runtime/google/index.test.ts +99 -5
- package/src/libs/agent-runtime/google/index.ts +58 -30
- package/src/server/services/discover/index.ts +1 -1
- package/src/services/message/server.ts +1 -1
- package/src/services/session/server.ts +2 -2
- package/src/store/chat/slices/plugin/action.ts +3 -1
- package/tsconfig.json +3 -3
@@ -1,5 +1,6 @@
|
|
1
1
|
import {
|
2
2
|
Content,
|
3
|
+
FunctionCallPart,
|
3
4
|
FunctionDeclaration,
|
4
5
|
FunctionDeclarationSchemaProperty,
|
5
6
|
FunctionDeclarationSchemaType,
|
@@ -11,6 +12,7 @@ import { JSONSchema7 } from 'json-schema';
|
|
11
12
|
import { transform } from 'lodash-es';
|
12
13
|
|
13
14
|
import { imageUrlToBase64 } from '@/utils/imageToBase64';
|
15
|
+
import { safeParseJSON } from '@/utils/safeParseJSON';
|
14
16
|
|
15
17
|
import { LobeRuntimeAI } from '../BaseAI';
|
16
18
|
import { AgentRuntimeErrorType, ILobeAgentRuntimeErrorType } from '../error';
|
@@ -50,8 +52,9 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
50
52
|
this.baseURL = baseURL;
|
51
53
|
}
|
52
54
|
|
53
|
-
async chat(
|
55
|
+
async chat(rawPayload: ChatStreamPayload, options?: ChatCompetitionOptions) {
|
54
56
|
try {
|
57
|
+
const payload = this.buildPayload(rawPayload);
|
55
58
|
const model = payload.model;
|
56
59
|
|
57
60
|
const contents = await this.buildGoogleMessages(payload.messages, model);
|
@@ -88,7 +91,11 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
88
91
|
},
|
89
92
|
{ apiVersion: 'v1beta', baseUrl: this.baseURL },
|
90
93
|
)
|
91
|
-
.generateContentStream({
|
94
|
+
.generateContentStream({
|
95
|
+
contents,
|
96
|
+
systemInstruction: payload.system as string,
|
97
|
+
tools: this.buildGoogleTools(payload.tools),
|
98
|
+
});
|
92
99
|
|
93
100
|
const googleStream = googleGenAIResultToStream(geminiStreamResult);
|
94
101
|
const [prod, useForDebug] = googleStream.tee();
|
@@ -111,6 +118,16 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
111
118
|
}
|
112
119
|
}
|
113
120
|
|
121
|
+
private buildPayload(payload: ChatStreamPayload) {
|
122
|
+
const system_message = payload.messages.find((m) => m.role === 'system');
|
123
|
+
const user_messages = payload.messages.filter((m) => m.role !== 'system');
|
124
|
+
|
125
|
+
return {
|
126
|
+
...payload,
|
127
|
+
messages: user_messages,
|
128
|
+
system: system_message?.content,
|
129
|
+
};
|
130
|
+
}
|
114
131
|
private convertContentToGooglePart = async (content: UserMessageContentPart): Promise<Part> => {
|
115
132
|
switch (content.type) {
|
116
133
|
case 'text': {
|
@@ -152,6 +169,17 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
152
169
|
message: OpenAIChatMessage,
|
153
170
|
): Promise<Content> => {
|
154
171
|
const content = message.content as string | UserMessageContentPart[];
|
172
|
+
if (!!message.tool_calls) {
|
173
|
+
return {
|
174
|
+
parts: message.tool_calls.map<FunctionCallPart>((tool) => ({
|
175
|
+
functionCall: {
|
176
|
+
args: safeParseJSON(tool.function.arguments)!,
|
177
|
+
name: tool.function.name,
|
178
|
+
},
|
179
|
+
})),
|
180
|
+
role: 'function',
|
181
|
+
};
|
182
|
+
}
|
155
183
|
|
156
184
|
return {
|
157
185
|
parts:
|
@@ -168,44 +196,44 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
168
196
|
messages: OpenAIChatMessage[],
|
169
197
|
model: string,
|
170
198
|
): Promise<Content[]> => {
|
171
|
-
// if the model is gemini-1.
|
172
|
-
if (model
|
173
|
-
const
|
174
|
-
|
175
|
-
|
199
|
+
// if the model is gemini-1.0 we don't need to pair messages
|
200
|
+
if (model.startsWith('gemini-1.0')) {
|
201
|
+
const contents: Content[] = [];
|
202
|
+
let lastRole = 'model';
|
203
|
+
|
204
|
+
for (const message of messages) {
|
205
|
+
// current to filter function message
|
206
|
+
if (message.role === 'function') {
|
207
|
+
continue;
|
208
|
+
}
|
209
|
+
const googleMessage = await this.convertOAIMessagesToGoogleMessage(message);
|
176
210
|
|
177
|
-
|
178
|
-
|
211
|
+
// if the last message is a model message and the current message is a model message
|
212
|
+
// then we need to add a user message to separate them
|
213
|
+
if (lastRole === googleMessage.role) {
|
214
|
+
contents.push({ parts: [{ text: '' }], role: lastRole === 'user' ? 'model' : 'user' });
|
215
|
+
}
|
179
216
|
|
180
|
-
|
181
|
-
|
217
|
+
// add the current message to the contents
|
218
|
+
contents.push(googleMessage);
|
182
219
|
|
183
|
-
|
184
|
-
|
185
|
-
if (message.role === 'function') {
|
186
|
-
continue;
|
220
|
+
// update the last role
|
221
|
+
lastRole = googleMessage.role;
|
187
222
|
}
|
188
|
-
const googleMessage = await this.convertOAIMessagesToGoogleMessage(message);
|
189
223
|
|
190
|
-
// if the last message is a
|
191
|
-
|
192
|
-
|
193
|
-
contents.push({ parts: [{ text: '' }], role: lastRole === 'user' ? 'model' : 'user' });
|
224
|
+
// if the last message is a user message, then we need to add a model message to separate them
|
225
|
+
if (lastRole === 'model') {
|
226
|
+
contents.push({ parts: [{ text: '' }], role: 'user' });
|
194
227
|
}
|
195
228
|
|
196
|
-
|
197
|
-
contents.push(googleMessage);
|
198
|
-
|
199
|
-
// update the last role
|
200
|
-
lastRole = googleMessage.role;
|
229
|
+
return contents;
|
201
230
|
}
|
202
231
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
}
|
232
|
+
const pools = messages
|
233
|
+
.filter((message) => message.role !== 'function')
|
234
|
+
.map(async (msg) => await this.convertOAIMessagesToGoogleMessage(msg));
|
207
235
|
|
208
|
-
return
|
236
|
+
return Promise.all(pools);
|
209
237
|
};
|
210
238
|
|
211
239
|
private parseErrorMessage(message: string): {
|
@@ -212,7 +212,7 @@ export class DiscoverService {
|
|
212
212
|
// Providers
|
213
213
|
|
214
214
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
215
|
-
getProviderList = async (
|
215
|
+
getProviderList = async (_locale: Locales): Promise<DiscoverProviderItem[]> => {
|
216
216
|
const list = DEFAULT_MODEL_PROVIDER_LIST.filter((item) => item.chatModels.length > 0);
|
217
217
|
return list.map((item) => {
|
218
218
|
const provider = {
|
@@ -79,7 +79,7 @@ export class ServerService implements IMessageService {
|
|
79
79
|
return lambdaClient.message.updatePluginState.mutate({ id, value });
|
80
80
|
}
|
81
81
|
|
82
|
-
bindMessagesToTopic(
|
82
|
+
bindMessagesToTopic(_topicId: string, _messageIds: string[]): Promise<any> {
|
83
83
|
throw new Error('Method not implemented.');
|
84
84
|
}
|
85
85
|
|
@@ -91,7 +91,7 @@ export class ServerService implements ISessionService {
|
|
91
91
|
return lambdaClient.session.updateSessionChatConfig.mutate({ id, value }, { signal });
|
92
92
|
}
|
93
93
|
|
94
|
-
getSessionsByType(
|
94
|
+
getSessionsByType(_type: 'agent' | 'group' | 'all' = 'all'): Promise<LobeSessions> {
|
95
95
|
// TODO: need be fixed
|
96
96
|
// @ts-ignore
|
97
97
|
return lambdaClient.session.getSessions.query({});
|
@@ -121,7 +121,7 @@ export class ServerService implements ISessionService {
|
|
121
121
|
return lambdaClient.sessionGroup.getSessionGroup.query();
|
122
122
|
}
|
123
123
|
|
124
|
-
batchCreateSessionGroups(
|
124
|
+
batchCreateSessionGroups(_groups: SessionGroups): Promise<BatchTaskResult> {
|
125
125
|
return Promise.resolve({ added: 0, ids: [], skips: [], success: true });
|
126
126
|
}
|
127
127
|
|
package/tsconfig.json
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"$schema": "https://json.schemastore.org/tsconfig",
|
3
3
|
"compilerOptions": {
|
4
4
|
"target": "ESNext",
|
5
|
-
"lib": ["dom", "dom.iterable", "esnext"],
|
5
|
+
"lib": ["dom", "dom.iterable", "esnext", "webworker"],
|
6
6
|
"allowJs": true,
|
7
7
|
"skipLibCheck": true,
|
8
8
|
"strict": true,
|
@@ -16,7 +16,7 @@
|
|
16
16
|
"jsx": "preserve",
|
17
17
|
"incremental": true,
|
18
18
|
"baseUrl": ".",
|
19
|
-
"types": ["vitest/globals"],
|
19
|
+
"types": ["vitest/globals", "@serwist/next/typings"],
|
20
20
|
"paths": {
|
21
21
|
"@/*": ["./src/*"],
|
22
22
|
"~test-utils": ["./tests/utils.tsx"]
|
@@ -27,7 +27,7 @@
|
|
27
27
|
}
|
28
28
|
]
|
29
29
|
},
|
30
|
-
"exclude": ["node_modules"],
|
30
|
+
"exclude": ["node_modules", "public/sw.js"],
|
31
31
|
"include": [
|
32
32
|
"next-env.d.ts",
|
33
33
|
"vitest.config.ts",
|