webaiapi 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +184 -2
- package/bin/webapi.mjs +45 -0
- package/dist/browser/auth-capture.d.ts +110 -0
- package/dist/browser/auth-capture.d.ts.map +1 -0
- package/dist/browser/auth-capture.js +487 -0
- package/dist/browser/auth-capture.js.map +1 -0
- package/dist/browser/credentials.d.ts +102 -0
- package/dist/browser/credentials.d.ts.map +1 -0
- package/dist/browser/credentials.js +209 -0
- package/dist/browser/credentials.js.map +1 -0
- package/dist/browser/js-eval.d.ts +44 -0
- package/dist/browser/js-eval.d.ts.map +1 -0
- package/dist/browser/js-eval.js +20 -0
- package/dist/browser/js-eval.js.map +1 -0
- package/dist/browser/login-flow.d.ts +171 -0
- package/dist/browser/login-flow.d.ts.map +1 -0
- package/dist/browser/login-flow.js +606 -0
- package/dist/browser/login-flow.js.map +1 -0
- package/dist/browser/manager.d.ts +144 -0
- package/dist/browser/manager.d.ts.map +1 -0
- package/dist/browser/manager.js +586 -0
- package/dist/browser/manager.js.map +1 -0
- package/dist/browser/platforms.d.ts +96 -0
- package/dist/browser/platforms.d.ts.map +1 -0
- package/dist/browser/platforms.js +288 -0
- package/dist/browser/platforms.js.map +1 -0
- package/dist/browser/sse-capture.d.ts +23 -0
- package/dist/browser/sse-capture.d.ts.map +1 -0
- package/dist/browser/sse-capture.js +199 -0
- package/dist/browser/sse-capture.js.map +1 -0
- package/dist/browser/stealth.d.ts +12 -0
- package/dist/browser/stealth.d.ts.map +1 -0
- package/dist/browser/stealth.js +12 -0
- package/dist/browser/stealth.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +441 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +90 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +246 -0
- package/dist/config.js.map +1 -0
- package/dist/controllers/history-db.d.ts +56 -0
- package/dist/controllers/history-db.d.ts.map +1 -0
- package/dist/controllers/history-db.js +260 -0
- package/dist/controllers/history-db.js.map +1 -0
- package/dist/controllers/request-pool.d.ts +78 -0
- package/dist/controllers/request-pool.d.ts.map +1 -0
- package/dist/controllers/request-pool.js +222 -0
- package/dist/controllers/request-pool.js.map +1 -0
- package/dist/controllers/router.d.ts +172 -0
- package/dist/controllers/router.d.ts.map +1 -0
- package/dist/controllers/router.js +569 -0
- package/dist/controllers/router.js.map +1 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/log/api-logger.d.ts +55 -0
- package/dist/log/api-logger.d.ts.map +1 -0
- package/dist/log/api-logger.js +264 -0
- package/dist/log/api-logger.js.map +1 -0
- package/dist/log/debug-logger.d.ts +49 -0
- package/dist/log/debug-logger.d.ts.map +1 -0
- package/dist/log/debug-logger.js +285 -0
- package/dist/log/debug-logger.js.map +1 -0
- package/dist/log/logger.d.ts +16 -0
- package/dist/log/logger.d.ts.map +1 -0
- package/dist/log/logger.js +35 -0
- package/dist/log/logger.js.map +1 -0
- package/dist/postinstall.d.ts +3 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +90 -0
- package/dist/postinstall.js.map +1 -0
- package/dist/providers/base.d.ts +83 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +51 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/chatglm-dom-extract.d.ts +24 -0
- package/dist/providers/chatglm-dom-extract.d.ts.map +1 -0
- package/dist/providers/chatglm-dom-extract.js +175 -0
- package/dist/providers/chatglm-dom-extract.js.map +1 -0
- package/dist/providers/chatglm-dom.d.ts +110 -0
- package/dist/providers/chatglm-dom.d.ts.map +1 -0
- package/dist/providers/chatglm-dom.js +384 -0
- package/dist/providers/chatglm-dom.js.map +1 -0
- package/dist/providers/chatglm-sse.d.ts +119 -0
- package/dist/providers/chatglm-sse.d.ts.map +1 -0
- package/dist/providers/chatglm-sse.js +241 -0
- package/dist/providers/chatglm-sse.js.map +1 -0
- package/dist/providers/chatglm.d.ts +288 -0
- package/dist/providers/chatglm.d.ts.map +1 -0
- package/dist/providers/chatglm.js +1631 -0
- package/dist/providers/chatglm.js.map +1 -0
- package/dist/routes/chat.d.ts +117 -0
- package/dist/routes/chat.d.ts.map +1 -0
- package/dist/routes/chat.js +1346 -0
- package/dist/routes/chat.js.map +1 -0
- package/dist/routes/compress.d.ts +142 -0
- package/dist/routes/compress.d.ts.map +1 -0
- package/dist/routes/compress.js +551 -0
- package/dist/routes/compress.js.map +1 -0
- package/dist/routes/failover.d.ts +34 -0
- package/dist/routes/failover.d.ts.map +1 -0
- package/dist/routes/failover.js +221 -0
- package/dist/routes/failover.js.map +1 -0
- package/dist/routes/helpers.d.ts +174 -0
- package/dist/routes/helpers.d.ts.map +1 -0
- package/dist/routes/helpers.js +525 -0
- package/dist/routes/helpers.js.map +1 -0
- package/dist/routes/meta.d.ts +31 -0
- package/dist/routes/meta.d.ts.map +1 -0
- package/dist/routes/meta.js +184 -0
- package/dist/routes/meta.js.map +1 -0
- package/dist/routes/sse.d.ts +82 -0
- package/dist/routes/sse.d.ts.map +1 -0
- package/dist/routes/sse.js +77 -0
- package/dist/routes/sse.js.map +1 -0
- package/dist/server/app.d.ts +24 -0
- package/dist/server/app.d.ts.map +1 -0
- package/dist/server/app.js +292 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/middleware/api-key.d.ts +61 -0
- package/dist/server/middleware/api-key.d.ts.map +1 -0
- package/dist/server/middleware/api-key.js +95 -0
- package/dist/server/middleware/api-key.js.map +1 -0
- package/dist/server/middleware/rate-limit.d.ts +67 -0
- package/dist/server/middleware/rate-limit.d.ts.map +1 -0
- package/dist/server/middleware/rate-limit.js +134 -0
- package/dist/server/middleware/rate-limit.js.map +1 -0
- package/dist/server/middleware/timeout.d.ts +34 -0
- package/dist/server/middleware/timeout.d.ts.map +1 -0
- package/dist/server/middleware/timeout.js +64 -0
- package/dist/server/middleware/timeout.js.map +1 -0
- package/dist/server/types.d.ts +20 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +2 -0
- package/dist/server/types.js.map +1 -0
- package/dist/tools/build.d.ts +14 -0
- package/dist/tools/build.d.ts.map +1 -0
- package/dist/tools/build.js +105 -0
- package/dist/tools/build.js.map +1 -0
- package/dist/tools/clean.d.ts +32 -0
- package/dist/tools/clean.d.ts.map +1 -0
- package/dist/tools/clean.js +65 -0
- package/dist/tools/clean.js.map +1 -0
- package/dist/tools/convert.d.ts +50 -0
- package/dist/tools/convert.d.ts.map +1 -0
- package/dist/tools/convert.js +289 -0
- package/dist/tools/convert.js.map +1 -0
- package/dist/tools/names.d.ts +138 -0
- package/dist/tools/names.d.ts.map +1 -0
- package/dist/tools/names.js +578 -0
- package/dist/tools/names.js.map +1 -0
- package/dist/tools/parse.d.ts +31 -0
- package/dist/tools/parse.d.ts.map +1 -0
- package/dist/tools/parse.js +273 -0
- package/dist/tools/parse.js.map +1 -0
- package/dist/tools/placeholder.d.ts +21 -0
- package/dist/tools/placeholder.d.ts.map +1 -0
- package/dist/tools/placeholder.js +135 -0
- package/dist/tools/placeholder.js.map +1 -0
- package/dist/tools/prompts.d.ts +42 -0
- package/dist/tools/prompts.d.ts.map +1 -0
- package/dist/tools/prompts.js +69 -0
- package/dist/tools/prompts.js.map +1 -0
- package/dist/tools/protocol.d.ts +58 -0
- package/dist/tools/protocol.d.ts.map +1 -0
- package/dist/tools/protocol.js +287 -0
- package/dist/tools/protocol.js.map +1 -0
- package/dist/tools/repair.d.ts +83 -0
- package/dist/tools/repair.d.ts.map +1 -0
- package/dist/tools/repair.js +510 -0
- package/dist/tools/repair.js.map +1 -0
- package/dist/tools/workspace.d.ts +40 -0
- package/dist/tools/workspace.d.ts.map +1 -0
- package/dist/tools/workspace.js +224 -0
- package/dist/tools/workspace.js.map +1 -0
- package/dist/types/message.d.ts +87 -0
- package/dist/types/message.d.ts.map +1 -0
- package/dist/types/message.js +85 -0
- package/dist/types/message.js.map +1 -0
- package/dist/types/openai.d.ts +100 -0
- package/dist/types/openai.d.ts.map +1 -0
- package/dist/types/openai.js +66 -0
- package/dist/types/openai.js.map +1 -0
- package/dist/utils/errors.d.ts +82 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +115 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/mutex.d.ts +31 -0
- package/dist/utils/mutex.d.ts.map +1 -0
- package/dist/utils/mutex.js +61 -0
- package/dist/utils/mutex.js.map +1 -0
- package/dist/utils/prompt.d.ts +150 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +514 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/text.d.ts +30 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +70 -0
- package/dist/utils/text.js.map +1 -0
- package/package.json +67 -4
- package/postinstall.mjs +34 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工具名 / 参数名映射与解析 —— `legacy-python/src/utils/tool_calls.py` 的一部分。
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ **与原设计不同处(有意的修正)**:
|
|
5
|
+
* Python 版把映射表放在**模块级全局变量**里(`_DYNAMIC_TOOL_NAME_MAP` /
|
|
6
|
+
* `_DYNAMIC_PARAM_NAME_MAP`),由 `format_tools_as_text(tools)` 写入、由
|
|
7
|
+
* `_build_tool_call` 读取。在并发服务里这是**真实的串扰 bug**:两个客户端
|
|
8
|
+
* 同时请求且工具集不同时,后者的映射会覆盖前者,导致工具名/参数名被映射错。
|
|
9
|
+
*
|
|
10
|
+
* TS 版改为**显式的 {@link ToolMaps} 对象**:由 `createToolMaps(tools)` 按请求创建,
|
|
11
|
+
* 沿调用链显式传递。既修掉并发串扰,也让函数变成可测的纯函数。
|
|
12
|
+
*/
|
|
13
|
+
import { randomUUID } from 'node:crypto';
|
|
14
|
+
import { logger } from '../log/logger.js';
|
|
15
|
+
import { toolNameOf, toolRequiredParams } from '../types/message.js';
|
|
16
|
+
import { cleanDomHtml } from './clean.js';
|
|
17
|
+
/** AI 输出工具名 → 标准名的静态别名表。 */
|
|
18
|
+
export const TOOL_NAME_ALIASES = {
|
|
19
|
+
edit_file: 'SearchReplace',
|
|
20
|
+
EditFile: 'SearchReplace',
|
|
21
|
+
edit: 'SearchReplace',
|
|
22
|
+
replace: 'SearchReplace',
|
|
23
|
+
replace_in_file: 'SearchReplace',
|
|
24
|
+
write_file: 'Write',
|
|
25
|
+
WriteFile: 'Write',
|
|
26
|
+
create_file: 'Write',
|
|
27
|
+
};
|
|
28
|
+
/** 语义别名分组:`write/create` → 写文件工具,等等。 */
|
|
29
|
+
export const TOOL_NAME_ALIAS_PATTERNS = [
|
|
30
|
+
['write', ['write', 'create', 'newfile']],
|
|
31
|
+
['edit', ['edit', 'replace', 'searchreplace', 'strreplace', 'str_replace', 'modify', 'patch']],
|
|
32
|
+
['read', ['read', 'catfile', 'viewfile']],
|
|
33
|
+
];
|
|
34
|
+
/** 仅在 IDE 内可用、不应由后端 API 调用的工具。 */
|
|
35
|
+
export const TRAE_INTERNAL_TOOLS = new Set([
|
|
36
|
+
'AdvisorTool',
|
|
37
|
+
'get_goal',
|
|
38
|
+
'create_goal',
|
|
39
|
+
'update_goal',
|
|
40
|
+
'OpenPreview',
|
|
41
|
+
'CheckCommandStatus',
|
|
42
|
+
'StopCommand',
|
|
43
|
+
'GetDiagnostics',
|
|
44
|
+
]);
|
|
45
|
+
/** 文件系统类工具:必须在**客户端**执行(后端只负责把调用回传)。 */
|
|
46
|
+
export const FILE_SYSTEM_TOOLS = new Set([
|
|
47
|
+
'Read',
|
|
48
|
+
'Write',
|
|
49
|
+
'Edit',
|
|
50
|
+
'SearchReplace',
|
|
51
|
+
'Grep',
|
|
52
|
+
'Glob',
|
|
53
|
+
'LS',
|
|
54
|
+
'DeleteFile',
|
|
55
|
+
'RunCommand',
|
|
56
|
+
'WebSearch',
|
|
57
|
+
'WebFetch',
|
|
58
|
+
'Skill',
|
|
59
|
+
'Task',
|
|
60
|
+
'SearchCodebase',
|
|
61
|
+
]);
|
|
62
|
+
/** 用户交互类工具:同样回传客户端执行。 */
|
|
63
|
+
export const USER_INTERACTION_TOOLS = new Set(['AskUserQuestion', 'TodoWrite', 'NotifyUser']);
|
|
64
|
+
/**
|
|
65
|
+
* 平台自带工具名 —— 出现即说明模型在「对着网页自己的工具」干活,必须专项告警。
|
|
66
|
+
*
|
|
67
|
+
* ⚠️ 2026-10-14 实测:`execute_sandbox_code` 是 ChatGLM 自己的代码沙箱工具。
|
|
68
|
+
* 模型在 `answer_type=python` 的回合里会去调它,而客户端并没有这个工具 →
|
|
69
|
+
* 被丢弃后整轮降级成纯文本、客户端直接结束回合(「对话无故停止」)。
|
|
70
|
+
*/
|
|
71
|
+
export const PLATFORM_BUILTIN_TOOL_NAMES = new Set([
|
|
72
|
+
'search',
|
|
73
|
+
'open',
|
|
74
|
+
'click',
|
|
75
|
+
'find',
|
|
76
|
+
'browse',
|
|
77
|
+
'browser',
|
|
78
|
+
'finish',
|
|
79
|
+
'execute_sandbox_code',
|
|
80
|
+
'execute_code',
|
|
81
|
+
'python_interpreter',
|
|
82
|
+
]);
|
|
83
|
+
/** 空映射表(等价于 Python 版全局变量未初始化时的行为)。 */
|
|
84
|
+
export const EMPTY_TOOL_MAPS = { name: {}, param: {} };
|
|
85
|
+
/** 归一化参数名:只保留字母后小写(`filePath` → `filepath`)。 */
|
|
86
|
+
export function normalizeParamKey(name) {
|
|
87
|
+
return name.replace(/[^a-zA-Z]/g, '').toLowerCase();
|
|
88
|
+
}
|
|
89
|
+
/** 归一化工具名:只保留小写字母数字(`write_to_file` → `writetofile`)。 */
|
|
90
|
+
export function normalizeToolName(name) {
|
|
91
|
+
return (name ?? '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 从客户端工具定义中检测写入/编辑/读取工具的实际名称(按参数特征推断)。
|
|
95
|
+
*
|
|
96
|
+
* - 写入工具:有 file_path/path + content,且无 old_str
|
|
97
|
+
* - 编辑工具:有 old_str/oldText 之一 + new_str/newText 之一
|
|
98
|
+
* - 读取工具:有 file_path(**不是** path,`path` 可能是目录)且无 content/old_str
|
|
99
|
+
*/
|
|
100
|
+
export function detectToolNames(tools) {
|
|
101
|
+
const result = {};
|
|
102
|
+
for (const tool of tools) {
|
|
103
|
+
const name = toolNameOf(tool);
|
|
104
|
+
const props = tool?.function?.parameters?.properties ?? {};
|
|
105
|
+
const paramNamesLower = new Set(Object.keys(props).map((p) => p.toLowerCase()));
|
|
106
|
+
const hasFilePath = paramNamesLower.has('file_path') || paramNamesLower.has('filepath');
|
|
107
|
+
const hasContent = paramNamesLower.has('content');
|
|
108
|
+
const hasOld = ['old_str', 'oldtext', 'old_text', 'search'].some((p) => paramNamesLower.has(p));
|
|
109
|
+
const hasNew = ['new_str', 'newtext', 'new_text', 'replace'].some((p) => paramNamesLower.has(p));
|
|
110
|
+
if (hasFilePath && hasContent && !hasOld) {
|
|
111
|
+
result['write'] ??= name;
|
|
112
|
+
}
|
|
113
|
+
else if (hasOld && hasNew) {
|
|
114
|
+
result['edit'] ??= name;
|
|
115
|
+
}
|
|
116
|
+
else if (hasFilePath && !hasContent && !hasOld) {
|
|
117
|
+
result['read'] ??= name;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 按客户端工具定义建立映射表(替代 Python 版写全局变量的做法)。
|
|
124
|
+
*/
|
|
125
|
+
export function createToolMaps(tools) {
|
|
126
|
+
const name = detectToolNames(tools);
|
|
127
|
+
if (Object.keys(name).length > 0) {
|
|
128
|
+
logger.info({ detected: name }, '[tool_calls] 检测到客户端工具名映射');
|
|
129
|
+
}
|
|
130
|
+
const param = {};
|
|
131
|
+
for (const tool of tools) {
|
|
132
|
+
const toolName = toolNameOf(tool);
|
|
133
|
+
const props = tool?.function?.parameters?.properties;
|
|
134
|
+
if (!toolName || !props || typeof props !== 'object')
|
|
135
|
+
continue;
|
|
136
|
+
const paramMap = {};
|
|
137
|
+
for (const paramName of Object.keys(props)) {
|
|
138
|
+
paramMap[normalizeParamKey(paramName)] = paramName;
|
|
139
|
+
}
|
|
140
|
+
param[toolName] = paramMap;
|
|
141
|
+
}
|
|
142
|
+
return { name, param };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 把 AI 输出的工具名解析为客户端真实工具名;无法解析时返回空字符串。
|
|
146
|
+
*
|
|
147
|
+
* 依次尝试:完全相同 → 归一化后相同 → 语义别名。
|
|
148
|
+
*
|
|
149
|
+
* ⚠️ **近似名必须映射后保留,绝不能直接丢弃** —— 丢弃会让工具调用凭空消失,
|
|
150
|
+
* 客户端收到一段纯文本后就停住了(实测 AI 输出 `write_file`、
|
|
151
|
+
* 客户端只有 `write_to_file`,整条调用被丢弃)。
|
|
152
|
+
*/
|
|
153
|
+
export function resolveToolName(name, allowed, maps = EMPTY_TOOL_MAPS) {
|
|
154
|
+
if (!name || allowed.length === 0)
|
|
155
|
+
return '';
|
|
156
|
+
if (allowed.includes(name))
|
|
157
|
+
return name;
|
|
158
|
+
const normMap = new Map();
|
|
159
|
+
for (const a of allowed)
|
|
160
|
+
normMap.set(normalizeToolName(a), a);
|
|
161
|
+
const norm = normalizeToolName(name);
|
|
162
|
+
const exact = normMap.get(norm);
|
|
163
|
+
if (exact)
|
|
164
|
+
return exact;
|
|
165
|
+
const low = name.toLowerCase();
|
|
166
|
+
for (const [kind, keys] of TOOL_NAME_ALIAS_PATTERNS) {
|
|
167
|
+
if (!keys.some((k) => low.includes(k)))
|
|
168
|
+
continue;
|
|
169
|
+
const real = maps.name[kind];
|
|
170
|
+
if (real && allowed.includes(real))
|
|
171
|
+
return real;
|
|
172
|
+
// 兜底:在客户端工具里找归一化名含该语义的
|
|
173
|
+
for (const a of allowed) {
|
|
174
|
+
if (normalizeToolName(a).includes(kind))
|
|
175
|
+
return a;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return '';
|
|
179
|
+
}
|
|
180
|
+
/** 生成 `call_` 前缀的工具调用 id(对应 Python `uuid4().hex[:24]`)。 */
|
|
181
|
+
export function makeToolCallId() {
|
|
182
|
+
return `call_${randomUUID().replace(/-/g, '').slice(0, 24)}`;
|
|
183
|
+
}
|
|
184
|
+
/** 通用别名:把各种写法归一化到标准参数名。 */
|
|
185
|
+
const GENERAL_ALIASES = {
|
|
186
|
+
filePath: 'file_path',
|
|
187
|
+
filepath: 'file_path',
|
|
188
|
+
filename: 'file_path',
|
|
189
|
+
fileName: 'file_path',
|
|
190
|
+
};
|
|
191
|
+
/** 需要把 `path` 当作 `file_path` 的工具(`LS` 等用 `path` 表示目录,不映射)。 */
|
|
192
|
+
const PATH_TO_FILE_PATH_TOOLS = new Set([
|
|
193
|
+
'Read',
|
|
194
|
+
'SearchReplace',
|
|
195
|
+
'write_file',
|
|
196
|
+
'Write',
|
|
197
|
+
'Edit',
|
|
198
|
+
'DeleteFile',
|
|
199
|
+
]);
|
|
200
|
+
const SEARCHREPLACE_ALIASES = {
|
|
201
|
+
oldText: 'old_str',
|
|
202
|
+
old_text: 'old_str',
|
|
203
|
+
old_string: 'old_str',
|
|
204
|
+
oldString: 'old_str',
|
|
205
|
+
search: 'old_str',
|
|
206
|
+
find: 'old_str',
|
|
207
|
+
pattern: 'old_str',
|
|
208
|
+
match: 'old_str',
|
|
209
|
+
target: 'old_str',
|
|
210
|
+
newText: 'new_str',
|
|
211
|
+
new_text: 'new_str',
|
|
212
|
+
new_string: 'new_str',
|
|
213
|
+
newString: 'new_str',
|
|
214
|
+
replace: 'new_str',
|
|
215
|
+
replacement: 'new_str',
|
|
216
|
+
replaceWith: 'new_str',
|
|
217
|
+
replace_with: 'new_str',
|
|
218
|
+
};
|
|
219
|
+
const WRITE_FILE_ALIASES = {
|
|
220
|
+
fileContent: 'content',
|
|
221
|
+
file_content: 'content',
|
|
222
|
+
text: 'content',
|
|
223
|
+
data: 'content',
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* 归一化工具参数名(等价于 `_normalize_tool_arguments`)。
|
|
227
|
+
*
|
|
228
|
+
* 规则:标准名的值优先于别名的值(同一目标 key 冲突时不覆盖)。
|
|
229
|
+
*/
|
|
230
|
+
export function normalizeToolArguments(toolName, args) {
|
|
231
|
+
if (!args || Object.keys(args).length === 0)
|
|
232
|
+
return args;
|
|
233
|
+
const name = TOOL_NAME_ALIASES[toolName] ?? toolName;
|
|
234
|
+
const normalized = {};
|
|
235
|
+
for (const [key, value] of Object.entries(args)) {
|
|
236
|
+
let newKey = key;
|
|
237
|
+
let isAlias = false;
|
|
238
|
+
if (key in GENERAL_ALIASES) {
|
|
239
|
+
newKey = GENERAL_ALIASES[key];
|
|
240
|
+
isAlias = true;
|
|
241
|
+
}
|
|
242
|
+
if (key === 'path' && PATH_TO_FILE_PATH_TOOLS.has(name)) {
|
|
243
|
+
newKey = 'file_path';
|
|
244
|
+
isAlias = true;
|
|
245
|
+
}
|
|
246
|
+
if (name === 'SearchReplace' && key in SEARCHREPLACE_ALIASES) {
|
|
247
|
+
newKey = SEARCHREPLACE_ALIASES[key];
|
|
248
|
+
isAlias = true;
|
|
249
|
+
}
|
|
250
|
+
else if ((name === 'write_file' || name === 'Write') && key in WRITE_FILE_ALIASES) {
|
|
251
|
+
newKey = WRITE_FILE_ALIASES[key];
|
|
252
|
+
isAlias = true;
|
|
253
|
+
}
|
|
254
|
+
if (!(newKey in normalized)) {
|
|
255
|
+
normalized[newKey] = value;
|
|
256
|
+
}
|
|
257
|
+
else if (!isAlias) {
|
|
258
|
+
// 目标 key 已存在,但当前是标准名 → 标准名的值更可靠,覆盖
|
|
259
|
+
normalized[newKey] = value;
|
|
260
|
+
}
|
|
261
|
+
// 否则:已存在且当前是别名 → 不覆盖(标准名优先)
|
|
262
|
+
}
|
|
263
|
+
return normalized;
|
|
264
|
+
}
|
|
265
|
+
/** 过滤掉「工具名不在客户端提供列表中」的调用,近似名先映射再保留。 */
|
|
266
|
+
export function filterUnknownToolCalls(toolCalls, tools, maps = EMPTY_TOOL_MAPS) {
|
|
267
|
+
if (!toolCalls || toolCalls.length === 0)
|
|
268
|
+
return { valid: [], dropped: [] };
|
|
269
|
+
if (!tools || tools.length === 0) {
|
|
270
|
+
// 客户端未提供工具列表 → 无法判断,全部放行
|
|
271
|
+
return { valid: [...toolCalls], dropped: [] };
|
|
272
|
+
}
|
|
273
|
+
const realNames = [];
|
|
274
|
+
for (const t of tools) {
|
|
275
|
+
const n = toolNameOf(t);
|
|
276
|
+
if (n)
|
|
277
|
+
realNames.push(n);
|
|
278
|
+
}
|
|
279
|
+
const realNameSet = new Set(realNames);
|
|
280
|
+
/** 兼容 AI 输出标准名(Write/Read/SearchReplace/Edit)的情况。 */
|
|
281
|
+
const COMPAT_STANDARD_NAMES = new Set(['Write', 'Read', 'SearchReplace', 'Edit']);
|
|
282
|
+
const valid = [];
|
|
283
|
+
const dropped = [];
|
|
284
|
+
const mapped = [];
|
|
285
|
+
for (const tc of toolCalls) {
|
|
286
|
+
const name = tc.function?.name ?? '';
|
|
287
|
+
// 客户端真实工具名 → 原样保留
|
|
288
|
+
if (realNameSet.has(name)) {
|
|
289
|
+
valid.push(tc);
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
// ⚠️ 先尝试映射,**再**考虑兼容标准名。
|
|
293
|
+
// Python 版把标准名直接放进 `allowed` 并优先于映射判断,
|
|
294
|
+
// 结果是:模型输出 `SearchReplace`、客户端只有 `replace_in_file` 时,
|
|
295
|
+
// 会原样下发一个客户端并不存在的工具 → IDE 报错。
|
|
296
|
+
// 这里改成「能映射就先映射」,映射不了才用标准名兜底。
|
|
297
|
+
const resolved = resolveToolName(name, realNames, maps);
|
|
298
|
+
if (resolved) {
|
|
299
|
+
valid.push({
|
|
300
|
+
...tc,
|
|
301
|
+
function: {
|
|
302
|
+
...tc.function,
|
|
303
|
+
name: resolved,
|
|
304
|
+
arguments: cleanDomHtml(tc.function.arguments),
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
mapped.push(`${name}→${resolved}`);
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
// 映射不了、但属于兼容标准名 → 保留(客户端也许本身就是标准名风格)
|
|
311
|
+
if (COMPAT_STANDARD_NAMES.has(name)) {
|
|
312
|
+
valid.push(tc);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
dropped.push(tc);
|
|
316
|
+
}
|
|
317
|
+
if (mapped.length > 0) {
|
|
318
|
+
logger.warn({ mapped }, '[tool_calls] 工具名已映射到客户端真实名称');
|
|
319
|
+
}
|
|
320
|
+
if (dropped.length > 0) {
|
|
321
|
+
const droppedNames = dropped.map((tc) => tc.function?.name ?? '');
|
|
322
|
+
logger.warn({ names: droppedNames }, `[tool_calls] 丢弃 ${dropped.length} 个未知工具名的调用(客户端未提供该工具)`);
|
|
323
|
+
const builtin = droppedNames.filter((n) => PLATFORM_BUILTIN_TOOL_NAMES.has(n.toLowerCase()));
|
|
324
|
+
if (builtin.length > 0) {
|
|
325
|
+
logger.warn({ builtin }, '[tool_calls] 模型调用了平台自带工具(不是客户端工具)——它在用网页端的联网搜索/浏览能力;' +
|
|
326
|
+
'请检查提示词中的「禁止联网搜索」约束');
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return { valid, dropped };
|
|
330
|
+
}
|
|
331
|
+
function paramSurfaceOf(tool) {
|
|
332
|
+
const name = toolNameOf(tool);
|
|
333
|
+
if (!name)
|
|
334
|
+
return null;
|
|
335
|
+
const props = Object.keys(tool?.function?.parameters?.properties ?? {});
|
|
336
|
+
// 没声明参数面的工具(或声明成空对象)无法参与判断 —— 跳过,别瞎猜
|
|
337
|
+
if (props.length === 0)
|
|
338
|
+
return null;
|
|
339
|
+
return {
|
|
340
|
+
name,
|
|
341
|
+
props: new Set(props),
|
|
342
|
+
required: new Set(toolRequiredParams(tool)),
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
/** 解析 `arguments`(OpenAI 形态是 JSON 字符串);解析失败返回 null。 */
|
|
346
|
+
function parseArgs(tc) {
|
|
347
|
+
const raw = tc.function?.arguments;
|
|
348
|
+
if (!raw)
|
|
349
|
+
return null;
|
|
350
|
+
if (typeof raw === 'object')
|
|
351
|
+
return raw;
|
|
352
|
+
try {
|
|
353
|
+
const parsed = JSON.parse(raw);
|
|
354
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
355
|
+
? parsed
|
|
356
|
+
: null;
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* 按「参数签名」纠正选错的工具。
|
|
364
|
+
*
|
|
365
|
+
* ## 解决的真实问题(2026-10-14,xzh 实测)
|
|
366
|
+
* 模型想**创建**文件,却调了 `edit_file` 并套用 `write_file` 的签名
|
|
367
|
+
* (`edit_file(path, content)`)。客户端校验签名直接拒收:
|
|
368
|
+
* `edit_file 收到未知参数 "content"。可用参数:"path"、"search"、"replace"`。
|
|
369
|
+
* 模型虽然能在下一轮思考里自我纠正(日志里它自己说
|
|
370
|
+
* "I used the wrong tool — edit_file needs path/search/replace, not content"),
|
|
371
|
+
* 但那一轮已经烧掉了客户端的一次工具往返,用户看到的就是一条报错。
|
|
372
|
+
*
|
|
373
|
+
* ## 规则(**保守**:只在能确定时动手)
|
|
374
|
+
* 对每个调用:
|
|
375
|
+
* 1. 按名字找到声明的工具;它的签名**装得下**全部参数 → 原样保留;
|
|
376
|
+
* 2. 装不下(存在未知参数)→ 在**其余**声明工具里找「能装下全部参数、
|
|
377
|
+
* 且必填参数都被满足」的候选:
|
|
378
|
+
* - 恰好 **1 个** → 改派给它(`edit_file(path,content)` → `write_file`);
|
|
379
|
+
* - 0 个或 ≥2 个 → **原样保留**。0 个说明没有更好的去处;≥2 个说明有歧义,
|
|
380
|
+
* 猜错比让客户端拒绝更糟(可能改写到错误的文件)。
|
|
381
|
+
* 3. 名字本身就不在声明列表里的调用**不碰**(那是 {@link filterUnknownToolCalls} 的职责)。
|
|
382
|
+
*
|
|
383
|
+
* @returns 修好的调用数组 + 改派记录(调用方负责打日志)
|
|
384
|
+
*/
|
|
385
|
+
export function repairToolCallBySignature(toolCalls, tools) {
|
|
386
|
+
if (!toolCalls || toolCalls.length === 0)
|
|
387
|
+
return { repaired: [], reroutes: [] };
|
|
388
|
+
if (!tools || tools.length === 0)
|
|
389
|
+
return { repaired: [...toolCalls], reroutes: [] };
|
|
390
|
+
const surfaces = [];
|
|
391
|
+
for (const t of tools) {
|
|
392
|
+
const s = paramSurfaceOf(t);
|
|
393
|
+
if (s)
|
|
394
|
+
surfaces.push(s);
|
|
395
|
+
}
|
|
396
|
+
// 连参数面都拿不到 → 无法判断,全部放行
|
|
397
|
+
if (surfaces.length === 0)
|
|
398
|
+
return { repaired: [...toolCalls], reroutes: [] };
|
|
399
|
+
const byName = new Map();
|
|
400
|
+
for (const s of surfaces)
|
|
401
|
+
byName.set(s.name, s);
|
|
402
|
+
const repaired = [];
|
|
403
|
+
const reroutes = [];
|
|
404
|
+
for (const tc of toolCalls) {
|
|
405
|
+
const name = tc.function?.name ?? '';
|
|
406
|
+
const declared = byName.get(name);
|
|
407
|
+
// 名字未知,或声明工具没有参数面 → 不归本函数管
|
|
408
|
+
if (!declared) {
|
|
409
|
+
repaired.push(tc);
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
const args = parseArgs(tc);
|
|
413
|
+
if (!args) {
|
|
414
|
+
repaired.push(tc);
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
const keys = Object.keys(args);
|
|
418
|
+
const unknownKeys = keys.filter((k) => !declared.props.has(k));
|
|
419
|
+
// 签名装得下 → 不动
|
|
420
|
+
if (unknownKeys.length === 0) {
|
|
421
|
+
repaired.push(tc);
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
// 找「能装下全部参数、且必填都被满足」的其它工具
|
|
425
|
+
const candidates = surfaces.filter((s) => s.name !== declared.name &&
|
|
426
|
+
keys.every((k) => s.props.has(k)) &&
|
|
427
|
+
[...s.required].every((r) => keys.includes(r)));
|
|
428
|
+
if (candidates.length === 1) {
|
|
429
|
+
const target = candidates[0];
|
|
430
|
+
reroutes.push({ from: name, to: target.name, unknownKeys });
|
|
431
|
+
repaired.push({
|
|
432
|
+
...tc,
|
|
433
|
+
function: { ...tc.function, name: target.name, arguments: JSON.stringify(args) },
|
|
434
|
+
});
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
// 0 个(没有更好的去处)或 ≥2 个(有歧义)→ 原样交给客户端裁决
|
|
438
|
+
repaired.push(tc);
|
|
439
|
+
}
|
|
440
|
+
return { repaired, reroutes };
|
|
441
|
+
}
|
|
442
|
+
/* ==================================================================== */
|
|
443
|
+
/* 「拿文件路径参数当命令用」→ 改派给命令执行工具 */
|
|
444
|
+
/* ==================================================================== */
|
|
445
|
+
/**
|
|
446
|
+
* 命令动词前缀 —— **必须带尾随空格**。
|
|
447
|
+
*
|
|
448
|
+
* ⚠️ 不带空格会把相对路径误伤(`python_utils/app.py` 以 `python` 开头)。
|
|
449
|
+
*/
|
|
450
|
+
const SHELL_COMMAND_PREFIXES = [
|
|
451
|
+
'cd ',
|
|
452
|
+
'rm ',
|
|
453
|
+
'rmdir ',
|
|
454
|
+
'ls ',
|
|
455
|
+
'mkdir ',
|
|
456
|
+
'mv ',
|
|
457
|
+
'cp ',
|
|
458
|
+
'cat ',
|
|
459
|
+
'echo ',
|
|
460
|
+
'touch ',
|
|
461
|
+
'chmod ',
|
|
462
|
+
'chown ',
|
|
463
|
+
'kill ',
|
|
464
|
+
'pkill ',
|
|
465
|
+
'ps ',
|
|
466
|
+
'source ',
|
|
467
|
+
'export ',
|
|
468
|
+
'git ',
|
|
469
|
+
'npm ',
|
|
470
|
+
'npx ',
|
|
471
|
+
'node ',
|
|
472
|
+
'python ',
|
|
473
|
+
'python3 ',
|
|
474
|
+
'bash ',
|
|
475
|
+
'sh ',
|
|
476
|
+
'zsh ',
|
|
477
|
+
'nohup ',
|
|
478
|
+
'curl ',
|
|
479
|
+
'wget ',
|
|
480
|
+
'tar ',
|
|
481
|
+
'find ',
|
|
482
|
+
'grep ',
|
|
483
|
+
'sed ',
|
|
484
|
+
'awk ',
|
|
485
|
+
'sudo ',
|
|
486
|
+
'./',
|
|
487
|
+
];
|
|
488
|
+
/** shell 里的连接符/元字符(正常文件路径不会出现)。 */
|
|
489
|
+
const SHELL_METACHARS = /(?:&&|\|\||[;|]|>>?|\$\(|`)/;
|
|
490
|
+
/** 路径类参数名(归一化后)。 */
|
|
491
|
+
const PATH_LIKE_PARAM_KINDS = ['path', 'filepath', 'filename', 'file'];
|
|
492
|
+
/** 命令执行类参数名(归一化后)—— 用来在客户端工具里找「命令执行工具」。 */
|
|
493
|
+
const COMMAND_PARAM_KINDS = ['command', 'cmd', 'script', 'shell'];
|
|
494
|
+
/**
|
|
495
|
+
* 值是否**明显是 shell 命令**而不是文件路径。
|
|
496
|
+
*
|
|
497
|
+
* 判据(保守,宁可漏判也不误判 —— 误判会把一条普通路径当命令执行):
|
|
498
|
+
* 1. 以命令动词 + 空格开头(`cd /x && ./start.sh` / `ls -la`);或
|
|
499
|
+
* 2. 以 `./` 开头(运行脚本的写法);
|
|
500
|
+
* 3. 否则:以 `/`、`~` 开头的一律当路径;其余只有含 `&&`/`;`/`|`/`>`/反引号/`$(` 才算命令。
|
|
501
|
+
*/
|
|
502
|
+
export function looksLikeShellCommand(value) {
|
|
503
|
+
const v = (value ?? '').trim();
|
|
504
|
+
if (!v || v.length > 2000)
|
|
505
|
+
return false;
|
|
506
|
+
if (SHELL_COMMAND_PREFIXES.some((p) => v.startsWith(p)))
|
|
507
|
+
return true;
|
|
508
|
+
if (v.startsWith('/') || v.startsWith('~'))
|
|
509
|
+
return false;
|
|
510
|
+
return SHELL_METACHARS.test(v);
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* 把「拿文件路径参数当命令用」的调用改派给客户端的命令执行工具。
|
|
514
|
+
*
|
|
515
|
+
* ## 真实事故(2026-10-14,xzh 实测)
|
|
516
|
+
* 模型想跑 `cd /home/amble/object/btc && ./start.sh`,却把它塞进 `write_file` 的
|
|
517
|
+
* `path` 参数 → 客户端**真的在工作目录里创建了一个名叫 `cd /home/...` 的文件**,
|
|
518
|
+
* 下一轮又用 `rm -f` / `rmdir 'cd'` 去收拾自己造的垃圾,任务彻底跑偏。
|
|
519
|
+
*
|
|
520
|
+
* ## 规则(保守:只在能确定时动手)
|
|
521
|
+
* 1. 只看**路径类**参数的值(`path` / `file_path` / `filePath` / `filename` / `file`);
|
|
522
|
+
* 2. 值必须明显是 shell 命令(见 {@link looksLikeShellCommand});
|
|
523
|
+
* 3. 客户端声明的工具里**恰好有一个**带 `command`/`cmd`/`script`/`shell` 参数的工具
|
|
524
|
+
* → 把命令原文改派给它(其余参数不必带过去:它们本来就是误填的);
|
|
525
|
+
* **0 个或 ≥2 个候选都不动手**(猜错比让客户端拒绝更糟)。
|
|
526
|
+
*
|
|
527
|
+
* @returns 修好的调用数组 + 改派记录(调用方负责打日志)
|
|
528
|
+
*/
|
|
529
|
+
export function rerouteCommandMisuse(toolCalls, tools) {
|
|
530
|
+
if (!toolCalls || toolCalls.length === 0)
|
|
531
|
+
return { repaired: [], reroutes: [] };
|
|
532
|
+
if (!tools || tools.length === 0)
|
|
533
|
+
return { repaired: [...toolCalls], reroutes: [] };
|
|
534
|
+
// 找「命令执行工具」:恰好一个候选才动手
|
|
535
|
+
const candidates = [];
|
|
536
|
+
const declared = new Set();
|
|
537
|
+
for (const tool of tools) {
|
|
538
|
+
const name = toolNameOf(tool);
|
|
539
|
+
if (!name)
|
|
540
|
+
continue;
|
|
541
|
+
declared.add(name);
|
|
542
|
+
const props = Object.keys(tool?.function?.parameters?.properties ?? {});
|
|
543
|
+
const hit = props.find((p) => COMMAND_PARAM_KINDS.includes(normalizeParamKey(p)));
|
|
544
|
+
if (hit)
|
|
545
|
+
candidates.push({ name, param: hit });
|
|
546
|
+
}
|
|
547
|
+
const target = candidates.length === 1 ? candidates[0] : undefined;
|
|
548
|
+
const repaired = [];
|
|
549
|
+
const reroutes = [];
|
|
550
|
+
for (const tc of toolCalls) {
|
|
551
|
+
const name = tc.function?.name ?? '';
|
|
552
|
+
const args = parseArgs(tc);
|
|
553
|
+
// 没有唯一的命令执行工具(或名字不由客户端声明)→ 不碰
|
|
554
|
+
if (!target || !args || !declared.has(name) || name === target.name) {
|
|
555
|
+
repaired.push(tc);
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
const misuse = Object.entries(args).find(([key, value]) => PATH_LIKE_PARAM_KINDS.includes(normalizeParamKey(key)) &&
|
|
559
|
+
typeof value === 'string' &&
|
|
560
|
+
looksLikeShellCommand(value));
|
|
561
|
+
if (!misuse) {
|
|
562
|
+
repaired.push(tc);
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
const command = String(misuse[1]);
|
|
566
|
+
reroutes.push({ from: name, to: target.name, commandPreview: command.slice(0, 120) });
|
|
567
|
+
repaired.push({
|
|
568
|
+
...tc,
|
|
569
|
+
function: {
|
|
570
|
+
...tc.function,
|
|
571
|
+
name: target.name,
|
|
572
|
+
arguments: JSON.stringify({ [target.param]: command }),
|
|
573
|
+
},
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
return { repaired, reroutes };
|
|
577
|
+
}
|
|
578
|
+
//# sourceMappingURL=names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/tools/names.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ToolCallPayload } from '../types/message.js';
|
|
2
|
+
import { type ToolMaps } from './names.js';
|
|
3
|
+
/**
|
|
4
|
+
* 等价于 Python `json.JSONDecoder().raw_decode(text, pos)`。
|
|
5
|
+
*
|
|
6
|
+
* 从 `text[pos]` 开始解析**第一个完整的 JSON 值**,返回其结束位置(**绝对下标**)。
|
|
7
|
+
* Python 的 `raw_decode` 允许后面还有别的内容,JS 的 `JSON.parse` 不允许,
|
|
8
|
+
* 所以这里自己扫括号配平(正确处理字符串与转义),再对切片做 `JSON.parse`。
|
|
9
|
+
*
|
|
10
|
+
* @param pos 起始下标;ChatGLM 的 SSE 报文会把多个 JSON 直接拼在一行,
|
|
11
|
+
* 需要从任意位置连续往后扫(`pos` 让调用方免于反复 `slice`,避免 O(n²))。
|
|
12
|
+
*/
|
|
13
|
+
export declare function rawDecodeJson(text: string, pos?: number): {
|
|
14
|
+
value: unknown;
|
|
15
|
+
end: number;
|
|
16
|
+
} | undefined;
|
|
17
|
+
/** 结果对象。 */
|
|
18
|
+
export interface ParseResult {
|
|
19
|
+
/** 移除工具调用块之后的剩余正文。 */
|
|
20
|
+
text: string;
|
|
21
|
+
/** OpenAI 格式的工具调用列表。 */
|
|
22
|
+
toolCalls: ToolCallPayload[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 从 AI 回复文本中解析工具调用。
|
|
26
|
+
*
|
|
27
|
+
* @param text AI 完整回复
|
|
28
|
+
* @param maps 本请求的工具映射表(决定了标准名会映射到哪个客户端真实工具名)
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseToolCallsFromText(text: string, maps?: ToolMaps): ParseResult;
|
|
31
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/tools/parse.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAE,KAAK,QAAQ,EAAmB,MAAM,YAAY,CAAC;AAkC5D;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,GAAG,SAAI,GACN;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA0C7C;AAQD,YAAY;AACZ,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,QAA0B,GAC/B,WAAW,CA2Kb"}
|