@liujitcn/kratos-admin-system 0.0.65 → 0.0.66
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 +5 -3
- package/dist/package/declarations/src/api/base/v1/ai_knowledge.d.ts +7 -0
- package/dist/package/declarations/src/api/system/admin/v1/ai_provider.d.ts +3 -1
- package/dist/package/declarations/src/api/system/admin/v1/ai_query.d.ts +10 -0
- package/dist/package/declarations/src/api/system/admin/v1/ai_session.d.ts +9 -0
- package/dist/package/declarations/src/locales/generated.d.ts +1801 -1553
- package/dist/package/declarations/src/rpc/base/v1/ai_knowledge.d.ts +22 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_message.d.ts +2 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/ai_provider.d.ts +63 -5
- package/dist/package/declarations/src/rpc/system/admin/v1/ai_query.d.ts +73 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/ai_session.d.ts +114 -0
- package/dist/package/declarations/src/views/ai/chat/components/ChatPanel.vue.d.ts +9 -2
- package/dist/package/declarations/src/views/ai/chat/components/XSender.vue.d.ts +7 -0
- package/dist/package/declarations/src/views/ai/query/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/ai/session/index.vue.d.ts +3 -0
- package/dist/package/src/api/base/v1/ai_knowledge.ts +22 -0
- package/dist/package/src/api/system/admin/v1/ai_provider.ts +7 -0
- package/dist/package/src/api/system/admin/v1/ai_query.ts +25 -0
- package/dist/package/src/api/system/admin/v1/ai_session.ts +25 -0
- package/dist/package/src/components/account/ChangePasswordForm.vue +1 -1
- package/dist/package/src/components/tenant-project/TenantProjectSelect.vue +21 -4
- package/dist/package/src/locales/en-US.json +354 -292
- package/dist/package/src/locales/ja-JP.json +351 -289
- package/dist/package/src/locales/zh-CN.json +351 -289
- package/dist/package/src/locales/zh-TW.json +351 -289
- package/dist/package/src/rpc/base/v1/ai_knowledge.ts +33 -0
- package/dist/package/src/rpc/base/v1/ai_message.ts +2 -0
- package/dist/package/src/rpc/system/admin/v1/ai_provider.ts +68 -5
- package/dist/package/src/rpc/system/admin/v1/ai_query.ts +89 -0
- package/dist/package/src/rpc/system/admin/v1/ai_session.ts +131 -0
- package/dist/package/src/views/ai/chat/components/ChatPanel.vue +18 -0
- package/dist/package/src/views/ai/chat/components/XSender.vue +101 -0
- package/dist/package/src/views/ai/chat/index.vue +22 -2
- package/dist/package/src/views/ai/query/index.vue +222 -0
- package/dist/package/src/views/ai/session/index.vue +422 -0
- package/dist/package/src/views/base/ai-provider/index.vue +201 -155
- package/dist/package/src/views/base/message-provider/index.vue +2 -2
- package/dist/package/src/views/base/oauth-provider/index.vue +2 -2
- package/dist/package/src/views/base/tenant-project-grant/index.vue +9 -4
- package/dist/package/src/views/tool/code-gen/config.ts +1 -0
- package/package.json +2 -2
|
@@ -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_knowledge.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
|
|
9
|
+
/** AI知识库选项查询请求。 */
|
|
10
|
+
export interface ListAiKnowledgeOptionsRequest {
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** AI知识库选项查询响应。 */
|
|
14
|
+
export interface ListAiKnowledgeOptionsResponse {
|
|
15
|
+
/** 知识库选项列表 */
|
|
16
|
+
options: AiKnowledgeOption[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** AI知识库选项。 */
|
|
20
|
+
export interface AiKnowledgeOption {
|
|
21
|
+
/** 知识库ID */
|
|
22
|
+
id: number;
|
|
23
|
+
/** 知识库名称 */
|
|
24
|
+
name: string;
|
|
25
|
+
/** 文档数量 */
|
|
26
|
+
doc_count: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** AI 知识库选项查询服务。 */
|
|
30
|
+
export interface AiKnowledgeService {
|
|
31
|
+
/** 查询可用的AI知识库选项。 */
|
|
32
|
+
ListAiKnowledgeOptions(request: ListAiKnowledgeOptionsRequest): Promise<ListAiKnowledgeOptionsResponse>;
|
|
33
|
+
}
|
|
@@ -8,6 +8,24 @@
|
|
|
8
8
|
import type { Status } from "../../../common/v1/enum";
|
|
9
9
|
import type { Empty } from "../../../google/protobuf/empty";
|
|
10
10
|
|
|
11
|
+
/** AI模型分类枚举。 */
|
|
12
|
+
export enum AiModelCategory {
|
|
13
|
+
/** AI_MODEL_CATEGORY_UNSPECIFIED - 未指定AI模型分类。 */
|
|
14
|
+
AI_MODEL_CATEGORY_UNSPECIFIED = 0,
|
|
15
|
+
/** AI_MODEL_CATEGORY_CHAT - 对话模型。 */
|
|
16
|
+
AI_MODEL_CATEGORY_CHAT = 1,
|
|
17
|
+
/** AI_MODEL_CATEGORY_EMBEDDING - 向量模型。 */
|
|
18
|
+
AI_MODEL_CATEGORY_EMBEDDING = 2,
|
|
19
|
+
/** AI_MODEL_CATEGORY_RERANK - 重排序模型。 */
|
|
20
|
+
AI_MODEL_CATEGORY_RERANK = 3,
|
|
21
|
+
/** AI_MODEL_CATEGORY_IMAGE - 图片模型。 */
|
|
22
|
+
AI_MODEL_CATEGORY_IMAGE = 4,
|
|
23
|
+
/** AI_MODEL_CATEGORY_VIDEO - 视频模型。 */
|
|
24
|
+
AI_MODEL_CATEGORY_VIDEO = 5,
|
|
25
|
+
/** AI_MODEL_CATEGORY_AUDIO - 音频模型。 */
|
|
26
|
+
AI_MODEL_CATEGORY_AUDIO = 6,
|
|
27
|
+
}
|
|
28
|
+
|
|
11
29
|
/** AI供应商分页查询条件。 */
|
|
12
30
|
export interface PageAiProviderRequest {
|
|
13
31
|
/** 供应商名称 */
|
|
@@ -48,8 +66,6 @@ export interface AiProviderForm {
|
|
|
48
66
|
api_key: string;
|
|
49
67
|
/** 是否已保存模型密钥 */
|
|
50
68
|
api_key_configured: boolean;
|
|
51
|
-
/** 多模型JSON数组 */
|
|
52
|
-
models_json: string;
|
|
53
69
|
/** 排序值 */
|
|
54
70
|
sort: number;
|
|
55
71
|
/** Provider稳定标识 */
|
|
@@ -58,6 +74,28 @@ export interface AiProviderForm {
|
|
|
58
74
|
config:
|
|
59
75
|
| { [key: string]: any }
|
|
60
76
|
| undefined;
|
|
77
|
+
/** 供应商下的AI模型列表 */
|
|
78
|
+
models: AiProviderModelForm[];
|
|
79
|
+
/** 状态 */
|
|
80
|
+
status: Status;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** AI供应商模型维护表单;provider_id由所属供应商表单隐式给定。 */
|
|
84
|
+
export interface AiProviderModelForm {
|
|
85
|
+
/** 模型ID;新增时为0 */
|
|
86
|
+
id: number;
|
|
87
|
+
/** 模型名称,供应商API标识 */
|
|
88
|
+
model_name: string;
|
|
89
|
+
/** 显示名称 */
|
|
90
|
+
display_name: string;
|
|
91
|
+
/** 模型分类:枚举【AiModelCategory】 */
|
|
92
|
+
category: AiModelCategory;
|
|
93
|
+
/** 分类个性化配置JSON对象 */
|
|
94
|
+
config:
|
|
95
|
+
| { [key: string]: any }
|
|
96
|
+
| undefined;
|
|
97
|
+
/** 排序值 */
|
|
98
|
+
sort: number;
|
|
61
99
|
/** 状态 */
|
|
62
100
|
status: Status;
|
|
63
101
|
}
|
|
@@ -74,7 +112,7 @@ export interface UpdateAiProviderRequest {
|
|
|
74
112
|
ai_provider: AiProviderForm | undefined;
|
|
75
113
|
}
|
|
76
114
|
|
|
77
|
-
/** 测试AI
|
|
115
|
+
/** 测试AI供应商模型请求。 */
|
|
78
116
|
export interface TestAiProviderModelsRequest {
|
|
79
117
|
/** 待测试的AI供应商草稿 */
|
|
80
118
|
ai_provider: AiProviderForm | undefined;
|
|
@@ -98,6 +136,26 @@ export interface TestAiProviderModelsResponse {
|
|
|
98
136
|
results: AiProviderModelTestResult[];
|
|
99
137
|
}
|
|
100
138
|
|
|
139
|
+
/** 查询AI供应商选项请求。 */
|
|
140
|
+
export interface ListAiProviderOptionsRequest {
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** 查询AI供应商选项响应。 */
|
|
144
|
+
export interface ListAiProviderOptionsResponse {
|
|
145
|
+
/** 已启用的AI供应商列表 */
|
|
146
|
+
options: AiProviderOption[];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** AI供应商选项。 */
|
|
150
|
+
export interface AiProviderOption {
|
|
151
|
+
/** 供应商ID */
|
|
152
|
+
id: number;
|
|
153
|
+
/** 供应商名称 */
|
|
154
|
+
name: string;
|
|
155
|
+
/** Provider稳定标识 */
|
|
156
|
+
provider: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
101
159
|
/** 删除AI供应商请求。 */
|
|
102
160
|
export interface DeleteAiProviderRequest {
|
|
103
161
|
/** 供应商ID */
|
|
@@ -122,12 +180,12 @@ export interface AiProvider {
|
|
|
122
180
|
base_url: string;
|
|
123
181
|
/** 是否已保存模型密钥 */
|
|
124
182
|
api_key_configured: boolean;
|
|
125
|
-
/** 模型名称列表 */
|
|
126
|
-
model_names: string[];
|
|
127
183
|
/** 排序值 */
|
|
128
184
|
sort: number;
|
|
129
185
|
/** Provider稳定标识 */
|
|
130
186
|
provider: string;
|
|
187
|
+
/** 供应商下的模型名称列表 */
|
|
188
|
+
model_names: string[];
|
|
131
189
|
/** 状态 */
|
|
132
190
|
status: Status;
|
|
133
191
|
/** 创建时间 */
|
|
@@ -140,6 +198,11 @@ export interface AiProvider {
|
|
|
140
198
|
export interface AiProviderService {
|
|
141
199
|
/** 分页查询AI供应商。 */
|
|
142
200
|
PageAiProvider(request: PageAiProviderRequest): Promise<PageAiProviderResponse>;
|
|
201
|
+
/**
|
|
202
|
+
* 查询已启用的AI供应商选项。
|
|
203
|
+
* 字面路径必须先于 /{id} 声明:gorilla mux 按注册顺序匹配,否则会被 {id} 路由抢占。
|
|
204
|
+
*/
|
|
205
|
+
ListAiProviderOptions(request: ListAiProviderOptionsRequest): Promise<ListAiProviderOptionsResponse>;
|
|
143
206
|
/** 查询AI供应商表单。 */
|
|
144
207
|
GetAiProvider(request: GetAiProviderRequest): Promise<AiProviderForm>;
|
|
145
208
|
/** 创建AI供应商。 */
|
|
@@ -0,0 +1,89 @@
|
|
|
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: system/admin/v1/ai_query.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
|
|
9
|
+
/** 智能问数状态枚举。 */
|
|
10
|
+
export enum AiQueryStatus {
|
|
11
|
+
/** AI_QUERY_STATUS_UNSPECIFIED - 未指定智能问数状态。 */
|
|
12
|
+
AI_QUERY_STATUS_UNSPECIFIED = 0,
|
|
13
|
+
/** AI_QUERY_STATUS_SUCCESS - 成功。 */
|
|
14
|
+
AI_QUERY_STATUS_SUCCESS = 1,
|
|
15
|
+
/** AI_QUERY_STATUS_FAILED - 失败。 */
|
|
16
|
+
AI_QUERY_STATUS_FAILED = 2,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 智能问数分页查询条件。 */
|
|
20
|
+
export interface PageAiQueryRequest {
|
|
21
|
+
/** 问题内容 */
|
|
22
|
+
question: string;
|
|
23
|
+
/** 问数状态:枚举【AiQueryStatus】 */
|
|
24
|
+
status?:
|
|
25
|
+
| AiQueryStatus
|
|
26
|
+
| undefined;
|
|
27
|
+
/** 当前页码 */
|
|
28
|
+
page_num: number;
|
|
29
|
+
/** 每页行数 */
|
|
30
|
+
page_size: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** 智能问数分页响应。 */
|
|
34
|
+
export interface PageAiQueryResponse {
|
|
35
|
+
/** 智能问数记录列表 */
|
|
36
|
+
queries: AiQueryRecord[];
|
|
37
|
+
/** 总数 */
|
|
38
|
+
total: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** 查询智能问数记录请求。 */
|
|
42
|
+
export interface GetAiQueryRequest {
|
|
43
|
+
/** 记录ID */
|
|
44
|
+
id: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** 智能问数结果快照行。 */
|
|
48
|
+
export interface AiQueryResultRow {
|
|
49
|
+
/** 行数据 */
|
|
50
|
+
values: string[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 智能问数记录。 */
|
|
54
|
+
export interface AiQueryRecord {
|
|
55
|
+
/** 记录ID */
|
|
56
|
+
id: number;
|
|
57
|
+
/** 租户ID */
|
|
58
|
+
tenant_id: number;
|
|
59
|
+
/** 用户ID */
|
|
60
|
+
user_id: number;
|
|
61
|
+
/** 用户账号 */
|
|
62
|
+
user_name: string;
|
|
63
|
+
/** 自然语言问题 */
|
|
64
|
+
question: string;
|
|
65
|
+
/** 生成的只读SQL */
|
|
66
|
+
sql: string;
|
|
67
|
+
/** 问数状态:枚举【AiQueryStatus】 */
|
|
68
|
+
status: AiQueryStatus;
|
|
69
|
+
/** 结果行数 */
|
|
70
|
+
row_count: number;
|
|
71
|
+
/** SQL执行耗时毫秒 */
|
|
72
|
+
elapsed_ms: number;
|
|
73
|
+
/** 失败原因 */
|
|
74
|
+
error_msg: string;
|
|
75
|
+
/** 结果快照列名,仅详情返回 */
|
|
76
|
+
result_columns: string[];
|
|
77
|
+
/** 结果快照数据行,仅详情返回 */
|
|
78
|
+
result_rows: AiQueryResultRow[];
|
|
79
|
+
/** 创建时间 */
|
|
80
|
+
created_at: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** 智能问数记录管理服务。 */
|
|
84
|
+
export interface AiQueryService {
|
|
85
|
+
/** 分页查询智能问数记录。 */
|
|
86
|
+
PageAiQuery(request: PageAiQueryRequest): Promise<PageAiQueryResponse>;
|
|
87
|
+
/** 查询智能问数记录详情。 */
|
|
88
|
+
GetAiQuery(request: GetAiQueryRequest): Promise<AiQueryRecord>;
|
|
89
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
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: system/admin/v1/ai_session.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
import type { AiMessageStatus } from "../../../base/v1/ai_session";
|
|
9
|
+
import type { Terminal } from "../../../base/v1/ai_tool";
|
|
10
|
+
|
|
11
|
+
/** AI会话分页查询条件。 */
|
|
12
|
+
export interface PageAiSessionRequest {
|
|
13
|
+
/** 会话标题 */
|
|
14
|
+
title: string;
|
|
15
|
+
/** 终端类型:枚举【Terminal】 */
|
|
16
|
+
terminal?:
|
|
17
|
+
| Terminal
|
|
18
|
+
| undefined;
|
|
19
|
+
/** 当前页码 */
|
|
20
|
+
page_num: number;
|
|
21
|
+
/** 每页行数 */
|
|
22
|
+
page_size: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** AI会话分页响应。 */
|
|
26
|
+
export interface PageAiSessionResponse {
|
|
27
|
+
/** 会话列表 */
|
|
28
|
+
sessions: AiSessionRecord[];
|
|
29
|
+
/** 总数 */
|
|
30
|
+
total: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** AI会话分页记录。 */
|
|
34
|
+
export interface AiSessionRecord {
|
|
35
|
+
/** 会话ID */
|
|
36
|
+
id: number;
|
|
37
|
+
/** 所属用户ID */
|
|
38
|
+
user_id: number;
|
|
39
|
+
/** 用户账号 */
|
|
40
|
+
user_name: string;
|
|
41
|
+
/** 用户昵称 */
|
|
42
|
+
nick_name: string;
|
|
43
|
+
/** 会话标题 */
|
|
44
|
+
title: string;
|
|
45
|
+
/** 会话摘要 */
|
|
46
|
+
summary: string;
|
|
47
|
+
/** 终端类型:枚举【Terminal】 */
|
|
48
|
+
terminal: Terminal;
|
|
49
|
+
/** 消息轮次数 */
|
|
50
|
+
message_count: number;
|
|
51
|
+
/** 累计输入Token数 */
|
|
52
|
+
input_tokens: number;
|
|
53
|
+
/** 累计输出Token数 */
|
|
54
|
+
output_tokens: number;
|
|
55
|
+
/** 累计缓存Token数 */
|
|
56
|
+
cache_tokens: number;
|
|
57
|
+
/** 累计总Token数 */
|
|
58
|
+
total_tokens: number;
|
|
59
|
+
/** 创建时间 */
|
|
60
|
+
created_at: string;
|
|
61
|
+
/** 更新时间 */
|
|
62
|
+
updated_at: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** 分页查询AI会话消息请求。 */
|
|
66
|
+
export interface PageAiSessionMessageRequest {
|
|
67
|
+
/** 会话ID */
|
|
68
|
+
id: number;
|
|
69
|
+
/** 当前页码 */
|
|
70
|
+
page_num: number;
|
|
71
|
+
/** 每页行数 */
|
|
72
|
+
page_size: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** 分页查询AI会话消息响应。 */
|
|
76
|
+
export interface PageAiSessionMessageResponse {
|
|
77
|
+
/** 消息列表 */
|
|
78
|
+
messages: AiSessionMessageRecord[];
|
|
79
|
+
/** 总数 */
|
|
80
|
+
total: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** AI会话消息记录。 */
|
|
84
|
+
export interface AiSessionMessageRecord {
|
|
85
|
+
/** 消息ID */
|
|
86
|
+
id: number;
|
|
87
|
+
/** 用户输入内容 */
|
|
88
|
+
input_content: string;
|
|
89
|
+
/** AI回复内容 */
|
|
90
|
+
output_content: string;
|
|
91
|
+
/** 回复使用的模型名称 */
|
|
92
|
+
model: string;
|
|
93
|
+
/** 消息生成状态:枚举【AiMessageStatus】 */
|
|
94
|
+
status: AiMessageStatus;
|
|
95
|
+
/** 输入Token数 */
|
|
96
|
+
input_tokens: number;
|
|
97
|
+
/** 输出Token数 */
|
|
98
|
+
output_tokens: number;
|
|
99
|
+
/** 缓存Token数 */
|
|
100
|
+
cache_tokens: number;
|
|
101
|
+
/** 总Token数 */
|
|
102
|
+
total_tokens: number;
|
|
103
|
+
/** 首Token耗时毫秒 */
|
|
104
|
+
first_token_ms: number;
|
|
105
|
+
/** 总耗时毫秒 */
|
|
106
|
+
duration_ms: number;
|
|
107
|
+
/** 附件列表 */
|
|
108
|
+
attachments: AiSessionMessageAttachment[];
|
|
109
|
+
/** 创建时间 */
|
|
110
|
+
created_at: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** AI会话消息附件。 */
|
|
114
|
+
export interface AiSessionMessageAttachment {
|
|
115
|
+
/** 附件名称 */
|
|
116
|
+
name: string;
|
|
117
|
+
/** 附件大小 */
|
|
118
|
+
size: number;
|
|
119
|
+
/** 附件地址 */
|
|
120
|
+
url: string;
|
|
121
|
+
/** 附件 MIME 类型 */
|
|
122
|
+
mime_type: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** AI会话管理服务。 */
|
|
126
|
+
export interface AiSessionService {
|
|
127
|
+
/** 分页查询AI会话。 */
|
|
128
|
+
PageAiSession(request: PageAiSessionRequest): Promise<PageAiSessionResponse>;
|
|
129
|
+
/** 分页查询AI会话消息。 */
|
|
130
|
+
PageAiSessionMessage(request: PageAiSessionMessageRequest): Promise<PageAiSessionMessageResponse>;
|
|
131
|
+
}
|
|
@@ -53,8 +53,11 @@
|
|
|
53
53
|
:model-providers="modelProviders"
|
|
54
54
|
:provider-id="providerId"
|
|
55
55
|
:model-name="modelName"
|
|
56
|
+
:knowledge-options="knowledgeOptions"
|
|
57
|
+
:knowledge-ids="knowledgeIds"
|
|
56
58
|
@submit="handleSubmit"
|
|
57
59
|
@model-change="handleModelChange"
|
|
60
|
+
@knowledge-change="handleKnowledgeChange"
|
|
58
61
|
/>
|
|
59
62
|
</div>
|
|
60
63
|
</div>
|
|
@@ -336,8 +339,11 @@
|
|
|
336
339
|
:model-providers="modelProviders"
|
|
337
340
|
:provider-id="providerId"
|
|
338
341
|
:model-name="modelName"
|
|
342
|
+
:knowledge-options="knowledgeOptions"
|
|
343
|
+
:knowledge-ids="knowledgeIds"
|
|
339
344
|
@submit="handleSubmit"
|
|
340
345
|
@model-change="handleModelChange"
|
|
346
|
+
@knowledge-change="handleKnowledgeChange"
|
|
341
347
|
/>
|
|
342
348
|
</div>
|
|
343
349
|
</template>
|
|
@@ -356,6 +362,7 @@ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
|
|
|
356
362
|
import type { AiAction } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_message";
|
|
357
363
|
import { type AiAttachment, type AiSession } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
|
|
358
364
|
import type { AiProviderModelOption } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_provider";
|
|
365
|
+
import type { AiKnowledgeOption } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_knowledge";
|
|
359
366
|
import type { AiShortcut, AiToolCall } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
|
|
360
367
|
import { AiMessageStatus } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
|
|
361
368
|
import { resolvePersistedMessage } from "../../../../utils/persisted-message";
|
|
@@ -501,6 +508,10 @@ const props = defineProps<{
|
|
|
501
508
|
providerId: number;
|
|
502
509
|
/** 当前选择的模型名称。 */
|
|
503
510
|
modelName: string;
|
|
511
|
+
/** 当前可供选择的知识库。 */
|
|
512
|
+
knowledgeOptions: AiKnowledgeOption[];
|
|
513
|
+
/** 当前选择的知识库编号列表。 */
|
|
514
|
+
knowledgeIds: number[];
|
|
504
515
|
}>();
|
|
505
516
|
|
|
506
517
|
const emit = defineEmits<{
|
|
@@ -508,6 +519,8 @@ const emit = defineEmits<{
|
|
|
508
519
|
submit: [payload: SubmitPayload];
|
|
509
520
|
/** 更新当前选择的供应商和模型。 */
|
|
510
521
|
modelChange: [providerId: number, modelName: string];
|
|
522
|
+
/** 更新当前选择的知识库编号列表。 */
|
|
523
|
+
knowledgeChange: [knowledgeIds: number[]];
|
|
511
524
|
/** 触发消息级操作。 */
|
|
512
525
|
messageAction: [payload: { action: ChatMessageAction; item: ChatMessageItem }];
|
|
513
526
|
/** 提交当前用户消息的文本编辑。 */
|
|
@@ -648,6 +661,11 @@ function handleModelChange(providerId: number, modelName: string) {
|
|
|
648
661
|
emit("modelChange", providerId, modelName);
|
|
649
662
|
}
|
|
650
663
|
|
|
664
|
+
/** 更新当前选择的知识库编号列表。 */
|
|
665
|
+
function handleKnowledgeChange(knowledgeIds: number[]) {
|
|
666
|
+
emit("knowledgeChange", knowledgeIds);
|
|
667
|
+
}
|
|
668
|
+
|
|
651
669
|
/** 点击快捷入口时提交对应入口动作。 */
|
|
652
670
|
function handleShortcutClick(shortcut: AiShortcut) {
|
|
653
671
|
emit("submit", {
|
|
@@ -126,6 +126,72 @@
|
|
|
126
126
|
{{ t("system.ai.model.empty") }}
|
|
127
127
|
</div>
|
|
128
128
|
</el-popover>
|
|
129
|
+
<el-popover
|
|
130
|
+
ref="knowledgePopoverRef"
|
|
131
|
+
placement="top-start"
|
|
132
|
+
:width="324"
|
|
133
|
+
trigger="click"
|
|
134
|
+
:show-arrow="false"
|
|
135
|
+
:persistent="false"
|
|
136
|
+
popper-class="agent-model-popper"
|
|
137
|
+
>
|
|
138
|
+
<template #reference>
|
|
139
|
+
<button
|
|
140
|
+
class="agent-model-selector"
|
|
141
|
+
:class="{ 'is-disabled': sending || !knowledgeOptions.length, 'is-selected': selectedKnowledgeCount > 0 }"
|
|
142
|
+
type="button"
|
|
143
|
+
:disabled="sending || !knowledgeOptions.length"
|
|
144
|
+
:aria-label="t('system.ai.knowledge.title')"
|
|
145
|
+
>
|
|
146
|
+
<el-icon class="agent-model-selector__spark"><Collection /></el-icon>
|
|
147
|
+
<span class="agent-model-selector__label">{{
|
|
148
|
+
selectedKnowledgeCount > 0
|
|
149
|
+
? t("system.ai.knowledge.selected_count", { count: selectedKnowledgeCount })
|
|
150
|
+
: t("system.ai.knowledge.title")
|
|
151
|
+
}}</span>
|
|
152
|
+
<el-icon class="agent-model-selector__arrow"><ArrowDown /></el-icon>
|
|
153
|
+
</button>
|
|
154
|
+
</template>
|
|
155
|
+
<div v-if="knowledgeOptions.length" class="agent-model-panel">
|
|
156
|
+
<div class="agent-model-panel__head">
|
|
157
|
+
<span class="agent-model-panel__title">{{ t("system.ai.knowledge.title") }}</span>
|
|
158
|
+
<span class="agent-model-panel__meta">{{
|
|
159
|
+
t("system.ai.knowledge.select_hint")
|
|
160
|
+
}}</span>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="agent-model-panel__list">
|
|
163
|
+
<button
|
|
164
|
+
v-for="option in knowledgeOptions"
|
|
165
|
+
:key="option.id"
|
|
166
|
+
class="agent-model-row"
|
|
167
|
+
:class="{ 'is-selected': isKnowledgeSelected(option.id) }"
|
|
168
|
+
type="button"
|
|
169
|
+
@click="handleKnowledgeToggle(option.id)"
|
|
170
|
+
>
|
|
171
|
+
<span class="agent-model-row__name">{{ option.name }}</span>
|
|
172
|
+
<span v-if="option.doc_count" class="agent-model-row__raw">{{
|
|
173
|
+
t("system.ai.knowledge.doc_count", { count: option.doc_count })
|
|
174
|
+
}}</span>
|
|
175
|
+
<el-icon v-if="isKnowledgeSelected(option.id)" class="agent-model-row__check">
|
|
176
|
+
<Check />
|
|
177
|
+
</el-icon>
|
|
178
|
+
</button>
|
|
179
|
+
</div>
|
|
180
|
+
<button
|
|
181
|
+
v-if="aiKnowledgeRoute"
|
|
182
|
+
class="agent-model-panel__manage"
|
|
183
|
+
type="button"
|
|
184
|
+
@click="openKnowledgeManage"
|
|
185
|
+
>
|
|
186
|
+
<el-icon><Setting /></el-icon>
|
|
187
|
+
<span>{{ t("system.ai.knowledge.manage") }}</span>
|
|
188
|
+
<el-icon class="agent-model-panel__manage-arrow"><ArrowRight /></el-icon>
|
|
189
|
+
</button>
|
|
190
|
+
</div>
|
|
191
|
+
<div v-else class="agent-model-panel agent-model-panel--empty">
|
|
192
|
+
{{ t("system.ai.knowledge.empty") }}
|
|
193
|
+
</div>
|
|
194
|
+
</el-popover>
|
|
129
195
|
<el-tooltip
|
|
130
196
|
:content="recording ? t('system.ai.chat.action.stop_voice_input') : t('system.ai.chat.action.voice_input')"
|
|
131
197
|
placement="top"
|
|
@@ -181,6 +247,7 @@ import {
|
|
|
181
247
|
ArrowDown,
|
|
182
248
|
ArrowRight,
|
|
183
249
|
Check,
|
|
250
|
+
Collection,
|
|
184
251
|
Loading,
|
|
185
252
|
MagicStick,
|
|
186
253
|
Microphone,
|
|
@@ -195,6 +262,7 @@ import { useAuthStore } from "@liujitcn/kratos-admin-core/stores/runtime";
|
|
|
195
262
|
import { defFileService } from "@liujitcn/kratos-admin-core/api/base/v1/file";
|
|
196
263
|
import type { AiAttachment } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
|
|
197
264
|
import type { AiProviderModelOption } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_provider";
|
|
265
|
+
import type { AiKnowledgeOption } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_knowledge";
|
|
198
266
|
import type { SubmitPayload } from "../types";
|
|
199
267
|
import { buildAIAttachmentFileCard } from "../attachment";
|
|
200
268
|
import { fallbackModelDisplayName } from "../modelDisplay";
|
|
@@ -210,6 +278,10 @@ const props = defineProps<{
|
|
|
210
278
|
providerId: number;
|
|
211
279
|
/** 当前选择的模型名称。 */
|
|
212
280
|
modelName: string;
|
|
281
|
+
/** 当前可供选择的知识库。 */
|
|
282
|
+
knowledgeOptions: AiKnowledgeOption[];
|
|
283
|
+
/** 当前选择的知识库编号列表。 */
|
|
284
|
+
knowledgeIds: number[];
|
|
213
285
|
}>();
|
|
214
286
|
|
|
215
287
|
const emit = defineEmits<{
|
|
@@ -217,6 +289,8 @@ const emit = defineEmits<{
|
|
|
217
289
|
submit: [payload: SubmitPayload];
|
|
218
290
|
/** 更新当前选择的供应商和模型。 */
|
|
219
291
|
"model-change": [providerId: number, modelName: string];
|
|
292
|
+
/** 更新当前选择的知识库编号列表。 */
|
|
293
|
+
"knowledge-change": [knowledgeIds: number[]];
|
|
220
294
|
}>();
|
|
221
295
|
|
|
222
296
|
const senderRef = ref<InstanceType<typeof BaseXSender>>();
|
|
@@ -249,6 +323,9 @@ const selectedModelDisplayName = computed(() => {
|
|
|
249
323
|
const aiProviderRoute = computed(() =>
|
|
250
324
|
authStore.flatMenuListGet.find(item => item.name === "AiProvider" && item.path)
|
|
251
325
|
);
|
|
326
|
+
const aiKnowledgeRoute = computed(() =>
|
|
327
|
+
authStore.flatMenuListGet.find(item => item.name === "AiKnowledge" && item.path)
|
|
328
|
+
);
|
|
252
329
|
const uploading = ref(false);
|
|
253
330
|
const maxAttachmentCount = 6;
|
|
254
331
|
const maxAttachmentSizeMB = 20;
|
|
@@ -323,6 +400,30 @@ async function openModelManage() {
|
|
|
323
400
|
await navigateTo(router, aiProviderRoute.value.path);
|
|
324
401
|
}
|
|
325
402
|
|
|
403
|
+
const knowledgePopoverRef = ref<InstanceType<typeof ElPopover>>();
|
|
404
|
+
|
|
405
|
+
const selectedKnowledgeCount = computed(() => props.knowledgeIds.length);
|
|
406
|
+
|
|
407
|
+
/** 判断知识库是否在当前选择中。 */
|
|
408
|
+
function isKnowledgeSelected(knowledgeId: number) {
|
|
409
|
+
return props.knowledgeIds.includes(knowledgeId);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/** 切换知识库选择状态并同步父组件。 */
|
|
413
|
+
function handleKnowledgeToggle(knowledgeId: number) {
|
|
414
|
+
const current = new Set(props.knowledgeIds);
|
|
415
|
+
if (current.has(knowledgeId)) current.delete(knowledgeId);
|
|
416
|
+
else current.add(knowledgeId);
|
|
417
|
+
emit("knowledge-change", [...current]);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/** 跳转到 AI 知识库管理页。 */
|
|
421
|
+
async function openKnowledgeManage() {
|
|
422
|
+
if (!aiKnowledgeRoute.value?.path) return;
|
|
423
|
+
knowledgePopoverRef.value?.hide();
|
|
424
|
+
await navigateTo(router, aiKnowledgeRoute.value.path);
|
|
425
|
+
}
|
|
426
|
+
|
|
326
427
|
/** 读取输入内容并发送给父组件。 */
|
|
327
428
|
function handleSubmit() {
|
|
328
429
|
if (uploading.value) return;
|
|
@@ -30,8 +30,11 @@
|
|
|
30
30
|
:model-providers="modelProviders"
|
|
31
31
|
:provider-id="selectedProviderId"
|
|
32
32
|
:model-name="selectedModelName"
|
|
33
|
+
:knowledge-options="knowledgeOptions"
|
|
34
|
+
:knowledge-ids="selectedKnowledgeIds"
|
|
33
35
|
@submit="handleSubmit"
|
|
34
36
|
@model-change="handleModelChange"
|
|
37
|
+
@knowledge-change="handleKnowledgeChange"
|
|
35
38
|
@message-action="handleMessageAction"
|
|
36
39
|
@message-edit="handleEditMessage"
|
|
37
40
|
>
|
|
@@ -59,9 +62,11 @@ import { defAiMessageService } from "@liujitcn/kratos-admin-system/api/base/v1/a
|
|
|
59
62
|
import { defAiSessionService } from "@liujitcn/kratos-admin-system/api/base/v1/ai_session";
|
|
60
63
|
import { defAiToolService } from "@liujitcn/kratos-admin-system/api/base/v1/ai_tool";
|
|
61
64
|
import { defAiModelService } from "@liujitcn/kratos-admin-system/api/base/v1/ai_provider";
|
|
65
|
+
import { defAiKnowledgeService } from "@liujitcn/kratos-admin-system/api/base/v1/ai_knowledge";
|
|
62
66
|
import type { AiAction } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_message";
|
|
63
67
|
import type { AiSession } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
|
|
64
68
|
import type { AiProviderModelOption } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_provider";
|
|
69
|
+
import type { AiKnowledgeOption } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_knowledge";
|
|
65
70
|
import type { AiShortcut } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
|
|
66
71
|
import { AiMessageStatus } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
|
|
67
72
|
import { Terminal } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
|
|
@@ -112,6 +117,8 @@ const starterShortcuts = ref<AiShortcut[]>([]);
|
|
|
112
117
|
const modelProviders = ref<AiProviderModelOption[]>([]);
|
|
113
118
|
const selectedProviderId = ref(0);
|
|
114
119
|
const selectedModelName = ref("");
|
|
120
|
+
const knowledgeOptions = ref<AiKnowledgeOption[]>([]);
|
|
121
|
+
const selectedKnowledgeIds = ref<number[]>([]);
|
|
115
122
|
const messages = ref<Record<string, ChatMessageItem[]>>({});
|
|
116
123
|
const pendingDeltaMap = new Map<string, AiStreamPayload>();
|
|
117
124
|
const runningStreamTaskMap = new Map<string, AiStreamTask>();
|
|
@@ -229,6 +236,7 @@ async function runAiStreamTask(sessionID: string, payload: SubmitPayload) {
|
|
|
229
236
|
content: payload.text,
|
|
230
237
|
provider_id: selectedProviderId.value,
|
|
231
238
|
model_name: selectedModelName.value,
|
|
239
|
+
knowledge_base_ids: selectedKnowledgeIds.value,
|
|
232
240
|
attachments: payload.attachments.map(item => ({
|
|
233
241
|
id: item.id,
|
|
234
242
|
name: item.name,
|
|
@@ -657,16 +665,23 @@ async function loadAiShortcuts() {
|
|
|
657
665
|
if (loadingShortcuts.value) return;
|
|
658
666
|
loadingShortcuts.value = true;
|
|
659
667
|
try {
|
|
660
|
-
const [response, providerResponse] = await Promise.all([
|
|
668
|
+
const [response, providerResponse, knowledgeResponse] = await Promise.all([
|
|
661
669
|
defAiToolService.ListAiShortcut({ terminal: Terminal.TERMINAL_ADMIN }),
|
|
662
|
-
defAiModelService.ListAiProviderModelOptions({})
|
|
670
|
+
defAiModelService.ListAiProviderModelOptions({}),
|
|
671
|
+
defAiKnowledgeService.ListAiKnowledgeOptions({})
|
|
663
672
|
]);
|
|
664
673
|
starterShortcuts.value = normalizeStarterShortcuts(response.shortcuts);
|
|
665
674
|
modelProviders.value = providerResponse.providers ?? [];
|
|
675
|
+
knowledgeOptions.value = knowledgeResponse.options ?? [];
|
|
676
|
+
// 知识库可能已被删除,剔除无效选择。
|
|
677
|
+
selectedKnowledgeIds.value = selectedKnowledgeIds.value.filter(id =>
|
|
678
|
+
knowledgeOptions.value.some(option => option.id === id)
|
|
679
|
+
);
|
|
666
680
|
applyModelSelection();
|
|
667
681
|
} catch {
|
|
668
682
|
starterShortcuts.value = [];
|
|
669
683
|
modelProviders.value = [];
|
|
684
|
+
knowledgeOptions.value = [];
|
|
670
685
|
selectedProviderId.value = 0;
|
|
671
686
|
selectedModelName.value = "";
|
|
672
687
|
} finally {
|
|
@@ -701,6 +716,11 @@ function handleModelChange(providerId: number, modelName: string) {
|
|
|
701
716
|
saveModelSelection({ provider_id: providerId, model_name: modelName });
|
|
702
717
|
}
|
|
703
718
|
|
|
719
|
+
/** 更新当前聊天检索注入的知识库选择。 */
|
|
720
|
+
function handleKnowledgeChange(knowledgeIds: number[]) {
|
|
721
|
+
selectedKnowledgeIds.value = knowledgeIds;
|
|
722
|
+
}
|
|
723
|
+
|
|
704
724
|
/** 使指定会话仍在途的消息列表请求失效。 */
|
|
705
725
|
function invalidateLoadMessages(sessionID: string) {
|
|
706
726
|
loadMessagesSeq.set(sessionID, (loadMessagesSeq.get(sessionID) ?? 0) + 1);
|