@kelvinjhu/lexiang-search 1.0.0 → 1.0.1
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 +46 -183
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -9
- package/dist/cli.js.map +1 -1
- package/dist/constants/api.constants.js +10 -13
- package/dist/constants/api.constants.js.map +1 -1
- package/dist/dto/ai-qa-request.dto.d.ts +8 -9
- package/dist/dto/ai-qa-request.dto.d.ts.map +1 -1
- package/dist/dto/ai-qa-request.dto.js +49 -62
- package/dist/dto/ai-qa-request.dto.js.map +1 -1
- package/dist/dto/ai-qa-response.dto.d.ts.map +1 -1
- package/dist/dto/ai-qa-response.dto.js +16 -20
- package/dist/dto/ai-qa-response.dto.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +57 -32
- package/dist/server.js.map +1 -1
- package/dist/services/ai-qa.service.d.ts +12 -3
- package/dist/services/ai-qa.service.d.ts.map +1 -1
- package/dist/services/ai-qa.service.js +60 -34
- package/dist/services/ai-qa.service.js.map +1 -1
- package/dist/services/lexiang-api.service.d.ts +6 -2
- package/dist/services/lexiang-api.service.d.ts.map +1 -1
- package/dist/services/lexiang-api.service.js +76 -57
- package/dist/services/lexiang-api.service.js.map +1 -1
- package/dist/tools/ai-qa-stream.tool.d.ts +1 -9
- package/dist/tools/ai-qa-stream.tool.d.ts.map +1 -1
- package/dist/tools/ai-qa-stream.tool.js +36 -71
- package/dist/tools/ai-qa-stream.tool.js.map +1 -1
- package/dist/tools/ai-qa.tool.d.ts +1 -9
- package/dist/tools/ai-qa.tool.d.ts.map +1 -1
- package/dist/tools/ai-qa.tool.js +11 -23
- package/dist/tools/ai-qa.tool.js.map +1 -1
- package/dist/types/lexiang-api.types.js +1 -2
- package/dist/types/lexiang-api.types.js.map +1 -1
- package/dist/types/mcp.types.js +1 -2
- package/dist/types/mcp.types.js.map +1 -1
- package/dist/utils/error-handler.d.ts +37 -32
- package/dist/utils/error-handler.d.ts.map +1 -1
- package/dist/utils/error-handler.js +46 -79
- package/dist/utils/error-handler.js.map +1 -1
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +6 -8
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/validator.d.ts +4 -15
- package/dist/utils/validator.d.ts.map +1 -1
- package/dist/utils/validator.js +17 -66
- package/dist/utils/validator.js.map +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -1,224 +1,87 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Lexiang Search MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@kelvinjhu/lexiang-search)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
这是一个基于 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 的服务器,允许 LLM (如 Claude) 直接访问腾讯乐享 (Lexiang) 知识库,进行智能问答和知识检索。
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
- ✅ 支持SSE流式实时问答
|
|
9
|
-
- ✅ 支持多轮对话上下文管理
|
|
10
|
-
- ✅ 支持多种问答模式(普通/深度思考/专业研究)
|
|
11
|
-
- ✅ 支持知识范围限制(团队/知识库/知识节点)
|
|
12
|
-
- ✅ 完整的TypeScript类型定义
|
|
13
|
-
- ✅ 严格的参数校验
|
|
8
|
+
## ✨ 功能特性
|
|
14
9
|
|
|
15
|
-
|
|
10
|
+
* **全站知识检索**: 支持对乐享全站、指定知识库 (Space) 或团队 (Team) 进行搜索。
|
|
11
|
+
* **智能问答**: 基于乐享 AI 引擎,提供精准的问答服务。
|
|
12
|
+
* **流式响应**: 支持流式 (Streaming) 输出,实时反馈思考过程和答案。
|
|
13
|
+
* **多轮对话**: 支持 Session 管理,保持上下文连贯。
|
|
14
|
+
* **安全可靠**: App Key/Secret 通过环境变量配置,不暴露给 LLM。
|
|
15
|
+
|
|
16
|
+
## 📦 安装
|
|
16
17
|
|
|
17
18
|
```bash
|
|
18
|
-
npm install -g @
|
|
19
|
+
npm install -g @kelvinjhu/lexiang-search
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
### 1. 环境变量(可选)
|
|
24
|
-
|
|
25
|
-
创建 `.env` 文件:
|
|
22
|
+
或者直接使用 `npx`:
|
|
26
23
|
|
|
27
24
|
```bash
|
|
28
|
-
|
|
29
|
-
LEXIANG_APP_SECRET=your_app_secret
|
|
25
|
+
npx -y @kelvinjhu/lexiang-search
|
|
30
26
|
```
|
|
31
27
|
|
|
32
|
-
|
|
28
|
+
## 🚀 配置 (Claude Desktop)
|
|
29
|
+
|
|
30
|
+
在您的 `claude_desktop_config.json` 文件中添加以下配置:
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
33
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
35
34
|
|
|
36
35
|
```json
|
|
37
36
|
{
|
|
38
37
|
"mcpServers": {
|
|
39
|
-
"lexiang
|
|
40
|
-
"command": "
|
|
41
|
-
"args": []
|
|
38
|
+
"lexiang": {
|
|
39
|
+
"command": "npx",
|
|
40
|
+
"args": ["-y", "@kelvinjhu/lexiang-search"],
|
|
41
|
+
"env": {
|
|
42
|
+
"LEXIANG_APP_KEY": "您的乐享AppKey",
|
|
43
|
+
"LEXIANG_APP_SECRET": "您的乐享AppSecret",
|
|
44
|
+
"LOG_LEVEL": "INFO"
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
> **注意**: 请确保替换 `LEXIANG_APP_KEY` 和 `LEXIANG_APP_SECRET` 为您真实的凭证。
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
## 🛠️ 使用指南
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
55
|
+
配置完成后,重启 Claude Desktop。您可以在对话中直接使用自然语言调用工具:
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
* **全站搜索**: "乐享里关于‘报销流程’的规定是什么?"
|
|
58
|
+
* **指定范围搜索**: "在知识库 ID 为 123456 中搜索‘健康评估算法’。"
|
|
59
|
+
* **多轮对话**: "接上一个问题,那具体的计算公式是怎样的?"
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
const result = await client.callTool({
|
|
59
|
-
name: 'ai_qa',
|
|
60
|
-
arguments: {
|
|
61
|
-
app_key: 'your_app_key',
|
|
62
|
-
app_secret: 'your_app_secret',
|
|
63
|
-
query: '乐享是什么?',
|
|
64
|
-
targets: [
|
|
65
|
-
{
|
|
66
|
-
type: 'team',
|
|
67
|
-
id: '74d76195adxxxxxxd49239d56e44f'
|
|
68
|
-
}
|
|
69
|
-
],
|
|
70
|
-
qa_mode: 'normal'
|
|
71
|
-
}
|
|
72
|
-
});
|
|
61
|
+
## 🔧 开发与调试
|
|
73
62
|
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### 流式问答
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
const result = await client.callTool({
|
|
81
|
-
name: 'ai_qa_stream',
|
|
82
|
-
arguments: {
|
|
83
|
-
app_key: 'your_app_key',
|
|
84
|
-
app_secret: 'your_app_secret',
|
|
85
|
-
query: '介绍一下乐享的功能',
|
|
86
|
-
targets: [
|
|
87
|
-
{
|
|
88
|
-
type: 'space',
|
|
89
|
-
id: 'space_id_123'
|
|
90
|
-
}
|
|
91
|
-
],
|
|
92
|
-
qa_mode: 'reasoning'
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
// 处理流式响应
|
|
97
|
-
for await (const chunk of result) {
|
|
98
|
-
process.stdout.write(chunk.content);
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### 多轮对话
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
// 第一轮问答
|
|
106
|
-
const result1 = await client.callTool({
|
|
107
|
-
name: 'ai_qa',
|
|
108
|
-
arguments: {
|
|
109
|
-
app_key: 'your_app_key',
|
|
110
|
-
app_secret: 'your_app_secret',
|
|
111
|
-
query: '乐享有哪些功能?',
|
|
112
|
-
targets: [{ type: 'team', id: 'team_id' }]
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
const sessionId = result1.data.session_id;
|
|
117
|
-
|
|
118
|
-
// 第二轮问答(带上session_id)
|
|
119
|
-
const result2 = await client.callTool({
|
|
120
|
-
name: 'ai_qa',
|
|
121
|
-
arguments: {
|
|
122
|
-
app_key: 'your_app_key',
|
|
123
|
-
app_secret: 'your_app_secret',
|
|
124
|
-
query: '这些功能是怎么收费的?',
|
|
125
|
-
session_id: sessionId,
|
|
126
|
-
targets: [{ type: 'team', id: 'team_id' }]
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## 工具参数
|
|
132
|
-
|
|
133
|
-
### ai_qa / ai_qa_stream
|
|
134
|
-
|
|
135
|
-
| 参数名 | 类型 | 必填 | 说明 |
|
|
136
|
-
|--------|------|------|------|
|
|
137
|
-
| app_key | string | 是 | 乐享应用Key |
|
|
138
|
-
| app_secret | string | 是 | 乐享应用密钥 |
|
|
139
|
-
| query | string | 是 | 用户问题,最长1024字符 |
|
|
140
|
-
| targets | array | 是 | 知识范围数组,最多20个对象 |
|
|
141
|
-
| targets[].type | enum | 是 | space/team/team_code/kb_entry |
|
|
142
|
-
| targets[].id | string | 是 | 对应类型的实体ID |
|
|
143
|
-
| session_id | string | 否 | 会话ID,40字符,用于多轮对话 |
|
|
144
|
-
| new_session | boolean | 否 | 是否开启新会话,默认false |
|
|
145
|
-
| qa_mode | string | 否 | 问答模式,默认normal |
|
|
146
|
-
| skip_faq | boolean | 否 | 是否跳过FAQ,默认false |
|
|
147
|
-
| max_chars | number | 否 | 回答字数限制 |
|
|
148
|
-
| language | string | 否 | 语言,默认zh-CN |
|
|
149
|
-
|
|
150
|
-
### qa_mode 可选值
|
|
151
|
-
|
|
152
|
-
- `normal` - 默认模型快速回答
|
|
153
|
-
- `normal-ds-v3` - deepseek-v3-0324模型快速回答
|
|
154
|
-
- `normal-ds-v3.1` - deepseek-v3.1模型快速回答
|
|
155
|
-
- `normal-ds-v3.2` - deepseek-v3.2模型快速回答
|
|
156
|
-
- `reasoning` - deepseek-r1-0528模型深度思考
|
|
157
|
-
- `reasoning-ds-v3.1` - deepseek-v3.1-terminus-think模型深度思考
|
|
158
|
-
- `reasoning-ds-v3.2` - deepseek-v3.2-think模型深度思考
|
|
159
|
-
- `research` - deepseek-r1-0528模型专业研究
|
|
160
|
-
- `research-ds-v3.1` - deepseek-v3.1-terminus-think模型专业研究
|
|
161
|
-
- `research-ds-v3.2` - deepseek-v3.2-think模型专业研究
|
|
162
|
-
|
|
163
|
-
## 响应数据
|
|
164
|
-
|
|
165
|
-
### 非流式响应
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
{
|
|
169
|
-
"content": "腾讯乐享是腾讯公司推出的……",
|
|
170
|
-
"answer_source": "internal",
|
|
171
|
-
"session_id": "cc77ca018fe67dcb581f3b3c460894dedb9f6b80",
|
|
172
|
-
"reasoning_content": "嗯,用户询问\"乐享是什么?\"……",
|
|
173
|
-
"additional_content": {
|
|
174
|
-
"generated_question": "",
|
|
175
|
-
"reference_chunks": [
|
|
176
|
-
{
|
|
177
|
-
"content": "腾讯乐享是腾讯推出的……",
|
|
178
|
-
"target_id": "5dc00bd321a24568bb4787dec964cde2",
|
|
179
|
-
"target_type": "kb_entry",
|
|
180
|
-
"title": "腾讯乐享介绍",
|
|
181
|
-
"url": "/pages/5dc00bd321a24568bb4787dec964cde2"
|
|
182
|
-
}
|
|
183
|
-
],
|
|
184
|
-
"reference_docs": [
|
|
185
|
-
{
|
|
186
|
-
"title": "腾讯乐享介绍",
|
|
187
|
-
"url": "/pages/5dc00bd321a24568bb4787dec964cde2"
|
|
188
|
-
}
|
|
189
|
-
]
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## 开发
|
|
63
|
+
### 本地构建
|
|
195
64
|
|
|
196
65
|
```bash
|
|
197
66
|
# 安装依赖
|
|
198
67
|
npm install
|
|
199
68
|
|
|
200
|
-
# 开发模式
|
|
201
|
-
npm run dev
|
|
202
|
-
|
|
203
69
|
# 构建
|
|
204
70
|
npm run build
|
|
205
71
|
|
|
206
|
-
#
|
|
207
|
-
|
|
72
|
+
# 运行
|
|
73
|
+
node dist/cli.js
|
|
208
74
|
```
|
|
209
75
|
|
|
210
|
-
|
|
76
|
+
### 环境变量
|
|
211
77
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
-
|
|
216
|
-
-
|
|
78
|
+
| 变量名 | 说明 | 必填 | 默认值 |
|
|
79
|
+
|Data | Description | Required | Default |
|
|
80
|
+
|---|---|---|---|
|
|
81
|
+
| `LEXIANG_APP_KEY` | 乐享应用 Key | 是 | - |
|
|
82
|
+
| `LEXIANG_APP_SECRET` | 乐享应用 Secret | 是 | - |
|
|
83
|
+
| `LOG_LEVEL` | 日志级别 (DEBUG, INFO, WARN, ERROR) | 否 | INFO |
|
|
217
84
|
|
|
218
|
-
##
|
|
85
|
+
## 📄 License
|
|
219
86
|
|
|
220
87
|
MIT
|
|
221
|
-
|
|
222
|
-
## 文档
|
|
223
|
-
|
|
224
|
-
完整设计文档请查看 [DESIGN.md](./DESIGN.md)
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;GAEG"}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,kBAAkB,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
2
|
/**
|
|
4
3
|
* CLI入口文件
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import 'reflect-metadata'; // 必须在最前面引入
|
|
6
|
+
import { LexiangMcpServer } from './server.js';
|
|
7
|
+
import { logger } from './utils/logger.js';
|
|
9
8
|
/**
|
|
10
9
|
* 启动MCP服务器
|
|
11
10
|
*/
|
|
12
11
|
async function main() {
|
|
13
|
-
const server = new
|
|
12
|
+
const server = new LexiangMcpServer();
|
|
14
13
|
// 优雅关闭处理
|
|
15
14
|
const shutdown = async (signal) => {
|
|
16
|
-
|
|
15
|
+
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
17
16
|
await server.stop();
|
|
18
17
|
process.exit(0);
|
|
19
18
|
};
|
|
@@ -21,12 +20,12 @@ async function main() {
|
|
|
21
20
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
22
21
|
// 未处理的Promise拒绝
|
|
23
22
|
process.on('unhandledRejection', (reason) => {
|
|
24
|
-
|
|
23
|
+
logger.error('Unhandled Rejection', { reason });
|
|
25
24
|
process.exit(1);
|
|
26
25
|
});
|
|
27
26
|
// 未捕获的异常
|
|
28
27
|
process.on('uncaughtException', (error) => {
|
|
29
|
-
|
|
28
|
+
logger.error('Uncaught Exception', { error });
|
|
30
29
|
process.exit(1);
|
|
31
30
|
});
|
|
32
31
|
// 启动服务器
|
|
@@ -34,7 +33,7 @@ async function main() {
|
|
|
34
33
|
}
|
|
35
34
|
// 启动应用
|
|
36
35
|
main().catch((error) => {
|
|
37
|
-
|
|
36
|
+
logger.error('Fatal error', { error });
|
|
38
37
|
process.exit(1);
|
|
39
38
|
});
|
|
40
39
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,kBAAkB,CAAC,CAAC,WAAW;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAEtC,SAAS;IACT,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACvD,MAAM,CAAC,IAAI,CAAC,YAAY,MAAM,+BAA+B,CAAC,CAAC;QAC/D,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE/C,gBAAgB;IAChB,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE;QACnD,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,SAAS;IACT,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAY,EAAE,EAAE;QAC/C,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,QAAQ;IACR,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,OAAO;AACP,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* API常量定义
|
|
4
3
|
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MAX_QUERY_LENGTH = exports.SESSION_ID_LENGTH = exports.MAX_TARGETS_COUNT = exports.ANONYMOUS_STAFF_ID = exports.DEFAULT_LANGUAGE = exports.SUPPORTED_TARGET_TYPES = exports.SUPPORTED_QA_MODES = exports.TOKEN_CACHE_TTL = exports.TIMEOUT_CONFIG = exports.LEXIANG_API_CONFIG = void 0;
|
|
7
4
|
// 乐享API配置
|
|
8
|
-
|
|
5
|
+
export const LEXIANG_API_CONFIG = {
|
|
9
6
|
BASE_URL: 'https://lxapi.lexiangla.com',
|
|
10
7
|
API_PATH: '/cgi-bin/v1/ai/qa',
|
|
11
8
|
TOKEN_PATH: '/cgi-bin/token',
|
|
12
9
|
};
|
|
13
10
|
// 请求超时配置(毫秒)
|
|
14
|
-
|
|
11
|
+
export const TIMEOUT_CONFIG = {
|
|
15
12
|
DEFAULT: parseInt(process.env.REQUEST_TIMEOUT || '30000', 10),
|
|
16
13
|
STREAM: parseInt(process.env.STREAM_TIMEOUT || '60000', 10),
|
|
17
14
|
};
|
|
18
15
|
// Token缓存TTL(秒)
|
|
19
|
-
|
|
16
|
+
export const TOKEN_CACHE_TTL = parseInt(process.env.TOKEN_CACHE_TTL || '3600', 10);
|
|
20
17
|
// 支持的问答模式
|
|
21
|
-
|
|
18
|
+
export const SUPPORTED_QA_MODES = [
|
|
22
19
|
'normal',
|
|
23
20
|
'normal-ds-v3',
|
|
24
21
|
'normal-ds-v3.1',
|
|
@@ -31,15 +28,15 @@ exports.SUPPORTED_QA_MODES = [
|
|
|
31
28
|
'research-ds-v3.2',
|
|
32
29
|
];
|
|
33
30
|
// 支持的目标类型
|
|
34
|
-
|
|
31
|
+
export const SUPPORTED_TARGET_TYPES = ['space', 'team', 'team_code', 'kb_entry'];
|
|
35
32
|
// 默认语言
|
|
36
|
-
|
|
33
|
+
export const DEFAULT_LANGUAGE = 'zh-CN';
|
|
37
34
|
// 匿名用户ID
|
|
38
|
-
|
|
35
|
+
export const ANONYMOUS_STAFF_ID = 'system-bot';
|
|
39
36
|
// 最大目标数量
|
|
40
|
-
|
|
37
|
+
export const MAX_TARGETS_COUNT = 20;
|
|
41
38
|
// Session ID长度
|
|
42
|
-
|
|
39
|
+
export const SESSION_ID_LENGTH = 40;
|
|
43
40
|
// Query最大长度
|
|
44
|
-
|
|
41
|
+
export const MAX_QUERY_LENGTH = 1024;
|
|
45
42
|
//# sourceMappingURL=api.constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.constants.js","sourceRoot":"","sources":["../../src/constants/api.constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.constants.js","sourceRoot":"","sources":["../../src/constants/api.constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,UAAU;AACV,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ,EAAE,6BAA6B;IACvC,QAAQ,EAAE,mBAAmB;IAC7B,UAAU,EAAE,gBAAgB;CACpB,CAAC;AAEX,aAAa;AACb,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,EAAE,EAAE,CAAC;IAC7D,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,EAAE,EAAE,CAAC;CACnD,CAAC;AAEX,gBAAgB;AAChB,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAEnF,UAAU;AACV,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ;IACR,cAAc;IACd,gBAAgB;IAChB,gBAAgB;IAChB,WAAW;IACX,mBAAmB;IACnB,mBAAmB;IACnB,UAAU;IACV,kBAAkB;IAClB,kBAAkB;CACV,CAAC;AAEX,UAAU;AACV,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,CAAU,CAAC;AAE1F,OAAO;AACP,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAExC,SAAS;AACT,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE/C,SAAS;AACT,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,eAAe;AACf,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,YAAY;AACZ,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC"}
|
|
@@ -1,31 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AI问答请求DTO
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import type { AiQaRequest } from '../types/lexiang-api.types';
|
|
4
|
+
import type { AiQaRequest } from '../types/lexiang-api.types.js';
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
6
|
+
* 知识范围对象
|
|
8
7
|
*/
|
|
9
8
|
export declare class TargetDto {
|
|
10
|
-
type:
|
|
9
|
+
type: string;
|
|
11
10
|
id: string;
|
|
12
11
|
}
|
|
13
12
|
/**
|
|
14
13
|
* AI问答请求DTO
|
|
15
14
|
*/
|
|
16
15
|
export declare class AiQaRequestDto {
|
|
16
|
+
app_key?: string;
|
|
17
|
+
app_secret?: string;
|
|
17
18
|
query: string;
|
|
18
|
-
|
|
19
|
-
app_secret: string;
|
|
20
|
-
targets: TargetDto[];
|
|
19
|
+
targets?: TargetDto[];
|
|
21
20
|
session_id?: string;
|
|
22
21
|
new_session?: boolean;
|
|
23
|
-
qa_mode?:
|
|
22
|
+
qa_mode?: string;
|
|
24
23
|
skip_faq?: boolean;
|
|
25
24
|
max_chars?: number;
|
|
26
25
|
language?: string;
|
|
27
26
|
/**
|
|
28
|
-
* 转换为乐享API
|
|
27
|
+
* 转换为乐享API请求对象
|
|
29
28
|
*/
|
|
30
29
|
toLexiangRequest(): AiQaRequest;
|
|
31
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-qa-request.dto.d.ts","sourceRoot":"","sources":["../../src/dto/ai-qa-request.dto.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"ai-qa-request.dto.d.ts","sourceRoot":"","sources":["../../src/dto/ai-qa-request.dto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,+BAA+B,CAAC;AAEjF;;GAEG;AACH,qBAAa,SAAS;IAGpB,IAAI,EAAG,MAAM,CAAC;IAGd,EAAE,EAAG,MAAM,CAAC;CACb;AAED;;GAEG;AACH,qBAAa,cAAc;IAGzB,OAAO,CAAC,EAAE,MAAM,CAAC;IAIjB,UAAU,CAAC,EAAE,MAAM,CAAC;IAIpB,KAAK,EAAG,MAAM,CAAC;IAMf,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IAMtB,UAAU,CAAC,EAAE,MAAM,CAAC;IAIpB,WAAW,CAAC,EAAE,OAAO,CAAC;IAKtB,OAAO,CAAC,EAAE,MAAM,CAAC;IAIjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAInB,SAAS,CAAC,EAAE,MAAM,CAAC;IAInB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,gBAAgB,IAAI,WAAW;CAkBhC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* AI问答请求DTO
|
|
4
3
|
*/
|
|
@@ -11,35 +10,32 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
11
10
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
12
11
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
13
12
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const class_transformer_1 = require("class-transformer");
|
|
18
|
-
const api_constants_1 = require("../constants/api.constants");
|
|
13
|
+
import { IsString, IsOptional, IsBoolean, IsNumber, IsArray, ValidateNested, IsEnum, MaxLength, MinLength } from 'class-validator';
|
|
14
|
+
import { Type } from 'class-transformer';
|
|
15
|
+
import { SUPPORTED_QA_MODES, SUPPORTED_TARGET_TYPES, DEFAULT_LANGUAGE } from '../constants/api.constants.js';
|
|
19
16
|
/**
|
|
20
|
-
*
|
|
17
|
+
* 知识范围对象
|
|
21
18
|
*/
|
|
22
|
-
class TargetDto {
|
|
19
|
+
export class TargetDto {
|
|
23
20
|
type;
|
|
24
21
|
id;
|
|
25
22
|
}
|
|
26
|
-
exports.TargetDto = TargetDto;
|
|
27
23
|
__decorate([
|
|
28
|
-
(
|
|
24
|
+
IsString(),
|
|
25
|
+
IsEnum(SUPPORTED_TARGET_TYPES),
|
|
29
26
|
__metadata("design:type", String)
|
|
30
27
|
], TargetDto.prototype, "type", void 0);
|
|
31
28
|
__decorate([
|
|
32
|
-
|
|
33
|
-
(0, class_validator_1.IsNotEmpty)(),
|
|
29
|
+
IsString(),
|
|
34
30
|
__metadata("design:type", String)
|
|
35
31
|
], TargetDto.prototype, "id", void 0);
|
|
36
32
|
/**
|
|
37
33
|
* AI问答请求DTO
|
|
38
34
|
*/
|
|
39
|
-
class AiQaRequestDto {
|
|
40
|
-
query;
|
|
35
|
+
export class AiQaRequestDto {
|
|
41
36
|
app_key;
|
|
42
37
|
app_secret;
|
|
38
|
+
query;
|
|
43
39
|
targets;
|
|
44
40
|
session_id;
|
|
45
41
|
new_session;
|
|
@@ -48,87 +44,78 @@ class AiQaRequestDto {
|
|
|
48
44
|
max_chars;
|
|
49
45
|
language;
|
|
50
46
|
/**
|
|
51
|
-
* 转换为乐享API
|
|
47
|
+
* 转换为乐享API请求对象
|
|
52
48
|
*/
|
|
53
49
|
toLexiangRequest() {
|
|
54
50
|
const request = {
|
|
55
51
|
query: this.query,
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
session_id: this.session_id,
|
|
53
|
+
new_session: this.new_session,
|
|
54
|
+
qa_mode: this.qa_mode,
|
|
55
|
+
skip_faq: this.skip_faq,
|
|
56
|
+
max_chars: this.max_chars,
|
|
57
|
+
language: this.language || DEFAULT_LANGUAGE,
|
|
58
58
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (this.new_session !== undefined) {
|
|
63
|
-
request.new_session = this.new_session;
|
|
64
|
-
}
|
|
65
|
-
if (this.qa_mode) {
|
|
66
|
-
request.qa_mode = this.qa_mode;
|
|
67
|
-
}
|
|
68
|
-
if (this.skip_faq !== undefined) {
|
|
69
|
-
request.skip_faq = this.skip_faq;
|
|
70
|
-
}
|
|
71
|
-
if (this.max_chars !== undefined) {
|
|
72
|
-
request.max_chars = this.max_chars;
|
|
59
|
+
// 只有当 targets 存在且不为空数组时才添加到请求中
|
|
60
|
+
if (this.targets && this.targets.length > 0) {
|
|
61
|
+
request.targets = this.targets;
|
|
73
62
|
}
|
|
74
63
|
return request;
|
|
75
64
|
}
|
|
76
65
|
}
|
|
77
|
-
exports.AiQaRequestDto = AiQaRequestDto;
|
|
78
66
|
__decorate([
|
|
79
|
-
|
|
80
|
-
(
|
|
81
|
-
(0, class_validator_1.MaxLength)(1024),
|
|
82
|
-
__metadata("design:type", String)
|
|
83
|
-
], AiQaRequestDto.prototype, "query", void 0);
|
|
84
|
-
__decorate([
|
|
85
|
-
(0, class_validator_1.IsString)(),
|
|
86
|
-
(0, class_validator_1.IsNotEmpty)(),
|
|
67
|
+
IsString(),
|
|
68
|
+
IsOptional(),
|
|
87
69
|
__metadata("design:type", String)
|
|
88
70
|
], AiQaRequestDto.prototype, "app_key", void 0);
|
|
89
71
|
__decorate([
|
|
90
|
-
|
|
91
|
-
(
|
|
72
|
+
IsString(),
|
|
73
|
+
IsOptional(),
|
|
92
74
|
__metadata("design:type", String)
|
|
93
75
|
], AiQaRequestDto.prototype, "app_secret", void 0);
|
|
94
76
|
__decorate([
|
|
95
|
-
(
|
|
96
|
-
(
|
|
97
|
-
(
|
|
98
|
-
|
|
99
|
-
|
|
77
|
+
IsString(),
|
|
78
|
+
MaxLength(1024),
|
|
79
|
+
__metadata("design:type", String)
|
|
80
|
+
], AiQaRequestDto.prototype, "query", void 0);
|
|
81
|
+
__decorate([
|
|
82
|
+
IsArray(),
|
|
83
|
+
IsOptional(),
|
|
84
|
+
ValidateNested({ each: true }),
|
|
85
|
+
Type(() => TargetDto),
|
|
100
86
|
__metadata("design:type", Array)
|
|
101
87
|
], AiQaRequestDto.prototype, "targets", void 0);
|
|
102
88
|
__decorate([
|
|
103
|
-
(
|
|
104
|
-
(
|
|
105
|
-
(
|
|
89
|
+
IsString(),
|
|
90
|
+
IsOptional(),
|
|
91
|
+
MinLength(40),
|
|
92
|
+
MaxLength(40),
|
|
106
93
|
__metadata("design:type", String)
|
|
107
94
|
], AiQaRequestDto.prototype, "session_id", void 0);
|
|
108
95
|
__decorate([
|
|
109
|
-
(
|
|
110
|
-
(
|
|
96
|
+
IsBoolean(),
|
|
97
|
+
IsOptional(),
|
|
111
98
|
__metadata("design:type", Boolean)
|
|
112
99
|
], AiQaRequestDto.prototype, "new_session", void 0);
|
|
113
100
|
__decorate([
|
|
114
|
-
(
|
|
115
|
-
(
|
|
116
|
-
|
|
101
|
+
IsString(),
|
|
102
|
+
IsOptional(),
|
|
103
|
+
IsEnum(SUPPORTED_QA_MODES),
|
|
104
|
+
__metadata("design:type", String)
|
|
117
105
|
], AiQaRequestDto.prototype, "qa_mode", void 0);
|
|
118
106
|
__decorate([
|
|
119
|
-
(
|
|
120
|
-
(
|
|
107
|
+
IsBoolean(),
|
|
108
|
+
IsOptional(),
|
|
121
109
|
__metadata("design:type", Boolean)
|
|
122
110
|
], AiQaRequestDto.prototype, "skip_faq", void 0);
|
|
123
111
|
__decorate([
|
|
124
|
-
(
|
|
125
|
-
(
|
|
126
|
-
(0, class_validator_1.Min)(1),
|
|
112
|
+
IsNumber(),
|
|
113
|
+
IsOptional(),
|
|
127
114
|
__metadata("design:type", Number)
|
|
128
115
|
], AiQaRequestDto.prototype, "max_chars", void 0);
|
|
129
116
|
__decorate([
|
|
130
|
-
(
|
|
131
|
-
(
|
|
117
|
+
IsString(),
|
|
118
|
+
IsOptional(),
|
|
132
119
|
__metadata("design:type", String)
|
|
133
120
|
], AiQaRequestDto.prototype, "language", void 0);
|
|
134
121
|
//# sourceMappingURL=ai-qa-request.dto.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-qa-request.dto.js","sourceRoot":"","sources":["../../src/dto/ai-qa-request.dto.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ai-qa-request.dto.js","sourceRoot":"","sources":["../../src/dto/ai-qa-request.dto.ts"],"names":[],"mappings":"AAAA;;GAEG;;;;;;;;;;AAEH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACnI,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAG7G;;GAEG;AACH,MAAM,OAAO,SAAS;IAGpB,IAAI,CAAU;IAGd,EAAE,CAAU;CACb;AAJC;IAFC,QAAQ,EAAE;IACV,MAAM,CAAC,sBAAsB,CAAC;;uCACjB;AAGd;IADC,QAAQ,EAAE;;qCACC;AAGd;;GAEG;AACH,MAAM,OAAO,cAAc;IAGzB,OAAO,CAAU;IAIjB,UAAU,CAAU;IAIpB,KAAK,CAAU;IAMf,OAAO,CAAe;IAMtB,UAAU,CAAU;IAIpB,WAAW,CAAW;IAKtB,OAAO,CAAU;IAIjB,QAAQ,CAAW;IAInB,SAAS,CAAU;IAInB,QAAQ,CAAU;IAElB;;OAEG;IACH,gBAAgB;QACd,MAAM,OAAO,GAAgB;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,OAAO,EAAE,IAAI,CAAC,OAA6B;YAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,gBAAgB;SAC5C,CAAC;QAEF,+BAA+B;QAC/B,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAA8B,CAAC;QACxD,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAhEC;IAFC,QAAQ,EAAE;IACV,UAAU,EAAE;;+CACI;AAIjB;IAFC,QAAQ,EAAE;IACV,UAAU,EAAE;;kDACO;AAIpB;IAFC,QAAQ,EAAE;IACV,SAAS,CAAC,IAAI,CAAC;;6CACD;AAMf;IAJC,OAAO,EAAE;IACT,UAAU,EAAE;IACZ,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;;+CACA;AAMtB;IAJC,QAAQ,EAAE;IACV,UAAU,EAAE;IACZ,SAAS,CAAC,EAAE,CAAC;IACb,SAAS,CAAC,EAAE,CAAC;;kDACM;AAIpB;IAFC,SAAS,EAAE;IACX,UAAU,EAAE;;mDACS;AAKtB;IAHC,QAAQ,EAAE;IACV,UAAU,EAAE;IACZ,MAAM,CAAC,kBAAkB,CAAC;;+CACV;AAIjB;IAFC,SAAS,EAAE;IACX,UAAU,EAAE;;gDACM;AAInB;IAFC,QAAQ,EAAE;IACV,UAAU,EAAE;;iDACM;AAInB;IAFC,QAAQ,EAAE;IACV,UAAU,EAAE;;gDACK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-qa-response.dto.d.ts","sourceRoot":"","sources":["../../src/dto/ai-qa-response.dto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,iBAAiB;IAC5B,OAAO,EAAG,MAAM,CAAC;IACjB,SAAS,EAAG,MAAM,CAAC;IACnB,WAAW,EAAG,MAAM,CAAC;IACrB,KAAK,EAAG,MAAM,CAAC;IACf,GAAG,EAAG,MAAM,CAAC;CACd;AAED,qBAAa,eAAe;IAC1B,KAAK,EAAG,MAAM,CAAC;IACf,GAAG,EAAG,MAAM,CAAC;CACd;AAED,qBAAa,oBAAoB;IAC/B,kBAAkB,EAAG,MAAM,CAAC;IAC5B,gBAAgB,EAAG,iBAAiB,EAAE,CAAC;IACvC,cAAc,EAAG,eAAe,EAAE,CAAC;CACpC;AAED,qBAAa,mBAAmB;IAC9B,OAAO,EAAG,MAAM,CAAC;IACjB,aAAa,EAAG,MAAM,CAAC;IACvB,UAAU,EAAG,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAG,oBAAoB,CAAC;CAC3C;AAED,qBAAa,eAAe;IAC1B,IAAI,EAAG,MAAM,CAAC;IACd,OAAO,EAAG,MAAM,CAAC;IACjB,UAAU,EAAG,MAAM,CAAC;IACpB,IAAI,EAAG,mBAAmB,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,mBAAmB,GAAG;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD,
|
|
1
|
+
{"version":3,"file":"ai-qa-response.dto.d.ts","sourceRoot":"","sources":["../../src/dto/ai-qa-response.dto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,iBAAiB;IAC5B,OAAO,EAAG,MAAM,CAAC;IACjB,SAAS,EAAG,MAAM,CAAC;IACnB,WAAW,EAAG,MAAM,CAAC;IACrB,KAAK,EAAG,MAAM,CAAC;IACf,GAAG,EAAG,MAAM,CAAC;CACd;AAED,qBAAa,eAAe;IAC1B,KAAK,EAAG,MAAM,CAAC;IACf,GAAG,EAAG,MAAM,CAAC;CACd;AAED,qBAAa,oBAAoB;IAC/B,kBAAkB,EAAG,MAAM,CAAC;IAC5B,gBAAgB,EAAG,iBAAiB,EAAE,CAAC;IACvC,cAAc,EAAG,eAAe,EAAE,CAAC;CACpC;AAED,qBAAa,mBAAmB;IAC9B,OAAO,EAAG,MAAM,CAAC;IACjB,aAAa,EAAG,MAAM,CAAC;IACvB,UAAU,EAAG,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAG,oBAAoB,CAAC;CAC3C;AAED,qBAAa,eAAe;IAC1B,IAAI,EAAG,MAAM,CAAC;IACd,OAAO,EAAG,MAAM,CAAC;IACjB,UAAU,EAAG,MAAM,CAAC;IACpB,IAAI,EAAG,mBAAmB,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,mBAAmB,GAAG;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD,CAkBA"}
|