@liujitcn/kratos-taro-app-system 0.0.62 → 0.0.64
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/README.md +1 -1
- package/dist/module.mjs +28 -4
- package/package.json +3 -3
- package/src/api/base/v1/ai_provider.ts +25 -0
- package/src/locales/en-US.json +7 -1
- package/src/locales/ja-JP.json +7 -1
- package/src/locales/zh-CN.json +7 -1
- package/src/locales/zh-TW.json +7 -1
- package/src/rpc/base/v1/ai_message.ts +7 -1
- package/src/rpc/base/v1/ai_provider.ts +33 -0
- package/src/rpc/base/v1/ai_session.ts +4 -0
- package/src/rpc/base/v1/notification.ts +2 -0
- package/src/views/pagesMember/ai/components/Composer.tsx +40 -1
- package/src/views/pagesMember/ai/components/composer.scss +23 -0
- package/src/views/pagesMember/ai/index.tsx +44 -5
- package/src/views/pagesMember/message/detail.tsx +8 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
## AI 助手
|
|
17
17
|
|
|
18
|
-
AI 页面支持会话创建与切换、历史会话搜索、消息加载、附件上传、复制、删除、再生成、工具提示和快捷入口。H5 使用 Fetch SSE,微信小程序使用 chunked 请求,两端共用增量 SSE 解析器和相同事件契约。
|
|
18
|
+
AI 页面支持会话创建与切换、历史会话搜索、消息加载、附件上传、复制、删除、再生成、工具提示和快捷入口。Provider 与模型通过独立的 `AiModelService` 选项接口加载。H5 使用 Fetch SSE,微信小程序使用 chunked 请求,两端共用增量 SSE 解析器和相同事件契约。
|
|
19
19
|
|
|
20
20
|
请求统一封装在 `src/api`,RPC 类型由 backend Buf 模板生成。页面不能直接写 `Taro.request`,也不能手工修改 `src/rpc`。
|
|
21
21
|
|
package/dist/module.mjs
CHANGED
|
@@ -51,6 +51,7 @@ var zh_CN_default = {
|
|
|
51
51
|
"system.ai.delete_session_failed": "\u5220\u9664\u4F1A\u8BDD\u5931\u8D25",
|
|
52
52
|
"system.ai.efficiency_assistant": "\u6548\u7387\u52A9\u624B",
|
|
53
53
|
"system.ai.failed_response": "\u8FD9\u6B21\u56DE\u590D\u6CA1\u6709\u6210\u529F\u8FD4\u56DE\uFF0C\u4F60\u53EF\u4EE5\u76F4\u63A5\u91CD\u8BD5\u521A\u624D\u7684\u95EE\u9898\u3002",
|
|
54
|
+
"system.ai.chat.error.details_unavailable": "\u804A\u5929\u754C\u9762\u4E0D\u5C55\u793A\u5E95\u5C42\u670D\u52A1\u9519\u8BEF\u8BE6\u60C5\uFF0C\u8BF7\u67E5\u770B\u670D\u52A1\u65E5\u5FD7\u3002",
|
|
54
55
|
"system.ai.general_assistant": "\u901A\u7528\u52A9\u624B",
|
|
55
56
|
"system.ai.greeting": "\u60A8\u597D\uFF0C{period}\u597D\uFF01\u4ECA\u5929\u6709\u4EC0\u4E48\u9700\u8981\u6211\u534F\u52A9\u7684\u5417\uFF1F",
|
|
56
57
|
"system.ai.greeting_hello": "\u60A8\u597D\uFF0CAI\u52A9\u624B\u4E3A\u60A8\u670D\u52A1\uFF01",
|
|
@@ -98,6 +99,7 @@ var zh_CN_default = {
|
|
|
98
99
|
"system.ai.text_assistant": "\u6587\u672C\u52A9\u624B",
|
|
99
100
|
"system.ai.thinking": "\u6B63\u5728\u56DE\u590D",
|
|
100
101
|
"system.ai.tool_called": "\u5DF2\u8C03\u7528\uFF1A{tools}",
|
|
102
|
+
"system.ai.web_search": "\u8054\u7F51\u641C\u7D22",
|
|
101
103
|
"system.ai.upload_failed": "\u9644\u4EF6\u4E0A\u4F20\u5931\u8D25",
|
|
102
104
|
"system.profile.account": "\u8D26\u53F7",
|
|
103
105
|
"system.profile.avatar_change": "\u70B9\u51FB\u4FEE\u6539\u5934\u50CF",
|
|
@@ -151,6 +153,7 @@ var zh_CN_default = {
|
|
|
151
153
|
"system.settings.mfa_copy_uri": "\u590D\u5236\u7ED1\u5B9A\u5730\u5740",
|
|
152
154
|
"system.settings.mfa_copy_success": "\u590D\u5236\u6210\u529F",
|
|
153
155
|
"system.notification.title": "\u6D88\u606F\u4E2D\u5FC3",
|
|
156
|
+
"system.notification.sender.system": "\u7CFB\u7EDF",
|
|
154
157
|
"system.notification.description": "\u67E5\u770B\u7CFB\u7EDF\u901A\u77E5\u548C\u4E1A\u52A1\u6D88\u606F",
|
|
155
158
|
"system.notification.empty": "\u6682\u65E0\u6D88\u606F",
|
|
156
159
|
"system.notification.action.view_all": "\u67E5\u770B\u5168\u90E8",
|
|
@@ -161,7 +164,10 @@ var zh_CN_default = {
|
|
|
161
164
|
"system.notification.mark_all_read": "\u5168\u90E8\u5DF2\u8BFB",
|
|
162
165
|
"system.notification.action.archive": "\u5F52\u6863",
|
|
163
166
|
"system.notification.action.restore": "\u6062\u590D",
|
|
164
|
-
"system.notification.action.delete": "\u5220\u9664"
|
|
167
|
+
"system.notification.action.delete": "\u5220\u9664",
|
|
168
|
+
"system.ai.model.provider_placeholder": "\u9009\u62E9\u4F9B\u5E94\u5546",
|
|
169
|
+
"system.ai.model.model_placeholder": "\u9009\u62E9\u6A21\u578B",
|
|
170
|
+
"system.ai.model.load_failed": "\u52A0\u8F7D\u4F9B\u5E94\u5546\u548C\u6A21\u578B\u5931\u8D25"
|
|
165
171
|
};
|
|
166
172
|
|
|
167
173
|
// src/locales/en-US.json
|
|
@@ -182,6 +188,7 @@ var en_US_default = {
|
|
|
182
188
|
"system.ai.delete_session_failed": "Failed to delete session",
|
|
183
189
|
"system.ai.efficiency_assistant": "Productivity assistant",
|
|
184
190
|
"system.ai.failed_response": "The response did not complete. You can retry your previous question.",
|
|
191
|
+
"system.ai.chat.error.details_unavailable": "Provider error details are not exposed in chat. See the service logs.",
|
|
185
192
|
"system.ai.general_assistant": "General assistant",
|
|
186
193
|
"system.ai.greeting": "Good {period}, how can I help you today?",
|
|
187
194
|
"system.ai.greeting_hello": "Hello, your AI assistant is ready to help.",
|
|
@@ -229,6 +236,7 @@ var en_US_default = {
|
|
|
229
236
|
"system.ai.text_assistant": "Writing assistant",
|
|
230
237
|
"system.ai.thinking": "Responding",
|
|
231
238
|
"system.ai.tool_called": "Tools used: {tools}",
|
|
239
|
+
"system.ai.web_search": "Web search",
|
|
232
240
|
"system.ai.upload_failed": "Attachment upload failed",
|
|
233
241
|
"system.profile.account": "Account",
|
|
234
242
|
"system.profile.avatar_change": "Tap to change avatar",
|
|
@@ -282,6 +290,7 @@ var en_US_default = {
|
|
|
282
290
|
"system.settings.mfa_copy_uri": "Copy binding address",
|
|
283
291
|
"system.settings.mfa_copy_success": "Copied",
|
|
284
292
|
"system.notification.title": "Message Center",
|
|
293
|
+
"system.notification.sender.system": "System",
|
|
285
294
|
"system.notification.description": "View system notifications and business messages",
|
|
286
295
|
"system.notification.empty": "No messages",
|
|
287
296
|
"system.notification.action.view_all": "View all",
|
|
@@ -292,7 +301,10 @@ var en_US_default = {
|
|
|
292
301
|
"system.notification.mark_all_read": "Mark all read",
|
|
293
302
|
"system.notification.action.archive": "Archive",
|
|
294
303
|
"system.notification.action.restore": "Restore",
|
|
295
|
-
"system.notification.action.delete": "Delete"
|
|
304
|
+
"system.notification.action.delete": "Delete",
|
|
305
|
+
"system.ai.model.provider_placeholder": "Select a provider",
|
|
306
|
+
"system.ai.model.model_placeholder": "Select a model",
|
|
307
|
+
"system.ai.model.load_failed": "Failed to load providers and models"
|
|
296
308
|
};
|
|
297
309
|
|
|
298
310
|
// src/locales/ja-JP.json
|
|
@@ -313,6 +325,7 @@ var ja_JP_default = {
|
|
|
313
325
|
"system.ai.delete_session_failed": "\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u524A\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
314
326
|
"system.ai.efficiency_assistant": "\u52B9\u7387\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8",
|
|
315
327
|
"system.ai.failed_response": "\u4ECA\u56DE\u306F\u5FDC\u7B54\u304C\u6B63\u5E38\u306B\u8FD4\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u8CEA\u554F\u3092\u76F4\u63A5\u518D\u8A66\u884C\u3067\u304D\u307E\u3059\u3002",
|
|
328
|
+
"system.ai.chat.error.details_unavailable": "\u30C1\u30E3\u30C3\u30C8\u3067\u306F\u5185\u90E8\u30A8\u30E9\u30FC\u306E\u8A73\u7D30\u306F\u8868\u793A\u3055\u308C\u307E\u305B\u3093\u3002\u30B5\u30FC\u30D3\u30B9\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
316
329
|
"system.ai.general_assistant": "\u30E6\u30CB\u30D0\u30FC\u30B5\u30EB \u30A2\u30B7\u30B9\u30BF\u30F3\u30C8",
|
|
317
330
|
"system.ai.greeting": "\u3053\u3093\u306B\u3061\u306F\u3001{period} \u3053\u3093\u306B\u3061\u306F\uFF01\u4ECA\u65E5\u306F\u4F55\u304B\u304A\u624B\u4F1D\u3044\u304C\u5FC5\u8981\u306A\u3053\u3068\u306F\u3042\u308A\u307E\u3059\u304B?",
|
|
318
331
|
"system.ai.greeting_hello": "\u3053\u3093\u306B\u3061\u306F\u3001AI \u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u304C\u304A\u624B\u4F1D\u3044\u3057\u307E\u3059\u3002",
|
|
@@ -360,6 +373,7 @@ var ja_JP_default = {
|
|
|
360
373
|
"system.ai.text_assistant": "\u30C6\u30AD\u30B9\u30C8 \u30A2\u30B7\u30B9\u30BF\u30F3\u30C8",
|
|
361
374
|
"system.ai.thinking": "\u304C\u8FD4\u4FE1\u3057\u3066\u3044\u307E\u3059",
|
|
362
375
|
"system.ai.tool_called": "\u547C\u3073\u51FA\u3057\u5148: {tools}",
|
|
376
|
+
"system.ai.web_search": "\u30A6\u30A7\u30D6\u691C\u7D22",
|
|
363
377
|
"system.ai.upload_failed": "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
364
378
|
"system.profile.account": "\u30A2\u30AB\u30A6\u30F3\u30C8",
|
|
365
379
|
"system.profile.avatar_change": "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30A2\u30D0\u30BF\u30FC\u3092\u5909\u66F4\u3057\u307E\u3059",
|
|
@@ -413,6 +427,7 @@ var ja_JP_default = {
|
|
|
413
427
|
"system.settings.mfa_copy_uri": "\u767B\u9332\u30A2\u30C9\u30EC\u30B9\u3092\u30B3\u30D4\u30FC",
|
|
414
428
|
"system.settings.mfa_copy_success": "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F",
|
|
415
429
|
"system.notification.title": "\u30E1\u30C3\u30BB\u30FC\u30B8\u30BB\u30F3\u30BF\u30FC",
|
|
430
|
+
"system.notification.sender.system": "\u30B7\u30B9\u30C6\u30E0",
|
|
416
431
|
"system.notification.description": "\u30B7\u30B9\u30C6\u30E0\u901A\u77E5\u3068\u696D\u52D9\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u78BA\u8A8D",
|
|
417
432
|
"system.notification.empty": "\u30E1\u30C3\u30BB\u30FC\u30B8\u306F\u3042\u308A\u307E\u305B\u3093",
|
|
418
433
|
"system.notification.action.view_all": "\u3059\u3079\u3066\u8868\u793A",
|
|
@@ -423,7 +438,10 @@ var ja_JP_default = {
|
|
|
423
438
|
"system.notification.mark_all_read": "\u3059\u3079\u3066\u65E2\u8AAD",
|
|
424
439
|
"system.notification.action.archive": "\u30A2\u30FC\u30AB\u30A4\u30D6",
|
|
425
440
|
"system.notification.action.restore": "\u5FA9\u5143",
|
|
426
|
-
"system.notification.action.delete": "\u524A\u9664"
|
|
441
|
+
"system.notification.action.delete": "\u524A\u9664",
|
|
442
|
+
"system.ai.model.provider_placeholder": "\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u3092\u9078\u629E",
|
|
443
|
+
"system.ai.model.model_placeholder": "\u30E2\u30C7\u30EB\u3092\u9078\u629E",
|
|
444
|
+
"system.ai.model.load_failed": "\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u3068\u30E2\u30C7\u30EB\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F"
|
|
427
445
|
};
|
|
428
446
|
|
|
429
447
|
// src/locales/zh-TW.json
|
|
@@ -444,6 +462,7 @@ var zh_TW_default = {
|
|
|
444
462
|
"system.ai.delete_session_failed": "\u522A\u9664\u6703\u8A71\u5931\u6557",
|
|
445
463
|
"system.ai.efficiency_assistant": "\u6548\u7387\u52A9\u624B",
|
|
446
464
|
"system.ai.failed_response": "\u9019\u6B21\u56DE\u8986\u6C92\u6709\u6210\u529F\u8FD4\u56DE\uFF0C\u4F60\u53EF\u4EE5\u76F4\u63A5\u91CD\u8A66\u525B\u624D\u7684\u554F\u984C\u3002",
|
|
465
|
+
"system.ai.chat.error.details_unavailable": "\u804A\u5929\u4ECB\u9762\u4E0D\u6703\u986F\u793A\u5E95\u5C64\u670D\u52D9\u932F\u8AA4\u8A73\u60C5\uFF0C\u8ACB\u67E5\u770B\u670D\u52D9\u65E5\u8A8C\u3002",
|
|
447
466
|
"system.ai.general_assistant": "\u901A\u7528\u52A9\u624B",
|
|
448
467
|
"system.ai.greeting": "\u60A8\u597D\uFF0C{period}\u597D\uFF01\u4ECA\u5929\u6709\u4EC0\u9EBC\u9700\u8981\u6211\u5354\u52A9\u7684\u55CE\uFF1F",
|
|
449
468
|
"system.ai.greeting_hello": "\u60A8\u597D\uFF0CAI\u52A9\u624B\u70BA\u60A8\u670D\u52D9\uFF01",
|
|
@@ -491,6 +510,7 @@ var zh_TW_default = {
|
|
|
491
510
|
"system.ai.text_assistant": "\u6587\u5B57\u52A9\u624B",
|
|
492
511
|
"system.ai.thinking": "\u6B63\u5728\u56DE\u8986",
|
|
493
512
|
"system.ai.tool_called": "\u5DF2\u547C\u53EB\uFF1A{tools}",
|
|
513
|
+
"system.ai.web_search": "\u7DB2\u8DEF\u641C\u5C0B",
|
|
494
514
|
"system.ai.upload_failed": "\u9644\u4EF6\u4E0A\u50B3\u5931\u6557",
|
|
495
515
|
"system.profile.account": "\u8CEC\u865F",
|
|
496
516
|
"system.profile.avatar_change": "\u9EDE\u9078\u4FEE\u6539\u982D\u50CF",
|
|
@@ -544,6 +564,7 @@ var zh_TW_default = {
|
|
|
544
564
|
"system.settings.mfa_copy_uri": "\u8907\u88FD\u7D81\u5B9A\u5730\u5740",
|
|
545
565
|
"system.settings.mfa_copy_success": "\u8907\u88FD\u6210\u529F",
|
|
546
566
|
"system.notification.title": "\u6D88\u606F\u4E2D\u5FC3",
|
|
567
|
+
"system.notification.sender.system": "\u7CFB\u7D71",
|
|
547
568
|
"system.notification.description": "\u67E5\u770B\u7CFB\u7D71\u901A\u77E5\u548C\u696D\u52D9\u6D88\u606F",
|
|
548
569
|
"system.notification.empty": "\u66AB\u7121\u6D88\u606F",
|
|
549
570
|
"system.notification.action.view_all": "\u67E5\u770B\u5168\u90E8",
|
|
@@ -554,7 +575,10 @@ var zh_TW_default = {
|
|
|
554
575
|
"system.notification.mark_all_read": "\u5168\u90E8\u5DF2\u8B80",
|
|
555
576
|
"system.notification.action.archive": "\u6B78\u6A94",
|
|
556
577
|
"system.notification.action.restore": "\u6062\u5FA9",
|
|
557
|
-
"system.notification.action.delete": "\u522A\u9664"
|
|
578
|
+
"system.notification.action.delete": "\u522A\u9664",
|
|
579
|
+
"system.ai.model.provider_placeholder": "\u9078\u64C7\u4F9B\u61C9\u5546",
|
|
580
|
+
"system.ai.model.model_placeholder": "\u9078\u64C7\u6A21\u578B",
|
|
581
|
+
"system.ai.model.load_failed": "\u8F09\u5165\u4F9B\u61C9\u5546\u8207\u6A21\u578B\u5931\u6557"
|
|
558
582
|
};
|
|
559
583
|
|
|
560
584
|
// src/locales/generated.ts
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git@github.com:liujitcn/kratos-admin.git"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.0.
|
|
10
|
+
"version": "0.0.64",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"@tarojs/components": "4.2.1",
|
|
39
39
|
"@tarojs/taro": "4.2.1",
|
|
40
40
|
"react": "18.3.1",
|
|
41
|
-
"@liujitcn/kratos-taro-app-
|
|
42
|
-
"@liujitcn/kratos-taro-app-
|
|
41
|
+
"@liujitcn/kratos-taro-app-ui": "^0.0.64",
|
|
42
|
+
"@liujitcn/kratos-taro-app-core": "^0.0.64"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "pnpm run build:entries && pnpm pack --pack-destination ../../../dist/npm",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { http } from '@liujitcn/kratos-taro-app-core/utils/http'
|
|
2
|
+
import type {
|
|
3
|
+
AiModelService,
|
|
4
|
+
ListAiProviderModelOptionsRequest,
|
|
5
|
+
ListAiProviderModelOptionsResponse,
|
|
6
|
+
} from '../../../rpc/base/v1/ai_provider'
|
|
7
|
+
|
|
8
|
+
const AI_PROVIDER_MODELS_URL = '/v1/base/ai/provider-models'
|
|
9
|
+
|
|
10
|
+
/** AI Provider模型选项服务。 */
|
|
11
|
+
export class AiModelServiceImpl implements AiModelService {
|
|
12
|
+
/** 查询已启用Provider及其可用模型。 */
|
|
13
|
+
ListAiProviderModelOptions(
|
|
14
|
+
request: ListAiProviderModelOptionsRequest,
|
|
15
|
+
): Promise<ListAiProviderModelOptionsResponse> {
|
|
16
|
+
return http<ListAiProviderModelOptionsResponse>({
|
|
17
|
+
url: AI_PROVIDER_MODELS_URL,
|
|
18
|
+
method: 'GET',
|
|
19
|
+
authMode: 'required',
|
|
20
|
+
data: request,
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const defAiModelService = new AiModelServiceImpl()
|
package/src/locales/en-US.json
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"system.ai.delete_session_failed": "Failed to delete session",
|
|
16
16
|
"system.ai.efficiency_assistant": "Productivity assistant",
|
|
17
17
|
"system.ai.failed_response": "The response did not complete. You can retry your previous question.",
|
|
18
|
+
"system.ai.chat.error.details_unavailable": "Provider error details are not exposed in chat. See the service logs.",
|
|
18
19
|
"system.ai.general_assistant": "General assistant",
|
|
19
20
|
"system.ai.greeting": "Good {period}, how can I help you today?",
|
|
20
21
|
"system.ai.greeting_hello": "Hello, your AI assistant is ready to help.",
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"system.ai.text_assistant": "Writing assistant",
|
|
63
64
|
"system.ai.thinking": "Responding",
|
|
64
65
|
"system.ai.tool_called": "Tools used: {tools}",
|
|
66
|
+
"system.ai.web_search": "Web search",
|
|
65
67
|
"system.ai.upload_failed": "Attachment upload failed",
|
|
66
68
|
"system.profile.account": "Account",
|
|
67
69
|
"system.profile.avatar_change": "Tap to change avatar",
|
|
@@ -115,6 +117,7 @@
|
|
|
115
117
|
"system.settings.mfa_copy_uri": "Copy binding address",
|
|
116
118
|
"system.settings.mfa_copy_success": "Copied",
|
|
117
119
|
"system.notification.title": "Message Center",
|
|
120
|
+
"system.notification.sender.system": "System",
|
|
118
121
|
"system.notification.description": "View system notifications and business messages",
|
|
119
122
|
"system.notification.empty": "No messages",
|
|
120
123
|
"system.notification.action.view_all": "View all",
|
|
@@ -125,5 +128,8 @@
|
|
|
125
128
|
"system.notification.mark_all_read": "Mark all read",
|
|
126
129
|
"system.notification.action.archive": "Archive",
|
|
127
130
|
"system.notification.action.restore": "Restore",
|
|
128
|
-
"system.notification.action.delete": "Delete"
|
|
131
|
+
"system.notification.action.delete": "Delete",
|
|
132
|
+
"system.ai.model.provider_placeholder": "Select a provider",
|
|
133
|
+
"system.ai.model.model_placeholder": "Select a model",
|
|
134
|
+
"system.ai.model.load_failed": "Failed to load providers and models"
|
|
129
135
|
}
|
package/src/locales/ja-JP.json
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"system.ai.delete_session_failed": "セッションの削除に失敗しました",
|
|
16
16
|
"system.ai.efficiency_assistant": "効率アシスタント",
|
|
17
17
|
"system.ai.failed_response": "今回は応答が正常に返されませんでした。質問を直接再試行できます。",
|
|
18
|
+
"system.ai.chat.error.details_unavailable": "チャットでは内部エラーの詳細は表示されません。サービスログを確認してください。",
|
|
18
19
|
"system.ai.general_assistant": "ユニバーサル アシスタント",
|
|
19
20
|
"system.ai.greeting": "こんにちは、{period} こんにちは!今日は何かお手伝いが必要なことはありますか?",
|
|
20
21
|
"system.ai.greeting_hello": "こんにちは、AI アシスタントがお手伝いします。",
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"system.ai.text_assistant": "テキスト アシスタント",
|
|
63
64
|
"system.ai.thinking": "が返信しています",
|
|
64
65
|
"system.ai.tool_called": "呼び出し先: {tools}",
|
|
66
|
+
"system.ai.web_search": "ウェブ検索",
|
|
65
67
|
"system.ai.upload_failed": "添付ファイルのアップロードに失敗しました",
|
|
66
68
|
"system.profile.account": "アカウント",
|
|
67
69
|
"system.profile.avatar_change": "クリックしてアバターを変更します",
|
|
@@ -115,6 +117,7 @@
|
|
|
115
117
|
"system.settings.mfa_copy_uri": "登録アドレスをコピー",
|
|
116
118
|
"system.settings.mfa_copy_success": "コピーしました",
|
|
117
119
|
"system.notification.title": "メッセージセンター",
|
|
120
|
+
"system.notification.sender.system": "システム",
|
|
118
121
|
"system.notification.description": "システム通知と業務メッセージを確認",
|
|
119
122
|
"system.notification.empty": "メッセージはありません",
|
|
120
123
|
"system.notification.action.view_all": "すべて表示",
|
|
@@ -125,5 +128,8 @@
|
|
|
125
128
|
"system.notification.mark_all_read": "すべて既読",
|
|
126
129
|
"system.notification.action.archive": "アーカイブ",
|
|
127
130
|
"system.notification.action.restore": "復元",
|
|
128
|
-
"system.notification.action.delete": "削除"
|
|
131
|
+
"system.notification.action.delete": "削除",
|
|
132
|
+
"system.ai.model.provider_placeholder": "プロバイダーを選択",
|
|
133
|
+
"system.ai.model.model_placeholder": "モデルを選択",
|
|
134
|
+
"system.ai.model.load_failed": "プロバイダーとモデルを読み込めませんでした"
|
|
129
135
|
}
|
package/src/locales/zh-CN.json
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"system.ai.delete_session_failed": "删除会话失败",
|
|
16
16
|
"system.ai.efficiency_assistant": "效率助手",
|
|
17
17
|
"system.ai.failed_response": "这次回复没有成功返回,你可以直接重试刚才的问题。",
|
|
18
|
+
"system.ai.chat.error.details_unavailable": "聊天界面不展示底层服务错误详情,请查看服务日志。",
|
|
18
19
|
"system.ai.general_assistant": "通用助手",
|
|
19
20
|
"system.ai.greeting": "您好,{period}好!今天有什么需要我协助的吗?",
|
|
20
21
|
"system.ai.greeting_hello": "您好,AI助手为您服务!",
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"system.ai.text_assistant": "文本助手",
|
|
63
64
|
"system.ai.thinking": "正在回复",
|
|
64
65
|
"system.ai.tool_called": "已调用:{tools}",
|
|
66
|
+
"system.ai.web_search": "联网搜索",
|
|
65
67
|
"system.ai.upload_failed": "附件上传失败",
|
|
66
68
|
"system.profile.account": "账号",
|
|
67
69
|
"system.profile.avatar_change": "点击修改头像",
|
|
@@ -115,6 +117,7 @@
|
|
|
115
117
|
"system.settings.mfa_copy_uri": "复制绑定地址",
|
|
116
118
|
"system.settings.mfa_copy_success": "复制成功",
|
|
117
119
|
"system.notification.title": "消息中心",
|
|
120
|
+
"system.notification.sender.system": "系统",
|
|
118
121
|
"system.notification.description": "查看系统通知和业务消息",
|
|
119
122
|
"system.notification.empty": "暂无消息",
|
|
120
123
|
"system.notification.action.view_all": "查看全部",
|
|
@@ -125,5 +128,8 @@
|
|
|
125
128
|
"system.notification.mark_all_read": "全部已读",
|
|
126
129
|
"system.notification.action.archive": "归档",
|
|
127
130
|
"system.notification.action.restore": "恢复",
|
|
128
|
-
"system.notification.action.delete": "删除"
|
|
131
|
+
"system.notification.action.delete": "删除",
|
|
132
|
+
"system.ai.model.provider_placeholder": "选择供应商",
|
|
133
|
+
"system.ai.model.model_placeholder": "选择模型",
|
|
134
|
+
"system.ai.model.load_failed": "加载供应商和模型失败"
|
|
129
135
|
}
|
package/src/locales/zh-TW.json
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"system.ai.delete_session_failed": "刪除會話失敗",
|
|
16
16
|
"system.ai.efficiency_assistant": "效率助手",
|
|
17
17
|
"system.ai.failed_response": "這次回覆沒有成功返回,你可以直接重試剛才的問題。",
|
|
18
|
+
"system.ai.chat.error.details_unavailable": "聊天介面不會顯示底層服務錯誤詳情,請查看服務日誌。",
|
|
18
19
|
"system.ai.general_assistant": "通用助手",
|
|
19
20
|
"system.ai.greeting": "您好,{period}好!今天有什麼需要我協助的嗎?",
|
|
20
21
|
"system.ai.greeting_hello": "您好,AI助手為您服務!",
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"system.ai.text_assistant": "文字助手",
|
|
63
64
|
"system.ai.thinking": "正在回覆",
|
|
64
65
|
"system.ai.tool_called": "已呼叫:{tools}",
|
|
66
|
+
"system.ai.web_search": "網路搜尋",
|
|
65
67
|
"system.ai.upload_failed": "附件上傳失敗",
|
|
66
68
|
"system.profile.account": "賬號",
|
|
67
69
|
"system.profile.avatar_change": "點選修改頭像",
|
|
@@ -115,6 +117,7 @@
|
|
|
115
117
|
"system.settings.mfa_copy_uri": "複製綁定地址",
|
|
116
118
|
"system.settings.mfa_copy_success": "複製成功",
|
|
117
119
|
"system.notification.title": "消息中心",
|
|
120
|
+
"system.notification.sender.system": "系統",
|
|
118
121
|
"system.notification.description": "查看系統通知和業務消息",
|
|
119
122
|
"system.notification.empty": "暫無消息",
|
|
120
123
|
"system.notification.action.view_all": "查看全部",
|
|
@@ -125,5 +128,8 @@
|
|
|
125
128
|
"system.notification.mark_all_read": "全部已讀",
|
|
126
129
|
"system.notification.action.archive": "歸檔",
|
|
127
130
|
"system.notification.action.restore": "恢復",
|
|
128
|
-
"system.notification.action.delete": "刪除"
|
|
131
|
+
"system.notification.action.delete": "刪除",
|
|
132
|
+
"system.ai.model.provider_placeholder": "選擇供應商",
|
|
133
|
+
"system.ai.model.model_placeholder": "選擇模型",
|
|
134
|
+
"system.ai.model.load_failed": "載入供應商與模型失敗"
|
|
129
135
|
}
|
|
@@ -46,7 +46,13 @@ export interface SendAiMessageRequest {
|
|
|
46
46
|
/** 附件列表 */
|
|
47
47
|
attachments: AiAttachment[];
|
|
48
48
|
/** 助手动作 */
|
|
49
|
-
action:
|
|
49
|
+
action:
|
|
50
|
+
| AiAction
|
|
51
|
+
| undefined;
|
|
52
|
+
/** 所选供应商ID;留空时使用首个可用模型 */
|
|
53
|
+
provider_id: number;
|
|
54
|
+
/** 所选模型名称 */
|
|
55
|
+
model_name: string;
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
/** AI 助手失败消息重试请求 */
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
|
+
// versions:
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
|
+
// protoc unknown
|
|
5
|
+
// source: base/v1/ai_provider.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
|
|
9
|
+
/** AI Provider模型选项查询请求。 */
|
|
10
|
+
export interface ListAiProviderModelOptionsRequest {
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** 已启用的AI Provider及其模型选项。 */
|
|
14
|
+
export interface AiProviderModelOption {
|
|
15
|
+
/** Provider ID */
|
|
16
|
+
provider_id: number;
|
|
17
|
+
/** Provider名称 */
|
|
18
|
+
name: string;
|
|
19
|
+
/** 模型名称列表 */
|
|
20
|
+
models: string[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** AI Provider模型选项查询响应。 */
|
|
24
|
+
export interface ListAiProviderModelOptionsResponse {
|
|
25
|
+
/** Provider及其模型列表 */
|
|
26
|
+
providers: AiProviderModelOption[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** AI Provider 可选模型查询服务。 */
|
|
30
|
+
export interface AiModelService {
|
|
31
|
+
/** 查询已启用的AI Provider及其可用模型。 */
|
|
32
|
+
ListAiProviderModelOptions(request: ListAiProviderModelOptionsRequest): Promise<ListAiProviderModelOptionsResponse>;
|
|
33
|
+
}
|
|
@@ -108,6 +108,8 @@ export interface DeleteAiSessionResponse {
|
|
|
108
108
|
export interface AiSession {
|
|
109
109
|
/** 会话ID */
|
|
110
110
|
id: string;
|
|
111
|
+
/** 租户ID */
|
|
112
|
+
tenant_id: number;
|
|
111
113
|
/** 会话标题 */
|
|
112
114
|
title: string;
|
|
113
115
|
/** 会话摘要 */
|
|
@@ -124,6 +126,8 @@ export interface AiSession {
|
|
|
124
126
|
export interface AiMessage {
|
|
125
127
|
/** 消息ID */
|
|
126
128
|
id: string;
|
|
129
|
+
/** 租户ID */
|
|
130
|
+
tenant_id: number;
|
|
127
131
|
/** 输入内容 */
|
|
128
132
|
input_content:
|
|
129
133
|
| AiInputContent
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import { Button, Text, Textarea, View } from '@tarojs/components'
|
|
1
|
+
import { Button, Picker, Text, Textarea, View } from '@tarojs/components'
|
|
2
2
|
import { UniIcon } from '@liujitcn/kratos-taro-app-ui'
|
|
3
3
|
import type { AiAttachment } from '../../../../rpc/base/v1/ai_session'
|
|
4
|
+
import type { AiProviderModelOption } from '../../../../rpc/base/v1/ai_provider'
|
|
4
5
|
import './composer.scss'
|
|
5
6
|
|
|
7
|
+
/** AI 助手输入框与模型选择器参数。 */
|
|
6
8
|
type ComposerProps = {
|
|
7
9
|
value: string
|
|
8
10
|
attachments: AiAttachment[]
|
|
11
|
+
/** 当前可供选择的供应商与模型。 */
|
|
12
|
+
modelProviders: AiProviderModelOption[]
|
|
13
|
+
/** 当前选中的供应商编号和模型名称。 */
|
|
14
|
+
providerId: number
|
|
15
|
+
modelName: string
|
|
16
|
+
/** 选择器未配置时显示的本地化占位文字。 */
|
|
17
|
+
providerPlaceholder: string
|
|
18
|
+
modelPlaceholder: string
|
|
9
19
|
placeholder: string
|
|
10
20
|
bottom: string
|
|
11
21
|
recording: boolean
|
|
@@ -16,12 +26,41 @@ type ComposerProps = {
|
|
|
16
26
|
onRecord: () => void
|
|
17
27
|
onSend: () => void
|
|
18
28
|
onRemoveAttachment: (attachment: AiAttachment) => void
|
|
29
|
+
onModelChange: (providerId: number, modelName: string) => void
|
|
19
30
|
}
|
|
20
31
|
|
|
21
32
|
/** AI 助手消息输入器。 */
|
|
22
33
|
export default function Composer(props: ComposerProps) {
|
|
34
|
+
const selectedProvider = props.modelProviders.find((provider) => provider.provider_id === props.providerId)
|
|
35
|
+
const modelNames = selectedProvider?.models ?? []
|
|
36
|
+
const providerIndex = Math.max(props.modelProviders.findIndex((provider) => provider.provider_id === props.providerId), 0)
|
|
37
|
+
const modelIndex = Math.max(modelNames.indexOf(props.modelName), 0)
|
|
38
|
+
|
|
23
39
|
return (
|
|
24
40
|
<View className='composer' style={{ paddingBottom: props.bottom }}>
|
|
41
|
+
<View className='composer-model-selectors'>
|
|
42
|
+
<Picker
|
|
43
|
+
mode='selector'
|
|
44
|
+
range={props.modelProviders.map((provider) => provider.name)}
|
|
45
|
+
value={providerIndex}
|
|
46
|
+
disabled={props.sending || !props.modelProviders.length}
|
|
47
|
+
onChange={(event) => {
|
|
48
|
+
const provider = props.modelProviders[Number(event.detail.value)]
|
|
49
|
+
props.onModelChange(provider?.provider_id ?? 0, provider?.models[0] ?? '')
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<View className='composer-model-select'><Text>{selectedProvider?.name || props.providerPlaceholder}</Text></View>
|
|
53
|
+
</Picker>
|
|
54
|
+
<Picker
|
|
55
|
+
mode='selector'
|
|
56
|
+
range={modelNames}
|
|
57
|
+
value={modelIndex}
|
|
58
|
+
disabled={props.sending || !modelNames.length}
|
|
59
|
+
onChange={(event) => props.onModelChange(props.providerId, modelNames[Number(event.detail.value)] ?? '')}
|
|
60
|
+
>
|
|
61
|
+
<View className='composer-model-select'><Text>{props.modelName || props.modelPlaceholder}</Text></View>
|
|
62
|
+
</Picker>
|
|
63
|
+
</View>
|
|
25
64
|
<View className='composer-main'>
|
|
26
65
|
<Button className='attach-button' hoverClass='none' onClick={props.onAttach}>
|
|
27
66
|
<UniIcon type='plusempty' size={30} color='#111' />
|
|
@@ -19,6 +19,29 @@
|
|
|
19
19
|
box-sizing: border-box;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
.composer-model-selectors {
|
|
23
|
+
display: flex;
|
|
24
|
+
justify-content: flex-end;
|
|
25
|
+
gap: 12px;
|
|
26
|
+
min-width: 0;
|
|
27
|
+
margin: 0 8px 12px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.composer-model-select {
|
|
31
|
+
max-width: 300px;
|
|
32
|
+
min-width: 120px;
|
|
33
|
+
padding: 8px 16px;
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
color: #46515b;
|
|
36
|
+
font-size: 22px;
|
|
37
|
+
line-height: 32px;
|
|
38
|
+
text-overflow: ellipsis;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
background: #fff;
|
|
41
|
+
border: 2px solid #d6dae2;
|
|
42
|
+
border-radius: 8px;
|
|
43
|
+
}
|
|
44
|
+
|
|
22
45
|
.composer-main {
|
|
23
46
|
display: flex;
|
|
24
47
|
align-items: center;
|
|
@@ -13,7 +13,9 @@ import { UniIcon } from '@liujitcn/kratos-taro-app-ui'
|
|
|
13
13
|
import { defAiMessageService, StreamAiMessageByChunkedRequest } from '../../../api/base/v1/ai_message'
|
|
14
14
|
import { defAiSessionService } from '../../../api/base/v1/ai_session'
|
|
15
15
|
import { defAiToolService } from '../../../api/base/v1/ai_tool'
|
|
16
|
+
import { defAiModelService } from '../../../api/base/v1/ai_provider'
|
|
16
17
|
import type { AiAttachment, AiMessage, AiSession } from '../../../rpc/base/v1/ai_session'
|
|
18
|
+
import type { AiProviderModelOption } from '../../../rpc/base/v1/ai_provider'
|
|
17
19
|
import type { AiShortcut, AiToolCall } from '../../../rpc/base/v1/ai_tool'
|
|
18
20
|
import { AiMessageStatus } from '../../../rpc/base/v1/ai_session'
|
|
19
21
|
import { Terminal } from '../../../rpc/base/v1/ai_tool'
|
|
@@ -92,6 +94,9 @@ export default function AiPage() {
|
|
|
92
94
|
const [sessions, setSessionsState] = useState<AiSession[]>([])
|
|
93
95
|
const [messages, setMessagesState] = useState<MessageMap>({})
|
|
94
96
|
const [selectedAttachments, setSelectedAttachments] = useState<AiAttachment[]>([])
|
|
97
|
+
const [modelProviders, setModelProviders] = useState<AiProviderModelOption[]>([])
|
|
98
|
+
const [selectedProviderId, setSelectedProviderId] = useState(0)
|
|
99
|
+
const [selectedModelName, setSelectedModelName] = useState('')
|
|
95
100
|
const [starterShortcuts, setStarterShortcuts] = useState<AiShortcut[]>(createDefaultShortcuts)
|
|
96
101
|
|
|
97
102
|
const activeSessionIDRef = useRef('')
|
|
@@ -351,25 +356,50 @@ export default function AiPage() {
|
|
|
351
356
|
if (loadingShortcutsRef.current) return
|
|
352
357
|
setLoadingShortcuts(true)
|
|
353
358
|
try {
|
|
354
|
-
const response = await
|
|
359
|
+
const [response, providerResponse] = await Promise.all([
|
|
360
|
+
defAiToolService.ListAiShortcut({ terminal: AI_TERMINAL }),
|
|
361
|
+
defAiModelService.ListAiProviderModelOptions({}),
|
|
362
|
+
])
|
|
355
363
|
const shortcuts = normalizeStarterShortcuts(response.shortcuts).filter((item) => !item.action)
|
|
364
|
+
const providers = providerResponse.providers ?? []
|
|
365
|
+
setModelProviders(providers)
|
|
366
|
+
if (!providers.some((item) => item.provider_id === selectedProviderId && item.models.includes(selectedModelName))) {
|
|
367
|
+
const firstProvider = providers[0]
|
|
368
|
+
setSelectedProviderId(firstProvider?.provider_id ?? 0)
|
|
369
|
+
setSelectedModelName(firstProvider?.models[0] ?? '')
|
|
370
|
+
}
|
|
356
371
|
if (shortcuts.length) {
|
|
357
372
|
setStarterShortcuts(shortcuts)
|
|
358
373
|
setStarterPromptGroupIndex(0)
|
|
359
374
|
}
|
|
360
375
|
} catch (error) {
|
|
376
|
+
setModelProviders([])
|
|
377
|
+
setSelectedProviderId(0)
|
|
378
|
+
setSelectedModelName('')
|
|
361
379
|
showError(error, t('system.ai.load_shortcuts_failed'))
|
|
362
380
|
} finally {
|
|
363
381
|
setLoadingShortcuts(false)
|
|
364
382
|
}
|
|
365
383
|
}
|
|
366
384
|
|
|
385
|
+
const handleModelChange = (providerId: number, modelName: string) => {
|
|
386
|
+
setSelectedProviderId(providerId)
|
|
387
|
+
setSelectedModelName(modelName)
|
|
388
|
+
}
|
|
389
|
+
|
|
367
390
|
const runAiTask = async (
|
|
368
391
|
sessionID: string,
|
|
369
392
|
payload: { text: string; attachments: AiAttachment[] },
|
|
370
393
|
) => {
|
|
371
394
|
let task: StreamTask | undefined
|
|
372
|
-
const request = {
|
|
395
|
+
const request = {
|
|
396
|
+
session_id: sessionID,
|
|
397
|
+
content: payload.text,
|
|
398
|
+
provider_id: selectedProviderId,
|
|
399
|
+
model_name: selectedModelName,
|
|
400
|
+
attachments: payload.attachments,
|
|
401
|
+
action: undefined,
|
|
402
|
+
}
|
|
373
403
|
try {
|
|
374
404
|
let handledByStream = false
|
|
375
405
|
if (process.env.TARO_ENV === 'weapp') {
|
|
@@ -719,6 +749,11 @@ export default function AiPage() {
|
|
|
719
749
|
<Composer
|
|
720
750
|
value={inputText}
|
|
721
751
|
attachments={selectedAttachments}
|
|
752
|
+
modelProviders={modelProviders}
|
|
753
|
+
providerId={selectedProviderId}
|
|
754
|
+
modelName={selectedModelName}
|
|
755
|
+
providerPlaceholder={t('system.ai.model.provider_placeholder')}
|
|
756
|
+
modelPlaceholder={t('system.ai.model.model_placeholder')}
|
|
722
757
|
placeholder={composerPlaceholder}
|
|
723
758
|
bottom={composerBottom}
|
|
724
759
|
recording={isRecording}
|
|
@@ -736,6 +771,7 @@ export default function AiPage() {
|
|
|
736
771
|
})
|
|
737
772
|
}}
|
|
738
773
|
onSend={() => void handleSend()}
|
|
774
|
+
onModelChange={handleModelChange}
|
|
739
775
|
onRemoveAttachment={(attachment) => setSelectedAttachments((current) => current.filter((item) => item !== attachment))}
|
|
740
776
|
/>
|
|
741
777
|
<SessionDrawer
|
|
@@ -758,6 +794,7 @@ export default function AiPage() {
|
|
|
758
794
|
function normalizeSession(session?: Partial<AiSession> | null): AiSession {
|
|
759
795
|
return {
|
|
760
796
|
id: String(session?.id ?? ''),
|
|
797
|
+
tenant_id: Number(session?.tenant_id ?? 0),
|
|
761
798
|
title: String(session?.title ?? t('system.ai.new_session')),
|
|
762
799
|
summary: String(session?.summary ?? ''),
|
|
763
800
|
updated_at: session?.updated_at,
|
|
@@ -848,6 +885,7 @@ function createLocalUserMessage(payload: { text: string; attachments: AiAttachme
|
|
|
848
885
|
const now = Date.now()
|
|
849
886
|
const message = mapMessageItem({
|
|
850
887
|
id: `${LOCAL_USER_MESSAGE_PREFIX}-${now}`,
|
|
888
|
+
tenant_id: 0,
|
|
851
889
|
input_content: { kind: 'text', content: payload.text },
|
|
852
890
|
output_content: undefined,
|
|
853
891
|
attachments: payload.attachments,
|
|
@@ -869,8 +907,9 @@ function createThinkingMessage(options?: { sessionID?: string; messageID?: strin
|
|
|
869
907
|
? buildStreamMessageKey(options.sessionID, options.messageID || PENDING_MESSAGE_ID)
|
|
870
908
|
: undefined
|
|
871
909
|
const message = mapMessageItem({
|
|
872
|
-
|
|
873
|
-
|
|
910
|
+
id: streamKey || `ai-thinking-${now}`,
|
|
911
|
+
tenant_id: 0,
|
|
912
|
+
input_content: undefined,
|
|
874
913
|
output_content: {
|
|
875
914
|
kind: 'text', content: t('system.ai.thinking'), reply_source: '', model: '', fallback: false,
|
|
876
915
|
fallback_reason: '', flow: '', step: '', blocks_json: '',
|
|
@@ -997,7 +1036,7 @@ function formatAttachmentMeta(attachment: AiAttachment) {
|
|
|
997
1036
|
}
|
|
998
1037
|
|
|
999
1038
|
function formatTools(tools: AiToolCall[]) {
|
|
1000
|
-
return tools.map((item) => item.title || item.name).filter(Boolean).join(' · ')
|
|
1039
|
+
return tools.map((item) => (item.name === 'web_search' ? t('system.ai.web_search') : item.title || item.name)).filter(Boolean).join(' · ')
|
|
1001
1040
|
}
|
|
1002
1041
|
|
|
1003
1042
|
function showError(error: unknown, fallback: string) {
|
|
@@ -25,6 +25,13 @@ export default function MessageDetailPage() {
|
|
|
25
25
|
if (!value.read_at) await defNotificationService.MarkNotificationRead({ ids: [id] })
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
function resolveSenderName(value?: string) {
|
|
29
|
+
if (value === '系统' || value === '__I18N__:system.notification.sender.system') {
|
|
30
|
+
return t('system.notification.sender.system')
|
|
31
|
+
}
|
|
32
|
+
return value || ''
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
/** 执行通知携带的稳定 viewKey 动作。 */
|
|
29
36
|
function openAction() {
|
|
30
37
|
if (!detail || detail.action_type !== MessageActionType.MESSAGE_ACTION_TYPE_VIEW_KEY) return
|
|
@@ -60,7 +67,7 @@ export default function MessageDetailPage() {
|
|
|
60
67
|
/>
|
|
61
68
|
<Text>{detail.category_name}</Text>
|
|
62
69
|
</View>
|
|
63
|
-
<Text>{detail.sender_name}</Text>
|
|
70
|
+
<Text>{resolveSenderName(detail.sender_name)}</Text>
|
|
64
71
|
<Text>{detail.received_at}</Text>
|
|
65
72
|
</View>
|
|
66
73
|
{detail.content_format === MessageContentFormat.MESSAGE_CONTENT_FORMAT_RICH_TEXT ? (
|