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.
Files changed (205) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -2
  3. package/bin/webapi.mjs +45 -0
  4. package/dist/browser/auth-capture.d.ts +110 -0
  5. package/dist/browser/auth-capture.d.ts.map +1 -0
  6. package/dist/browser/auth-capture.js +487 -0
  7. package/dist/browser/auth-capture.js.map +1 -0
  8. package/dist/browser/credentials.d.ts +102 -0
  9. package/dist/browser/credentials.d.ts.map +1 -0
  10. package/dist/browser/credentials.js +209 -0
  11. package/dist/browser/credentials.js.map +1 -0
  12. package/dist/browser/js-eval.d.ts +44 -0
  13. package/dist/browser/js-eval.d.ts.map +1 -0
  14. package/dist/browser/js-eval.js +20 -0
  15. package/dist/browser/js-eval.js.map +1 -0
  16. package/dist/browser/login-flow.d.ts +171 -0
  17. package/dist/browser/login-flow.d.ts.map +1 -0
  18. package/dist/browser/login-flow.js +606 -0
  19. package/dist/browser/login-flow.js.map +1 -0
  20. package/dist/browser/manager.d.ts +144 -0
  21. package/dist/browser/manager.d.ts.map +1 -0
  22. package/dist/browser/manager.js +586 -0
  23. package/dist/browser/manager.js.map +1 -0
  24. package/dist/browser/platforms.d.ts +96 -0
  25. package/dist/browser/platforms.d.ts.map +1 -0
  26. package/dist/browser/platforms.js +288 -0
  27. package/dist/browser/platforms.js.map +1 -0
  28. package/dist/browser/sse-capture.d.ts +23 -0
  29. package/dist/browser/sse-capture.d.ts.map +1 -0
  30. package/dist/browser/sse-capture.js +199 -0
  31. package/dist/browser/sse-capture.js.map +1 -0
  32. package/dist/browser/stealth.d.ts +12 -0
  33. package/dist/browser/stealth.d.ts.map +1 -0
  34. package/dist/browser/stealth.js +12 -0
  35. package/dist/browser/stealth.js.map +1 -0
  36. package/dist/cli.d.ts +12 -0
  37. package/dist/cli.d.ts.map +1 -0
  38. package/dist/cli.js +441 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/config.d.ts +90 -0
  41. package/dist/config.d.ts.map +1 -0
  42. package/dist/config.js +246 -0
  43. package/dist/config.js.map +1 -0
  44. package/dist/controllers/history-db.d.ts +56 -0
  45. package/dist/controllers/history-db.d.ts.map +1 -0
  46. package/dist/controllers/history-db.js +260 -0
  47. package/dist/controllers/history-db.js.map +1 -0
  48. package/dist/controllers/request-pool.d.ts +78 -0
  49. package/dist/controllers/request-pool.d.ts.map +1 -0
  50. package/dist/controllers/request-pool.js +222 -0
  51. package/dist/controllers/request-pool.js.map +1 -0
  52. package/dist/controllers/router.d.ts +172 -0
  53. package/dist/controllers/router.d.ts.map +1 -0
  54. package/dist/controllers/router.js +569 -0
  55. package/dist/controllers/router.js.map +1 -0
  56. package/dist/index.d.ts +72 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +61 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/log/api-logger.d.ts +55 -0
  61. package/dist/log/api-logger.d.ts.map +1 -0
  62. package/dist/log/api-logger.js +264 -0
  63. package/dist/log/api-logger.js.map +1 -0
  64. package/dist/log/debug-logger.d.ts +49 -0
  65. package/dist/log/debug-logger.d.ts.map +1 -0
  66. package/dist/log/debug-logger.js +285 -0
  67. package/dist/log/debug-logger.js.map +1 -0
  68. package/dist/log/logger.d.ts +16 -0
  69. package/dist/log/logger.d.ts.map +1 -0
  70. package/dist/log/logger.js +35 -0
  71. package/dist/log/logger.js.map +1 -0
  72. package/dist/postinstall.d.ts +3 -0
  73. package/dist/postinstall.d.ts.map +1 -0
  74. package/dist/postinstall.js +90 -0
  75. package/dist/postinstall.js.map +1 -0
  76. package/dist/providers/base.d.ts +83 -0
  77. package/dist/providers/base.d.ts.map +1 -0
  78. package/dist/providers/base.js +51 -0
  79. package/dist/providers/base.js.map +1 -0
  80. package/dist/providers/chatglm-dom-extract.d.ts +24 -0
  81. package/dist/providers/chatglm-dom-extract.d.ts.map +1 -0
  82. package/dist/providers/chatglm-dom-extract.js +175 -0
  83. package/dist/providers/chatglm-dom-extract.js.map +1 -0
  84. package/dist/providers/chatglm-dom.d.ts +110 -0
  85. package/dist/providers/chatglm-dom.d.ts.map +1 -0
  86. package/dist/providers/chatglm-dom.js +384 -0
  87. package/dist/providers/chatglm-dom.js.map +1 -0
  88. package/dist/providers/chatglm-sse.d.ts +119 -0
  89. package/dist/providers/chatglm-sse.d.ts.map +1 -0
  90. package/dist/providers/chatglm-sse.js +241 -0
  91. package/dist/providers/chatglm-sse.js.map +1 -0
  92. package/dist/providers/chatglm.d.ts +288 -0
  93. package/dist/providers/chatglm.d.ts.map +1 -0
  94. package/dist/providers/chatglm.js +1631 -0
  95. package/dist/providers/chatglm.js.map +1 -0
  96. package/dist/routes/chat.d.ts +117 -0
  97. package/dist/routes/chat.d.ts.map +1 -0
  98. package/dist/routes/chat.js +1346 -0
  99. package/dist/routes/chat.js.map +1 -0
  100. package/dist/routes/compress.d.ts +142 -0
  101. package/dist/routes/compress.d.ts.map +1 -0
  102. package/dist/routes/compress.js +551 -0
  103. package/dist/routes/compress.js.map +1 -0
  104. package/dist/routes/failover.d.ts +34 -0
  105. package/dist/routes/failover.d.ts.map +1 -0
  106. package/dist/routes/failover.js +221 -0
  107. package/dist/routes/failover.js.map +1 -0
  108. package/dist/routes/helpers.d.ts +174 -0
  109. package/dist/routes/helpers.d.ts.map +1 -0
  110. package/dist/routes/helpers.js +525 -0
  111. package/dist/routes/helpers.js.map +1 -0
  112. package/dist/routes/meta.d.ts +31 -0
  113. package/dist/routes/meta.d.ts.map +1 -0
  114. package/dist/routes/meta.js +184 -0
  115. package/dist/routes/meta.js.map +1 -0
  116. package/dist/routes/sse.d.ts +82 -0
  117. package/dist/routes/sse.d.ts.map +1 -0
  118. package/dist/routes/sse.js +77 -0
  119. package/dist/routes/sse.js.map +1 -0
  120. package/dist/server/app.d.ts +24 -0
  121. package/dist/server/app.d.ts.map +1 -0
  122. package/dist/server/app.js +292 -0
  123. package/dist/server/app.js.map +1 -0
  124. package/dist/server/middleware/api-key.d.ts +61 -0
  125. package/dist/server/middleware/api-key.d.ts.map +1 -0
  126. package/dist/server/middleware/api-key.js +95 -0
  127. package/dist/server/middleware/api-key.js.map +1 -0
  128. package/dist/server/middleware/rate-limit.d.ts +67 -0
  129. package/dist/server/middleware/rate-limit.d.ts.map +1 -0
  130. package/dist/server/middleware/rate-limit.js +134 -0
  131. package/dist/server/middleware/rate-limit.js.map +1 -0
  132. package/dist/server/middleware/timeout.d.ts +34 -0
  133. package/dist/server/middleware/timeout.d.ts.map +1 -0
  134. package/dist/server/middleware/timeout.js +64 -0
  135. package/dist/server/middleware/timeout.js.map +1 -0
  136. package/dist/server/types.d.ts +20 -0
  137. package/dist/server/types.d.ts.map +1 -0
  138. package/dist/server/types.js +2 -0
  139. package/dist/server/types.js.map +1 -0
  140. package/dist/tools/build.d.ts +14 -0
  141. package/dist/tools/build.d.ts.map +1 -0
  142. package/dist/tools/build.js +105 -0
  143. package/dist/tools/build.js.map +1 -0
  144. package/dist/tools/clean.d.ts +32 -0
  145. package/dist/tools/clean.d.ts.map +1 -0
  146. package/dist/tools/clean.js +65 -0
  147. package/dist/tools/clean.js.map +1 -0
  148. package/dist/tools/convert.d.ts +50 -0
  149. package/dist/tools/convert.d.ts.map +1 -0
  150. package/dist/tools/convert.js +289 -0
  151. package/dist/tools/convert.js.map +1 -0
  152. package/dist/tools/names.d.ts +138 -0
  153. package/dist/tools/names.d.ts.map +1 -0
  154. package/dist/tools/names.js +578 -0
  155. package/dist/tools/names.js.map +1 -0
  156. package/dist/tools/parse.d.ts +31 -0
  157. package/dist/tools/parse.d.ts.map +1 -0
  158. package/dist/tools/parse.js +273 -0
  159. package/dist/tools/parse.js.map +1 -0
  160. package/dist/tools/placeholder.d.ts +21 -0
  161. package/dist/tools/placeholder.d.ts.map +1 -0
  162. package/dist/tools/placeholder.js +135 -0
  163. package/dist/tools/placeholder.js.map +1 -0
  164. package/dist/tools/prompts.d.ts +42 -0
  165. package/dist/tools/prompts.d.ts.map +1 -0
  166. package/dist/tools/prompts.js +69 -0
  167. package/dist/tools/prompts.js.map +1 -0
  168. package/dist/tools/protocol.d.ts +58 -0
  169. package/dist/tools/protocol.d.ts.map +1 -0
  170. package/dist/tools/protocol.js +287 -0
  171. package/dist/tools/protocol.js.map +1 -0
  172. package/dist/tools/repair.d.ts +83 -0
  173. package/dist/tools/repair.d.ts.map +1 -0
  174. package/dist/tools/repair.js +510 -0
  175. package/dist/tools/repair.js.map +1 -0
  176. package/dist/tools/workspace.d.ts +40 -0
  177. package/dist/tools/workspace.d.ts.map +1 -0
  178. package/dist/tools/workspace.js +224 -0
  179. package/dist/tools/workspace.js.map +1 -0
  180. package/dist/types/message.d.ts +87 -0
  181. package/dist/types/message.d.ts.map +1 -0
  182. package/dist/types/message.js +85 -0
  183. package/dist/types/message.js.map +1 -0
  184. package/dist/types/openai.d.ts +100 -0
  185. package/dist/types/openai.d.ts.map +1 -0
  186. package/dist/types/openai.js +66 -0
  187. package/dist/types/openai.js.map +1 -0
  188. package/dist/utils/errors.d.ts +82 -0
  189. package/dist/utils/errors.d.ts.map +1 -0
  190. package/dist/utils/errors.js +115 -0
  191. package/dist/utils/errors.js.map +1 -0
  192. package/dist/utils/mutex.d.ts +31 -0
  193. package/dist/utils/mutex.d.ts.map +1 -0
  194. package/dist/utils/mutex.js +61 -0
  195. package/dist/utils/mutex.js.map +1 -0
  196. package/dist/utils/prompt.d.ts +150 -0
  197. package/dist/utils/prompt.d.ts.map +1 -0
  198. package/dist/utils/prompt.js +514 -0
  199. package/dist/utils/prompt.js.map +1 -0
  200. package/dist/utils/text.d.ts +30 -0
  201. package/dist/utils/text.d.ts.map +1 -0
  202. package/dist/utils/text.js +70 -0
  203. package/dist/utils/text.js.map +1 -0
  204. package/package.json +67 -4
  205. package/postinstall.mjs +34 -0
@@ -0,0 +1,289 @@
1
+ import { toolNameOf, toolParamNames } from '../types/message.js';
2
+ import { detectToolNames, makeToolCallId, normalizeParamKey } from './names.js';
3
+ import { PY_W_CHARS } from './repair.js';
4
+ /** 常见源代码扩展名。 */
5
+ const CODE_EXTENSIONS = [
6
+ '.py', '.js', '.ts', '.tsx', '.jsx', '.java', '.go', '.rs', '.c', '.cpp',
7
+ '.h', '.rb', '.php', '.sh', '.bash', '.zsh', '.sql', '.html', '.css',
8
+ '.json', '.yaml', '.yml', '.toml', '.xml', '.md', '.txt', '.ini', '.cfg',
9
+ '.env', '.gitignore', '.dockerfile', '.makefile',
10
+ ];
11
+ /** 带文件路径的代码块:```lang path/to/file */
12
+ const CODE_BLOCK_WITH_PATH = /```(\w+)?[:\s]+([^\n]+?)\n(.*?)```/gsu;
13
+ /** 「文件: path」后跟代码块。 */
14
+ const FILE_REF_PATTERN = /(?:文件[::]\s*|创建文件[::]\s*|新建文件[::]\s*|\/\/\s*|File:\s*)([^\n]+\.\w+)\s*\n```(\w+)?\s*\n(.*?)```/gsu;
15
+ /**
16
+ * 判断字符串是否像文件路径。
17
+ *
18
+ * 注意:只用来**排除明显不是路径**的代码块首行,宁可放宽也不要漏判。
19
+ */
20
+ export function looksLikeFilepath(s, _lang = '') {
21
+ if (!s || s.length > 200)
22
+ return false;
23
+ const trimmed = s.trim();
24
+ if (trimmed.includes('/') || trimmed.includes('\\')) {
25
+ if (trimmed.startsWith('http://') || trimmed.startsWith('https://'))
26
+ return false;
27
+ return true;
28
+ }
29
+ const lower = trimmed.toLowerCase();
30
+ if (CODE_EXTENSIONS.some((ext) => lower.endsWith(ext)))
31
+ return true;
32
+ // 点开头但不是相对路径引用(如 .bashrc)
33
+ if (trimmed.startsWith('.') && !trimmed.startsWith('..') && trimmed.length < 50)
34
+ return true;
35
+ return false;
36
+ }
37
+ /**
38
+ * 路径类参数的归一化名集合。
39
+ * ⚠️ 用归一化名(去除非字母、转小写)比较,而不是直接比对字面量 ——
40
+ * Python 版写的是 `p in ("file_path","path","filepath","filename")`,
41
+ * **匹配不到驼峰的 `filePath`**(CodeBuddy 正是这种命名),
42
+ * 于是回退成 `file_path` 并原样发给客户端 → 客户端报「未知参数」。
43
+ */
44
+ const PATH_PARAM_KEYS = new Set(['filepath', 'path', 'filename']);
45
+ /** 内容类参数的归一化名集合。 */
46
+ const CONTENT_PARAM_KEYS = new Set(['content', 'code', 'text', 'body']);
47
+ /** 按工具声明的参数名构建写文件参数(兼容 `file_path`/`filePath`、`content`/`code`)。 */
48
+ export function buildWriteArgs(paramNames, filepath, content) {
49
+ const args = {};
50
+ let pathSet = false;
51
+ for (const p of paramNames) {
52
+ if (PATH_PARAM_KEYS.has(normalizeParamKey(p))) {
53
+ args[p] = filepath;
54
+ pathSet = true;
55
+ break;
56
+ }
57
+ }
58
+ if (!pathSet)
59
+ args['file_path'] = filepath;
60
+ let contentSet = false;
61
+ for (const p of paramNames) {
62
+ if (CONTENT_PARAM_KEYS.has(normalizeParamKey(p))) {
63
+ args[p] = content;
64
+ contentSet = true;
65
+ break;
66
+ }
67
+ }
68
+ if (!contentSet)
69
+ args['content'] = content;
70
+ return args;
71
+ }
72
+ /** 从用户请求和内容推断文件名。 */
73
+ export function inferFilename(userRequest, content) {
74
+ const nameMatch = /(?:创建|新建|生成|write|create)\s+[::]?\s*([^\s,,]+?\.\w+)/u.exec(userRequest);
75
+ if (nameMatch)
76
+ return nameMatch[1];
77
+ if (content.trim().startsWith('#')) {
78
+ const titleMatch = /^#+\s+(.+)/mu.exec(content);
79
+ if (titleMatch) {
80
+ const title = titleMatch[1].trim();
81
+ const clean = title.replace(/[^\p{L}\p{N}_\s-]/gu, '').trim().replace(/\s+/g, '_');
82
+ return `${clean}.md`;
83
+ }
84
+ return 'README.md';
85
+ }
86
+ const firstLine = content.trim().split('\n')[0] ?? '';
87
+ const lowerFirst = firstLine.toLowerCase();
88
+ if (lowerFirst.includes('python') || firstLine.startsWith('import ') || firstLine.startsWith('from ')) {
89
+ return 'main.py';
90
+ }
91
+ if (lowerFirst.includes('javascript') ||
92
+ firstLine.startsWith('const ') ||
93
+ firstLine.startsWith('function ')) {
94
+ return 'index.js';
95
+ }
96
+ if (firstLine.startsWith('<?xml') || firstLine.startsWith('<'))
97
+ return 'config.xml';
98
+ if (firstLine.includes('{') && (firstLine.includes('"') || firstLine.includes("'"))) {
99
+ return 'config.json';
100
+ }
101
+ return 'README.md';
102
+ }
103
+ /** 计划性语言(出现即判定为「描述」而非「文件内容」)。 */
104
+ const PLANNING_PATTERNS = [
105
+ /我先/u, /让我先/u, /首先让我/u, /接下来我会/u,
106
+ /我将先/u, /我先读取/u, /我先查看/u, /让我读取/u,
107
+ /I'll (?:first |then )?read/i, /Let me (?:first |then )?read/i,
108
+ /让我先检查/u, /首先读取/u,
109
+ ];
110
+ /**
111
+ * 判断 AI 回复是否像**文件内容**(而不是描述性/计划性文字)。
112
+ *
113
+ * 满足任一即触发:markdown 标题开头且够长、含带路径的代码块、
114
+ * 3+ 个代码块、代码行占比 > 40%、看起来是完整 HTML。
115
+ */
116
+ export function looksLikeFileContent(text) {
117
+ if (text.length < 300)
118
+ return false;
119
+ const head = text.slice(0, 500);
120
+ if (PLANNING_PATTERNS.some((p) => p.test(head)))
121
+ return false;
122
+ if (text.trim().startsWith('#') && text.length > 500)
123
+ return true;
124
+ const stripped = text.trim();
125
+ if ((stripped.startsWith('<!DOCTYPE') || stripped.startsWith('<html')) &&
126
+ text.length > 500) {
127
+ return true;
128
+ }
129
+ if (stripped.startsWith('html\n') && stripped.slice(0, 200).includes('<!DOCTYPE'))
130
+ return true;
131
+ if (/```(\w+)[:\s]+([^\n]+?)\n/u.test(text))
132
+ return true;
133
+ const fenceCount = (text.match(/```/g) ?? []).length;
134
+ if (fenceCount >= 6)
135
+ return true; // 3 个代码块 = 6 个围栏
136
+ const lines = text.split('\n');
137
+ if (lines.length > 20) {
138
+ const codeLike = lines.filter((l) => l.trim() !== '' &&
139
+ !/^\s*[^\x00-\x7F]/u.test(l) &&
140
+ /^\s*(\/\/|#|<|>|from |import |def |class |const |let |var |if |for |while |return )/u.test(l)).length;
141
+ if (codeLike / lines.length > 0.4)
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ /**
147
+ * 找出客户端**真实的**写文件工具名与它的参数名列表。
148
+ *
149
+ * ⚠️ 与原设计不同处:Python 版直接 `tool_names.get("write_file") or "write_file"`,
150
+ * **硬编码了 `write_file`**。当客户端用的是 `write_to_file`(CodeBuddy)时,
151
+ * 产出的调用指向一个客户端不存在的工具 —— 正是「转换成功但 IDE 不执行」的成因。
152
+ * 这里改为优先用参数特征探测(`detectToolNames`),再退回名字匹配。
153
+ */
154
+ function resolveWriteTool(tools) {
155
+ const detected = detectToolNames(tools);
156
+ const candidate = detected['write'] ?? detected['edit'];
157
+ if (candidate) {
158
+ const tool = tools.find((t) => toolNameOf(t) === candidate);
159
+ return { name: candidate, params: tool ? toolParamNames(tool) : [] };
160
+ }
161
+ for (const key of ['write_file', 'edit_file']) {
162
+ const tool = tools.find((t) => toolNameOf(t).toLowerCase() === key);
163
+ if (tool)
164
+ return { name: toolNameOf(tool), params: toolParamNames(tool) };
165
+ }
166
+ return { name: 'write_file', params: [] };
167
+ }
168
+ /**
169
+ * 从纯文本回复里提取「带路径的代码块」并转成写文件调用。
170
+ *
171
+ * 没提取到时返回 `(原文本, [])` —— 调用方务必检查是否真的提取到了。
172
+ */
173
+ export function convertTextToToolCalls(text, tools) {
174
+ const pairs = [];
175
+ for (const match of text.matchAll(CODE_BLOCK_WITH_PATH)) {
176
+ const lang = match[1] ?? '';
177
+ const filepath = (match[2] ?? '').trim();
178
+ const code = match[3] ?? '';
179
+ if (looksLikeFilepath(filepath, lang)) {
180
+ pairs.push({ path: filepath, code, start: match.index ?? 0, end: (match.index ?? 0) + match[0].length });
181
+ }
182
+ }
183
+ for (const match of text.matchAll(FILE_REF_PATTERN)) {
184
+ pairs.push({
185
+ path: (match[1] ?? '').trim(),
186
+ code: match[3] ?? '',
187
+ start: match.index ?? 0,
188
+ end: (match.index ?? 0) + match[0].length,
189
+ });
190
+ }
191
+ // 按起点去重(同一块可能被两个正则同时命中)
192
+ const seen = new Set();
193
+ const unique = [];
194
+ for (const pair of pairs) {
195
+ if (seen.has(pair.start))
196
+ continue;
197
+ seen.add(pair.start);
198
+ unique.push(pair);
199
+ }
200
+ const writeTool = resolveWriteTool(tools);
201
+ const toolCalls = unique.map((pair) => ({
202
+ id: makeToolCallId(),
203
+ type: 'function',
204
+ function: {
205
+ name: writeTool.name,
206
+ arguments: JSON.stringify(buildWriteArgs(writeTool.params, pair.path, pair.code)),
207
+ },
208
+ }));
209
+ if (toolCalls.length === 0)
210
+ return { text, toolCalls: [] };
211
+ // 移除已提取的代码块,保留其余文本
212
+ const remainingParts = [];
213
+ let lastEnd = 0;
214
+ for (const pair of [...unique].sort((a, b) => a.start - b.start)) {
215
+ if (pair.start > lastEnd)
216
+ remainingParts.push(text.slice(lastEnd, pair.start).trim());
217
+ lastEnd = pair.end;
218
+ }
219
+ if (lastEnd < text.length)
220
+ remainingParts.push(text.slice(lastEnd).trim());
221
+ return { text: remainingParts.filter(Boolean).join('\n'), toolCalls };
222
+ }
223
+ /**
224
+ * 把第一轮回复**整段**包成一次写文件调用(零损失)。
225
+ *
226
+ * 仅在回复看起来像文件内容时才触发;描述性文字不触发。
227
+ */
228
+ export function directConvertToToolCalls(firstResponse, tools, userRequest = '') {
229
+ if (!looksLikeFileContent(firstResponse)) {
230
+ return { text: firstResponse, toolCalls: [] };
231
+ }
232
+ // 客户端真实的写文件工具 + 它的真实参数名(可能是 filePath/file_path、content/code)
233
+ const { name: writeTool, params: writeParams } = resolveWriteTool(tools);
234
+ // 策略1:提取带路径的代码块
235
+ const pairs = [];
236
+ for (const match of firstResponse.matchAll(CODE_BLOCK_WITH_PATH)) {
237
+ const lang = match[1] ?? '';
238
+ const filepath = (match[2] ?? '').trim();
239
+ const code = match[3] ?? '';
240
+ if (looksLikeFilepath(filepath, lang))
241
+ pairs.push({ path: filepath, code });
242
+ }
243
+ if (pairs.length > 0) {
244
+ const toolCalls = pairs.map((pair) => ({
245
+ id: makeToolCallId(),
246
+ type: 'function',
247
+ function: {
248
+ name: writeTool,
249
+ arguments: JSON.stringify(buildWriteArgs(writeParams, pair.path, pair.code)),
250
+ },
251
+ }));
252
+ return { text: '', toolCalls };
253
+ }
254
+ // 策略2:整个回复作为一个文件
255
+ const filename = inferFilename(userRequest, firstResponse);
256
+ return {
257
+ text: '',
258
+ toolCalls: [
259
+ {
260
+ id: makeToolCallId(),
261
+ type: 'function',
262
+ function: {
263
+ name: writeTool,
264
+ arguments: JSON.stringify(buildWriteArgs(writeParams, filename, firstResponse)),
265
+ },
266
+ },
267
+ ],
268
+ };
269
+ }
270
+ /** 从文本中抽取出现过的疑似文件路径(供 reparse 提示词使用)。 */
271
+ export function collectFilePathsInText(text, limit = Number.POSITIVE_INFINITY) {
272
+ const out = new Set();
273
+ // 注意用 PY_W_CHARS 而非 \w:中文文件名(如 文档.md)也要能匹配
274
+ const pattern = new RegExp(String.raw `[/~][${PY_W_CHARS}./-]+\.[${PY_W_CHARS}]{1,10}`, 'gu');
275
+ for (const m of text.matchAll(pattern)) {
276
+ const p = m[0];
277
+ // ⚠️ 与原设计不同处:还要排除 `//host/path`。
278
+ // 正则从 URL 的第一个 `/` 开始匹配,得到的是 `//x.com/a.ts`,
279
+ // 而它不以 "http" 开头,Python 版的 `startswith('http')` 拦不住它。
280
+ if (p.startsWith('//'))
281
+ continue;
282
+ if (!p.startsWith('http') && p.length < 200)
283
+ out.add(p);
284
+ if (out.size >= limit)
285
+ break;
286
+ }
287
+ return out;
288
+ }
289
+ //# sourceMappingURL=convert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/tools/convert.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ import type { ToolCallPayload, ToolDefinition } from '../types/message.js';
2
+ /** AI 输出工具名 → 标准名的静态别名表。 */
3
+ export declare const TOOL_NAME_ALIASES: Record<string, string>;
4
+ /** 语义别名分组:`write/create` → 写文件工具,等等。 */
5
+ export declare const TOOL_NAME_ALIAS_PATTERNS: ReadonlyArray<readonly [string, readonly string[]]>;
6
+ /** 仅在 IDE 内可用、不应由后端 API 调用的工具。 */
7
+ export declare const TRAE_INTERNAL_TOOLS: Set<string>;
8
+ /** 文件系统类工具:必须在**客户端**执行(后端只负责把调用回传)。 */
9
+ export declare const FILE_SYSTEM_TOOLS: Set<string>;
10
+ /** 用户交互类工具:同样回传客户端执行。 */
11
+ export declare const USER_INTERACTION_TOOLS: Set<string>;
12
+ /**
13
+ * 平台自带工具名 —— 出现即说明模型在「对着网页自己的工具」干活,必须专项告警。
14
+ *
15
+ * ⚠️ 2026-10-14 实测:`execute_sandbox_code` 是 ChatGLM 自己的代码沙箱工具。
16
+ * 模型在 `answer_type=python` 的回合里会去调它,而客户端并没有这个工具 →
17
+ * 被丢弃后整轮降级成纯文本、客户端直接结束回合(「对话无故停止」)。
18
+ */
19
+ export declare const PLATFORM_BUILTIN_TOOL_NAMES: Set<string>;
20
+ /** 一次请求内有效的工具名/参数名映射。 */
21
+ export interface ToolMaps {
22
+ /** 标准名(write / edit / read)→ 客户端实际工具名。 */
23
+ name: Record<string, string>;
24
+ /** 工具名 → { 归一化参数名(仅小写字母)→ 客户端原始参数名 }。 */
25
+ param: Record<string, Record<string, string>>;
26
+ }
27
+ /** 空映射表(等价于 Python 版全局变量未初始化时的行为)。 */
28
+ export declare const EMPTY_TOOL_MAPS: ToolMaps;
29
+ /** 归一化参数名:只保留字母后小写(`filePath` → `filepath`)。 */
30
+ export declare function normalizeParamKey(name: string): string;
31
+ /** 归一化工具名:只保留小写字母数字(`write_to_file` → `writetofile`)。 */
32
+ export declare function normalizeToolName(name: string | null | undefined): string;
33
+ /**
34
+ * 从客户端工具定义中检测写入/编辑/读取工具的实际名称(按参数特征推断)。
35
+ *
36
+ * - 写入工具:有 file_path/path + content,且无 old_str
37
+ * - 编辑工具:有 old_str/oldText 之一 + new_str/newText 之一
38
+ * - 读取工具:有 file_path(**不是** path,`path` 可能是目录)且无 content/old_str
39
+ */
40
+ export declare function detectToolNames(tools: ReadonlyArray<ToolDefinition>): Record<string, string>;
41
+ /**
42
+ * 按客户端工具定义建立映射表(替代 Python 版写全局变量的做法)。
43
+ */
44
+ export declare function createToolMaps(tools: ReadonlyArray<ToolDefinition>): ToolMaps;
45
+ /**
46
+ * 把 AI 输出的工具名解析为客户端真实工具名;无法解析时返回空字符串。
47
+ *
48
+ * 依次尝试:完全相同 → 归一化后相同 → 语义别名。
49
+ *
50
+ * ⚠️ **近似名必须映射后保留,绝不能直接丢弃** —— 丢弃会让工具调用凭空消失,
51
+ * 客户端收到一段纯文本后就停住了(实测 AI 输出 `write_file`、
52
+ * 客户端只有 `write_to_file`,整条调用被丢弃)。
53
+ */
54
+ export declare function resolveToolName(name: string | null | undefined, allowed: ReadonlyArray<string>, maps?: ToolMaps): string;
55
+ /** 生成 `call_` 前缀的工具调用 id(对应 Python `uuid4().hex[:24]`)。 */
56
+ export declare function makeToolCallId(): string;
57
+ /**
58
+ * 归一化工具参数名(等价于 `_normalize_tool_arguments`)。
59
+ *
60
+ * 规则:标准名的值优先于别名的值(同一目标 key 冲突时不覆盖)。
61
+ */
62
+ export declare function normalizeToolArguments(toolName: string, args: Record<string, unknown>): Record<string, unknown>;
63
+ /** 过滤掉「工具名不在客户端提供列表中」的调用,近似名先映射再保留。 */
64
+ export declare function filterUnknownToolCalls(toolCalls: ReadonlyArray<ToolCallPayload> | null | undefined, tools: ReadonlyArray<ToolDefinition> | null | undefined, maps?: ToolMaps): {
65
+ valid: ToolCallPayload[];
66
+ dropped: ToolCallPayload[];
67
+ };
68
+ export interface SignatureReroute {
69
+ from: string;
70
+ to: string;
71
+ /** 触发改派的多余参数名(诊断用)。 */
72
+ unknownKeys: string[];
73
+ }
74
+ /**
75
+ * 按「参数签名」纠正选错的工具。
76
+ *
77
+ * ## 解决的真实问题(2026-10-14,xzh 实测)
78
+ * 模型想**创建**文件,却调了 `edit_file` 并套用 `write_file` 的签名
79
+ * (`edit_file(path, content)`)。客户端校验签名直接拒收:
80
+ * `edit_file 收到未知参数 "content"。可用参数:"path"、"search"、"replace"`。
81
+ * 模型虽然能在下一轮思考里自我纠正(日志里它自己说
82
+ * "I used the wrong tool — edit_file needs path/search/replace, not content"),
83
+ * 但那一轮已经烧掉了客户端的一次工具往返,用户看到的就是一条报错。
84
+ *
85
+ * ## 规则(**保守**:只在能确定时动手)
86
+ * 对每个调用:
87
+ * 1. 按名字找到声明的工具;它的签名**装得下**全部参数 → 原样保留;
88
+ * 2. 装不下(存在未知参数)→ 在**其余**声明工具里找「能装下全部参数、
89
+ * 且必填参数都被满足」的候选:
90
+ * - 恰好 **1 个** → 改派给它(`edit_file(path,content)` → `write_file`);
91
+ * - 0 个或 ≥2 个 → **原样保留**。0 个说明没有更好的去处;≥2 个说明有歧义,
92
+ * 猜错比让客户端拒绝更糟(可能改写到错误的文件)。
93
+ * 3. 名字本身就不在声明列表里的调用**不碰**(那是 {@link filterUnknownToolCalls} 的职责)。
94
+ *
95
+ * @returns 修好的调用数组 + 改派记录(调用方负责打日志)
96
+ */
97
+ export declare function repairToolCallBySignature(toolCalls: ReadonlyArray<ToolCallPayload> | null | undefined, tools: ReadonlyArray<ToolDefinition> | null | undefined): {
98
+ repaired: ToolCallPayload[];
99
+ reroutes: SignatureReroute[];
100
+ };
101
+ /**
102
+ * 值是否**明显是 shell 命令**而不是文件路径。
103
+ *
104
+ * 判据(保守,宁可漏判也不误判 —— 误判会把一条普通路径当命令执行):
105
+ * 1. 以命令动词 + 空格开头(`cd /x && ./start.sh` / `ls -la`);或
106
+ * 2. 以 `./` 开头(运行脚本的写法);
107
+ * 3. 否则:以 `/`、`~` 开头的一律当路径;其余只有含 `&&`/`;`/`|`/`>`/反引号/`$(` 才算命令。
108
+ */
109
+ export declare function looksLikeShellCommand(value: string | null | undefined): boolean;
110
+ /** 一次「命令误填进路径参数」的改派记录(调用方负责打日志)。 */
111
+ export interface CommandMisroute {
112
+ from: string;
113
+ to: string;
114
+ /** 被当成路径传进来的命令原文(截断,仅用于日志)。 */
115
+ commandPreview: string;
116
+ }
117
+ /**
118
+ * 把「拿文件路径参数当命令用」的调用改派给客户端的命令执行工具。
119
+ *
120
+ * ## 真实事故(2026-10-14,xzh 实测)
121
+ * 模型想跑 `cd /home/amble/object/btc && ./start.sh`,却把它塞进 `write_file` 的
122
+ * `path` 参数 → 客户端**真的在工作目录里创建了一个名叫 `cd /home/...` 的文件**,
123
+ * 下一轮又用 `rm -f` / `rmdir 'cd'` 去收拾自己造的垃圾,任务彻底跑偏。
124
+ *
125
+ * ## 规则(保守:只在能确定时动手)
126
+ * 1. 只看**路径类**参数的值(`path` / `file_path` / `filePath` / `filename` / `file`);
127
+ * 2. 值必须明显是 shell 命令(见 {@link looksLikeShellCommand});
128
+ * 3. 客户端声明的工具里**恰好有一个**带 `command`/`cmd`/`script`/`shell` 参数的工具
129
+ * → 把命令原文改派给它(其余参数不必带过去:它们本来就是误填的);
130
+ * **0 个或 ≥2 个候选都不动手**(猜错比让客户端拒绝更糟)。
131
+ *
132
+ * @returns 修好的调用数组 + 改派记录(调用方负责打日志)
133
+ */
134
+ export declare function rerouteCommandMisuse(toolCalls: ReadonlyArray<ToolCallPayload> | null | undefined, tools: ReadonlyArray<ToolDefinition> | null | undefined): {
135
+ repaired: ToolCallPayload[];
136
+ reroutes: CommandMisroute[];
137
+ };
138
+ //# sourceMappingURL=names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/tools/names.ts"],"names":[],"mappings":"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"}