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,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 调试日志 —— `legacy-python/src/utils/debug_logger.py` 的移植。
|
|
3
|
+
*
|
|
4
|
+
* 仅当 `DEBUG_LOGS=true` 时写入,输出到 `~/.ai-api/logs/debug_YYYYMMDD.log`。
|
|
5
|
+
*
|
|
6
|
+
* 与 `api-logger.ts` 的分工(**不要混**):
|
|
7
|
+
* - `api-logger` 写**项目内** `logs/api_requests.log`,**原样、不截断**,每次启动重置;
|
|
8
|
+
* - `debug-logger` 写**用户目录** `~/.ai-api/logs/`,**带截断**(500/300/200 字符),
|
|
9
|
+
* 按天分文件、跨重启累积。前者是「事实记录」,后者是「排查辅助」。
|
|
10
|
+
*
|
|
11
|
+
* 与原实现的差异:
|
|
12
|
+
* - Python 的 `@lru_cache(maxsize=1)` 在 TS 里没有直接对应物;这里改用
|
|
13
|
+
* **惰性 + 可重置的模块级缓存**(`resetDebugLoggerCache()` 供测试用),
|
|
14
|
+
* 语义等价(首次调用时定值,且 config 变更后测试可重置)。
|
|
15
|
+
* - 时间戳 `%H:%M:%S.%f`[:-3] → `HH:mm:ss.SSS`。
|
|
16
|
+
*/
|
|
17
|
+
import { appendFileSync, mkdirSync } from 'node:fs';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { settings } from '../config.js';
|
|
21
|
+
/* ------------------------------------------------------------------ */
|
|
22
|
+
/* 缓存 */
|
|
23
|
+
/* ------------------------------------------------------------------ */
|
|
24
|
+
let cachedLogDir = null;
|
|
25
|
+
let cachedEnabled = null;
|
|
26
|
+
/** 重置缓存(测试用;对应 Python 的 `lru_cache` 失效)。 */
|
|
27
|
+
export function resetDebugLoggerCache() {
|
|
28
|
+
cachedLogDir = null;
|
|
29
|
+
cachedEnabled = null;
|
|
30
|
+
}
|
|
31
|
+
/** 日志目录:`~/.ai-api/logs`。 */
|
|
32
|
+
function debugLogDir() {
|
|
33
|
+
if (cachedLogDir === null) {
|
|
34
|
+
cachedLogDir = join(homedir(), '.ai-api', 'logs');
|
|
35
|
+
}
|
|
36
|
+
return cachedLogDir;
|
|
37
|
+
}
|
|
38
|
+
/** 是否启用调试日志。 */
|
|
39
|
+
function isEnabled() {
|
|
40
|
+
if (cachedEnabled === null) {
|
|
41
|
+
try {
|
|
42
|
+
cachedEnabled = Boolean(settings.debugLogs);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
cachedEnabled = (process.env['DEBUG_LOGS'] ?? 'false').toLowerCase() === 'true';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return cachedEnabled;
|
|
49
|
+
}
|
|
50
|
+
/** `debug_YYYYMMDD.log` 的绝对路径。 */
|
|
51
|
+
export function debugLogPath(date = new Date()) {
|
|
52
|
+
const p = (n) => String(n).padStart(2, '0');
|
|
53
|
+
const stamp = `${date.getFullYear()}${p(date.getMonth() + 1)}${p(date.getDate())}`;
|
|
54
|
+
return join(debugLogDir(), `debug_${stamp}.log`);
|
|
55
|
+
}
|
|
56
|
+
/** `HH:mm:ss.SSS`(Python 的 `%H:%M:%S.%f` 取前 3 位)。 */
|
|
57
|
+
function timeOnly(date = new Date()) {
|
|
58
|
+
const p = (n, width = 2) => String(n).padStart(width, '0');
|
|
59
|
+
return (`${p(date.getHours())}:${p(date.getMinutes())}:${p(date.getSeconds())}.` +
|
|
60
|
+
`${p(date.getMilliseconds(), 3)}`);
|
|
61
|
+
}
|
|
62
|
+
/** 截断过长文本(与原实现一致:追加 `... (共 N 字符)`)。 */
|
|
63
|
+
function truncate(text, maxLen = 500) {
|
|
64
|
+
if (text.length <= maxLen)
|
|
65
|
+
return text;
|
|
66
|
+
return `${text.slice(0, maxLen)}... (共 ${text.length} 字符)`;
|
|
67
|
+
}
|
|
68
|
+
/** 追加写(失败静默)。 */
|
|
69
|
+
function append(lines) {
|
|
70
|
+
try {
|
|
71
|
+
mkdirSync(debugLogDir(), { recursive: true });
|
|
72
|
+
appendFileSync(debugLogPath(), `${lines.join('\n')}\n`, 'utf8');
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// 调试日志失败绝不能影响主流程
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** 格式化消息列表(每条截断到 `maxEach`)。 */
|
|
79
|
+
function formatMessages(messages, maxEach = 300) {
|
|
80
|
+
const parts = [];
|
|
81
|
+
messages.forEach((msg, i) => {
|
|
82
|
+
const role = typeof msg['role'] === 'string' ? msg['role'] : '?';
|
|
83
|
+
const rawContent = msg['content'];
|
|
84
|
+
const content = Array.isArray(rawContent)
|
|
85
|
+
? JSON.stringify(rawContent).slice(0, maxEach)
|
|
86
|
+
: truncate(String(rawContent ?? ''), maxEach);
|
|
87
|
+
let tcInfo = '';
|
|
88
|
+
const toolCalls = msg['tool_calls'];
|
|
89
|
+
if (Array.isArray(toolCalls) && toolCalls.length > 0) {
|
|
90
|
+
const names = toolCalls.map((tc) => {
|
|
91
|
+
const fn = tc?.['function'];
|
|
92
|
+
return typeof fn?.['name'] === 'string' ? fn['name'] : '?';
|
|
93
|
+
});
|
|
94
|
+
tcInfo = ` [tool_calls: ${names.join(', ')}]`;
|
|
95
|
+
}
|
|
96
|
+
// ⚠️ 注意原实现的行为:`tool_call_id` 存在时会**覆盖**掉 `tool_calls` 信息
|
|
97
|
+
// (是同名变量被重新赋值,看起来像 bug,但保持一致以免日志对照时困惑)
|
|
98
|
+
const toolCallId = msg['tool_call_id'];
|
|
99
|
+
if (typeof toolCallId === 'string' && toolCallId) {
|
|
100
|
+
tcInfo = ` [tool_call_id: ${toolCallId}]`;
|
|
101
|
+
}
|
|
102
|
+
parts.push(` [${i}] ${role}${tcInfo}: ${content}`);
|
|
103
|
+
});
|
|
104
|
+
return parts.join('\n');
|
|
105
|
+
}
|
|
106
|
+
/** 格式化工具调用(`arguments` 尽量解析成对象再序列化,失败则原样截断)。 */
|
|
107
|
+
function formatToolCalls(toolCalls, maxArgs = 200) {
|
|
108
|
+
const parts = [];
|
|
109
|
+
for (const tc of toolCalls) {
|
|
110
|
+
const fn = (tc['function'] ?? {});
|
|
111
|
+
const name = typeof fn['name'] === 'string' ? fn['name'] : '?';
|
|
112
|
+
let argsStr;
|
|
113
|
+
const rawArgs = fn['arguments'];
|
|
114
|
+
if (typeof rawArgs === 'string') {
|
|
115
|
+
try {
|
|
116
|
+
argsStr = JSON.stringify(JSON.parse(rawArgs));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
argsStr = rawArgs;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
try {
|
|
124
|
+
argsStr = JSON.stringify(rawArgs ?? {});
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
argsStr = String(rawArgs);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
parts.push(` - ${name}: ${truncate(argsStr, maxArgs)}`);
|
|
131
|
+
}
|
|
132
|
+
return parts.join('\n');
|
|
133
|
+
}
|
|
134
|
+
/* ------------------------------------------------------------------ */
|
|
135
|
+
/* 公开接口 */
|
|
136
|
+
/* ------------------------------------------------------------------ */
|
|
137
|
+
/** 记录客户端请求。 */
|
|
138
|
+
export function logClientRequest(params) {
|
|
139
|
+
if (!isEnabled())
|
|
140
|
+
return;
|
|
141
|
+
const { requestId, model, messages, stream = true, tools, extra } = params;
|
|
142
|
+
const lines = [
|
|
143
|
+
`[${timeOnly()}] [>>> 客户端请求] [${requestId}]`,
|
|
144
|
+
` 模型: ${model} | 流式: ${stream}`,
|
|
145
|
+
` 消息数: ${messages.length}`,
|
|
146
|
+
];
|
|
147
|
+
if (tools && tools.length > 0) {
|
|
148
|
+
const names = tools.map((t) => {
|
|
149
|
+
const fn = t['function'];
|
|
150
|
+
return typeof fn?.['name'] === 'string' ? fn['name'] : '?';
|
|
151
|
+
});
|
|
152
|
+
lines.push(` 工具数: ${tools.length} | 工具: ${names.slice(0, 10).join(', ')}` +
|
|
153
|
+
(names.length > 10 ? '...' : ''));
|
|
154
|
+
}
|
|
155
|
+
lines.push(' 消息内容:');
|
|
156
|
+
lines.push(formatMessages(messages));
|
|
157
|
+
if (extra) {
|
|
158
|
+
const keys = Object.keys(extra).filter((k) => !['model', 'messages', 'stream', 'tools'].includes(k));
|
|
159
|
+
if (keys.length > 0) {
|
|
160
|
+
const picked = {};
|
|
161
|
+
for (const k of keys)
|
|
162
|
+
picked[k] = extra[k];
|
|
163
|
+
lines.push(` 额外参数: ${safeJson(picked)}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
lines.push('');
|
|
167
|
+
append(lines);
|
|
168
|
+
}
|
|
169
|
+
/** 记录返回给客户端的响应。 */
|
|
170
|
+
export function logClientResponse(params) {
|
|
171
|
+
if (!isEnabled())
|
|
172
|
+
return;
|
|
173
|
+
const { requestId, model, finishReason, content, toolCalls, duration = 0 } = params;
|
|
174
|
+
const lines = [
|
|
175
|
+
`[${timeOnly()}] [<<< 客户端响应] [${requestId}]`,
|
|
176
|
+
` 模型: ${model} | 完成原因: ${finishReason} | 耗时: ${duration.toFixed(1)}s`,
|
|
177
|
+
];
|
|
178
|
+
if (content)
|
|
179
|
+
lines.push(` 文本内容: ${truncate(content, 500)}`);
|
|
180
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
181
|
+
lines.push(` 工具调用数: ${toolCalls.length}`);
|
|
182
|
+
lines.push(' 工具调用:');
|
|
183
|
+
lines.push(formatToolCalls(toolCalls));
|
|
184
|
+
}
|
|
185
|
+
lines.push('');
|
|
186
|
+
append(lines);
|
|
187
|
+
}
|
|
188
|
+
/** 记录发送给网页 AI 的内容。 */
|
|
189
|
+
export function logAiRequest(params) {
|
|
190
|
+
if (!isEnabled())
|
|
191
|
+
return;
|
|
192
|
+
const { requestId, platform, messages, workspacePath } = params;
|
|
193
|
+
const lines = [
|
|
194
|
+
`[${timeOnly()}] [>>> 发送给AI] [${requestId}] 平台=${platform}`,
|
|
195
|
+
` 工作目录: ${workspacePath || '(未设置)'}`,
|
|
196
|
+
` 消息数: ${messages.length}`,
|
|
197
|
+
' 消息内容:',
|
|
198
|
+
];
|
|
199
|
+
for (const msg of messages) {
|
|
200
|
+
const role = typeof msg['role'] === 'string' ? msg['role'] : '?';
|
|
201
|
+
const content = msg['content'];
|
|
202
|
+
const text = String(content ?? '');
|
|
203
|
+
if (role === 'system') {
|
|
204
|
+
lines.push(` [system] (${text.length} 字符): ${truncate(text, 800)}`);
|
|
205
|
+
}
|
|
206
|
+
else if (role === 'user') {
|
|
207
|
+
lines.push(` [user]: ${truncate(text, 300)}`);
|
|
208
|
+
}
|
|
209
|
+
else if (role === 'assistant') {
|
|
210
|
+
const tc = msg['tool_calls'];
|
|
211
|
+
if (Array.isArray(tc) && tc.length > 0) {
|
|
212
|
+
const names = tc.map((t) => {
|
|
213
|
+
const fn = t?.['function'];
|
|
214
|
+
return typeof fn?.['name'] === 'string' ? fn['name'] : '?';
|
|
215
|
+
});
|
|
216
|
+
lines.push(` [assistant] tool_calls: ${names.join(', ')}`);
|
|
217
|
+
lines.push(` 文本: ${truncate(text, 200)}`);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
lines.push(` [assistant]: ${truncate(text, 300)}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (role === 'tool') {
|
|
224
|
+
lines.push(` [tool]: ${truncate(text, 300)}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
lines.push('');
|
|
228
|
+
append(lines);
|
|
229
|
+
}
|
|
230
|
+
/** 记录网页 AI 的原始回复。 */
|
|
231
|
+
export function logAiResponse(params) {
|
|
232
|
+
if (!isEnabled())
|
|
233
|
+
return;
|
|
234
|
+
const { requestId, platform, rawText, parsedToolCalls, parsedText, duration = 0 } = params;
|
|
235
|
+
const lines = [
|
|
236
|
+
`[${timeOnly()}] [<<< AI原始回复] [${requestId}] 平台=${platform} | 耗时: ${duration.toFixed(1)}s`,
|
|
237
|
+
` 原始文本长度: ${rawText.length}`,
|
|
238
|
+
` 原始文本: ${truncate(rawText, 1000)}`,
|
|
239
|
+
];
|
|
240
|
+
if (parsedText)
|
|
241
|
+
lines.push(` 解析文本: ${truncate(parsedText, 500)}`);
|
|
242
|
+
if (parsedToolCalls && parsedToolCalls.length > 0) {
|
|
243
|
+
lines.push(` 解析工具调用数: ${parsedToolCalls.length}`);
|
|
244
|
+
lines.push(' 解析工具调用:');
|
|
245
|
+
lines.push(formatToolCalls(parsedToolCalls, 300));
|
|
246
|
+
}
|
|
247
|
+
lines.push('');
|
|
248
|
+
append(lines);
|
|
249
|
+
}
|
|
250
|
+
/** 记录错误。 */
|
|
251
|
+
export function logError(requestId, error, context = '') {
|
|
252
|
+
if (!isEnabled())
|
|
253
|
+
return;
|
|
254
|
+
const lines = [
|
|
255
|
+
`[${timeOnly()}] [!!! 错误] [${requestId}]`,
|
|
256
|
+
` 错误: ${error}`,
|
|
257
|
+
];
|
|
258
|
+
if (context)
|
|
259
|
+
lines.push(` 上下文: ${truncate(context, 500)}`);
|
|
260
|
+
lines.push('');
|
|
261
|
+
append(lines);
|
|
262
|
+
}
|
|
263
|
+
/** 记录工具调用结果。 */
|
|
264
|
+
export function logToolCallResult(params) {
|
|
265
|
+
if (!isEnabled())
|
|
266
|
+
return;
|
|
267
|
+
const { requestId, toolName, toolArgs, result, duration = 0 } = params;
|
|
268
|
+
append([
|
|
269
|
+
`[${timeOnly()}] [工具执行结果] [${requestId}]`,
|
|
270
|
+
` 工具: ${toolName} | 耗时: ${duration.toFixed(1)}s`,
|
|
271
|
+
` 参数: ${truncate(safeJson(toolArgs), 300)}`,
|
|
272
|
+
` 结果: ${truncate(result, 500)}`,
|
|
273
|
+
'',
|
|
274
|
+
]);
|
|
275
|
+
}
|
|
276
|
+
/** `JSON.stringify` 的容错版本(对应 Python `default=str`)。 */
|
|
277
|
+
function safeJson(value) {
|
|
278
|
+
try {
|
|
279
|
+
return JSON.stringify(value, (_key, val) => typeof val === 'bigint' ? val.toString() : val);
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return String(value);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=debug-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-logger.js","sourceRoot":"","sources":["../../src/log/debug-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日志 —— 替代 Python 版的 loguru。
|
|
3
|
+
*
|
|
4
|
+
* 与原实现的差异:
|
|
5
|
+
* - Python 用 loguru(`logger.info` / `logger.warning`),TS 用 pino。
|
|
6
|
+
* - 测试环境自动静音:pino 在 import 时就绑定 level,若不静音,单测输出会被
|
|
7
|
+
* 大量 `[tool_calls] ...` 噪音淹没。
|
|
8
|
+
* - `logs/api_requests.log` 那种「原样记录、不做任何加工」的日志**不走 pino**,
|
|
9
|
+
* 由 `src/log/api-logger.ts` 直接追加写文件(见 docs/hard-constraints.md「日志」)。
|
|
10
|
+
*/
|
|
11
|
+
import pino from 'pino';
|
|
12
|
+
/** 解析日志级别,非法值回退 info。 */
|
|
13
|
+
export declare function resolveLogLevel(raw: string | undefined): pino.LevelWithSilent;
|
|
14
|
+
export declare const logger: pino.Logger<never, boolean>;
|
|
15
|
+
export type Logger = typeof logger;
|
|
16
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/log/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,yBAAyB;AACzB,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,eAAe,CAgB7E;AAED,eAAO,MAAM,MAAM,6BAGjB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日志 —— 替代 Python 版的 loguru。
|
|
3
|
+
*
|
|
4
|
+
* 与原实现的差异:
|
|
5
|
+
* - Python 用 loguru(`logger.info` / `logger.warning`),TS 用 pino。
|
|
6
|
+
* - 测试环境自动静音:pino 在 import 时就绑定 level,若不静音,单测输出会被
|
|
7
|
+
* 大量 `[tool_calls] ...` 噪音淹没。
|
|
8
|
+
* - `logs/api_requests.log` 那种「原样记录、不做任何加工」的日志**不走 pino**,
|
|
9
|
+
* 由 `src/log/api-logger.ts` 直接追加写文件(见 docs/hard-constraints.md「日志」)。
|
|
10
|
+
*/
|
|
11
|
+
import pino from 'pino';
|
|
12
|
+
const isTest = Boolean(process.env['VITEST']) || process.env['NODE_ENV'] === 'test';
|
|
13
|
+
/** 解析日志级别,非法值回退 info。 */
|
|
14
|
+
export function resolveLogLevel(raw) {
|
|
15
|
+
if (!raw)
|
|
16
|
+
return isTest ? 'silent' : 'info';
|
|
17
|
+
const normalized = raw.trim().toLowerCase();
|
|
18
|
+
const allowed = [
|
|
19
|
+
'silent',
|
|
20
|
+
'fatal',
|
|
21
|
+
'error',
|
|
22
|
+
'warn',
|
|
23
|
+
'info',
|
|
24
|
+
'debug',
|
|
25
|
+
'trace',
|
|
26
|
+
];
|
|
27
|
+
return allowed.includes(normalized)
|
|
28
|
+
? normalized
|
|
29
|
+
: 'info';
|
|
30
|
+
}
|
|
31
|
+
export const logger = pino({
|
|
32
|
+
level: isTest ? 'silent' : resolveLogLevel(process.env['LOG_LEVEL']),
|
|
33
|
+
base: undefined, // 去掉 pid/hostname,日志更接近 loguru 的可读输出
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/log/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC;AAEpF,yBAAyB;AACzB,MAAM,UAAU,eAAe,CAAC,GAAuB;IACrD,IAAI,CAAC,GAAG;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAE5C,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,OAAO,GAA2B;QACtC,QAAQ;QACR,OAAO;QACP,OAAO;QACP,MAAM;QACN,MAAM;QACN,OAAO;QACP,OAAO;KACR,CAAC;IACF,OAAQ,OAAoB,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/C,CAAC,CAAE,UAAmC;QACtC,CAAC,CAAC,MAAM,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACpE,IAAI,EAAE,SAAS,EAAE,qCAAqC;CACvD,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postinstall.d.ts","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 安装后钩子:尽力把 Playwright 的 **Firefox** 二进制装好。
|
|
4
|
+
*
|
|
5
|
+
* ## 为什么需要我们自己写这个
|
|
6
|
+
* 实测(playwright 1.64.0):`playwright` 与 `playwright-core` 的 `package.json`
|
|
7
|
+
* **都没有 `scripts` 字段**,也就是**没有任何安装期脚本** —— `npm i playwright`
|
|
8
|
+
* 只装 JS 包,**不会下载浏览器**(浏览器缓存目录里 `firefox-1555` 的时间戳可以证明:
|
|
9
|
+
* 它出现在我们手动执行 `npx playwright install firefox` 的那一刻,而不是 install 时)。
|
|
10
|
+
*
|
|
11
|
+
* 而 Playwright 官方对**库作者**的建议是「让用户自己装浏览器」,因为一个库不该
|
|
12
|
+
* 偷偷下几百 MB。但本包是个**给最终用户用的 CLI**:用户 `npm i -g webaiapi`
|
|
13
|
+
* 之后期望的是「马上能用」,而不是先撞一次「Executable doesn't exist」再回来翻文档。
|
|
14
|
+
*
|
|
15
|
+
* ## 三条设计原则
|
|
16
|
+
* 1. **只装 firefox**(本项目硬约束:禁止 Chrome/Chromium)。默认的 `install`
|
|
17
|
+
* 会把 chromium / webkit 一起拖下来(~400MB 浪费)。
|
|
18
|
+
* 2. **失败绝不阻断安装**:一律 `exit 0` 并打印可复制的修复命令。
|
|
19
|
+
* 安装脚本因为网络问题让整个 `npm i` 失败,是最不可接受的失败方式。
|
|
20
|
+
* 3. **尊重标准开关**:`PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD`(Playwright 自己的约定)
|
|
21
|
+
* 与 `WEBAIAPI_SKIP_BROWSER_INSTALL`(本包的逃生口,CI 里常用)。
|
|
22
|
+
*/
|
|
23
|
+
import { execFileSync } from 'node:child_process';
|
|
24
|
+
import { existsSync } from 'node:fs';
|
|
25
|
+
import { createRequire } from 'node:module';
|
|
26
|
+
import { dirname, join } from 'node:path';
|
|
27
|
+
/** 打印一行提示(安装期没有 pino,直接用 console)。 */
|
|
28
|
+
function say(message) {
|
|
29
|
+
console.log(`[webaiapi] ${message}`);
|
|
30
|
+
}
|
|
31
|
+
/** 是否被显式要求跳过。 */
|
|
32
|
+
function shouldSkip() {
|
|
33
|
+
if (process.env['WEBAIAPI_SKIP_BROWSER_INSTALL'])
|
|
34
|
+
return 'WEBAIAPI_SKIP_BROWSER_INSTALL 已设置';
|
|
35
|
+
if (process.env['PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD']) {
|
|
36
|
+
return 'PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD 已设置';
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
async function main() {
|
|
41
|
+
const skipReason = shouldSkip();
|
|
42
|
+
if (skipReason) {
|
|
43
|
+
say(`跳过浏览器安装(${skipReason})。需要时手动运行: npx playwright install firefox`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
let firefox;
|
|
47
|
+
try {
|
|
48
|
+
({ firefox } = await import('playwright'));
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
say(`无法加载 playwright(${String(error)}),跳过浏览器安装`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// 已经装好 → 什么都不做(大多数重复安装/本地 `npm i` 走这条快路径)
|
|
55
|
+
try {
|
|
56
|
+
const exe = firefox.executablePath();
|
|
57
|
+
if (existsSync(exe))
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// 拿不到路径就继续尝试安装
|
|
62
|
+
}
|
|
63
|
+
say('首次安装:正在下载 Playwright Firefox(约 80MB,只需一次)...');
|
|
64
|
+
try {
|
|
65
|
+
// ⚠️ 不能用 `npx playwright`:全局安装时 node_modules/.bin 不在 PATH 上。
|
|
66
|
+
// 直接解析包内 CLI 的绝对路径最稳(`./package.json` 在 exports 白名单里)。
|
|
67
|
+
const require = createRequire(import.meta.url);
|
|
68
|
+
const pkgJson = require.resolve('playwright/package.json');
|
|
69
|
+
const cli = join(dirname(pkgJson), 'cli.js');
|
|
70
|
+
execFileSync(process.execPath, [cli, 'install', 'firefox'], {
|
|
71
|
+
stdio: 'inherit',
|
|
72
|
+
env: process.env,
|
|
73
|
+
});
|
|
74
|
+
say('Firefox 安装完成。运行 `webaiapi doctor` 可自检。');
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// 绝不因为下载失败而让 `npm i` 失败 —— 提示用户手动补装即可
|
|
78
|
+
say(`自动下载 Firefox 失败:${String(error)}`);
|
|
79
|
+
say('安装本身已成功。需要对话时请手动运行: npx playwright install firefox');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
void main()
|
|
83
|
+
.catch((error) => {
|
|
84
|
+
say(`postinstall 异常(已忽略):${String(error)}`);
|
|
85
|
+
})
|
|
86
|
+
.finally(() => {
|
|
87
|
+
// 显式 0:安装脚本的任何失败都不该让 npm install 失败
|
|
88
|
+
process.exit(0);
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=postinstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,sCAAsC;AACtC,SAAS,GAAG,CAAC,OAAe;IAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,iBAAiB;AACjB,SAAS,UAAU;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC;QAAE,OAAO,mCAAmC,CAAC;IAC7F,IAAI,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,EAAE,CAAC;QACpD,OAAO,sCAAsC,CAAC;IAChD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;IAChC,IAAI,UAAU,EAAE,CAAC;QACf,GAAG,CAAC,WAAW,UAAU,2CAA2C,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,IAAI,OAA4C,CAAC;IACjD,IAAI,CAAC;QACH,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,mBAAmB,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,0CAA0C;IAC1C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IAED,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,6DAA6D;QAC7D,0DAA0D;QAC1D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;QAE7C,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;YAC1D,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,GAAG,CAAC,wCAAwC,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,sCAAsC;QACtC,GAAG,CAAC,mBAAmB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,KAAK,IAAI,EAAE;KACR,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IACxB,GAAG,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC;KACD,OAAO,CAAC,GAAG,EAAE;IACZ,oCAAoC;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider 基类 —— `legacy-python/src/providers/base.py` 的 TypeScript 移植。
|
|
3
|
+
*
|
|
4
|
+
* 与原实现的差异:
|
|
5
|
+
* - Python 用 `@dataclass`;TS 用 `interface`(结构类型,无需运行时构造)。
|
|
6
|
+
* - `BaseProvider` 是 `abstract class`(Python 用 `ABC` + `@abstractmethod`);
|
|
7
|
+
* TS 的抽象方法在**编译期**就能拦住漏实现,比 Python 的运行时 `TypeError` 更早。
|
|
8
|
+
* - `chat_stream` 返回 `AsyncGenerator`(Python 的 `AsyncIterator`),
|
|
9
|
+
* 这样调用方可以用 `for await`,并且 `chatStream()` 内部的 `finally` 一定执行
|
|
10
|
+
* —— 这是「锁必须释放」那条硬约束的语言级保障。
|
|
11
|
+
*/
|
|
12
|
+
/** 聊天请求。 */
|
|
13
|
+
export interface ChatRequest {
|
|
14
|
+
/** 要发给网页端模型的文本(会话复用时可能只含增量)。 */
|
|
15
|
+
message: string;
|
|
16
|
+
model?: string;
|
|
17
|
+
conversation_id?: string;
|
|
18
|
+
stream?: boolean;
|
|
19
|
+
temperature?: number;
|
|
20
|
+
max_tokens?: number;
|
|
21
|
+
/**
|
|
22
|
+
* 附加上下文。路由层用到的键:
|
|
23
|
+
* - `session_key` —— 逻辑会话 ID(判断能否复用网页会话)
|
|
24
|
+
* - `delta_message` —— 只含新增消息(可增量发送)
|
|
25
|
+
* - `full_message` —— 完整提示词(换号/会话不一致时必须发它)
|
|
26
|
+
* - `use_aux_page` —— 要求本次对话走辅助页面(两轮策略的 reparse)
|
|
27
|
+
*/
|
|
28
|
+
context?: Record<string, unknown>;
|
|
29
|
+
/**
|
|
30
|
+
* 整个 HTTP 请求的**绝对截止时间戳**(毫秒,`Date.now()` 口径)。
|
|
31
|
+
*
|
|
32
|
+
* 用于把「首轮对话 + 两轮策略 reparse」等多段往返的总耗时收敛在超时中间件
|
|
33
|
+
* (300s)以内,避免客户端拿到 504 而完全看不到内容。
|
|
34
|
+
*/
|
|
35
|
+
deadlineTs?: number;
|
|
36
|
+
}
|
|
37
|
+
/** 聊天响应(一个分片或一次错误)。 */
|
|
38
|
+
export interface ChatResponse {
|
|
39
|
+
content?: string;
|
|
40
|
+
model?: string;
|
|
41
|
+
conversation_id?: string;
|
|
42
|
+
usage?: Record<string, number>;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
/** Provider 抽象基类。 */
|
|
47
|
+
export declare abstract class BaseProvider {
|
|
48
|
+
/** 平台标识(如 `chatglm-browser`)。 */
|
|
49
|
+
readonly platform: string;
|
|
50
|
+
/** 本 Provider 对外暴露的模型名清单。 */
|
|
51
|
+
models: string[];
|
|
52
|
+
constructor(platform: string);
|
|
53
|
+
/** 非流式聊天。 */
|
|
54
|
+
abstract chat(request: ChatRequest): Promise<ChatResponse>;
|
|
55
|
+
/** 流式聊天(必须串行化,见各实现的 `finally`)。 */
|
|
56
|
+
abstract chatStream(request: ChatRequest): AsyncGenerator<ChatResponse>;
|
|
57
|
+
/** 创建新会话,返回会话 ID。 */
|
|
58
|
+
abstract createConversation(): Promise<string>;
|
|
59
|
+
/** 删除会话。 */
|
|
60
|
+
abstract deleteConversation(conversationId: string): Promise<void>;
|
|
61
|
+
/** 检查登录状态。 */
|
|
62
|
+
abstract checkLoginStatus(): Promise<boolean>;
|
|
63
|
+
/** 获取支持的模型列表。 */
|
|
64
|
+
getModels(): string[];
|
|
65
|
+
/**
|
|
66
|
+
* 本 Provider **当前**使用的账号 ID。
|
|
67
|
+
*
|
|
68
|
+
* 为什么要暴露:`ModelRouter` 必须知道「主通道现在占着哪个账号」,
|
|
69
|
+
* 才能给辅助通道挑一个**不同的**账号(同账号并行会立刻触发
|
|
70
|
+
* 「请等待其他对话生成完毕」)。Python 版是直接读 `provider._account_id`
|
|
71
|
+
* 私有字段;TS 用显式方法,避免到处访问私有成员。
|
|
72
|
+
*
|
|
73
|
+
* ⚠️ 主通道被限流**换号后**返回值会变,调用方不能缓存它。
|
|
74
|
+
*/
|
|
75
|
+
getAccountId(): string;
|
|
76
|
+
/** 辅助通道标识(非空表示这是独立通道实例,不是主通道)。 */
|
|
77
|
+
getChannelKey(): string | undefined;
|
|
78
|
+
/** 标记「刚被使用过」(更新空闲计时)。*/
|
|
79
|
+
markUsed(): Promise<void>;
|
|
80
|
+
/** 是否支持指定模型。 */
|
|
81
|
+
supportsModel(model: string): boolean;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY;AACZ,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,uBAAuB;AACvB,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAqB;AACrB,8BAAsB,YAAY;IAChC,iCAAiC;IACjC,SAAgB,QAAQ,EAAE,MAAM,CAAC;IAEjC,6BAA6B;IACtB,MAAM,EAAE,MAAM,EAAE,CAAM;IAE7B,YAAY,QAAQ,EAAE,MAAM,EAE3B;IAED,aAAa;IACb,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAE3D,mCAAmC;IACnC,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;IAExE,qBAAqB;IACrB,QAAQ,CAAC,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/C,YAAY;IACZ,QAAQ,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnE,cAAc;IACd,QAAQ,CAAC,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9C,iBAAiB;IACjB,SAAS,IAAI,MAAM,EAAE,CAEpB;IAED;;;;;;;;;OASG;IACH,YAAY,IAAI,MAAM,CAErB;IAED,kCAAkC;IAClC,aAAa,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,wBAAwB;IAClB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAE9B;IAED,gBAAgB;IAChB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpC;CACF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider 基类 —— `legacy-python/src/providers/base.py` 的 TypeScript 移植。
|
|
3
|
+
*
|
|
4
|
+
* 与原实现的差异:
|
|
5
|
+
* - Python 用 `@dataclass`;TS 用 `interface`(结构类型,无需运行时构造)。
|
|
6
|
+
* - `BaseProvider` 是 `abstract class`(Python 用 `ABC` + `@abstractmethod`);
|
|
7
|
+
* TS 的抽象方法在**编译期**就能拦住漏实现,比 Python 的运行时 `TypeError` 更早。
|
|
8
|
+
* - `chat_stream` 返回 `AsyncGenerator`(Python 的 `AsyncIterator`),
|
|
9
|
+
* 这样调用方可以用 `for await`,并且 `chatStream()` 内部的 `finally` 一定执行
|
|
10
|
+
* —— 这是「锁必须释放」那条硬约束的语言级保障。
|
|
11
|
+
*/
|
|
12
|
+
/** Provider 抽象基类。 */
|
|
13
|
+
export class BaseProvider {
|
|
14
|
+
/** 平台标识(如 `chatglm-browser`)。 */
|
|
15
|
+
platform;
|
|
16
|
+
/** 本 Provider 对外暴露的模型名清单。 */
|
|
17
|
+
models = [];
|
|
18
|
+
constructor(platform) {
|
|
19
|
+
this.platform = platform;
|
|
20
|
+
}
|
|
21
|
+
/** 获取支持的模型列表。 */
|
|
22
|
+
getModels() {
|
|
23
|
+
return this.models;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 本 Provider **当前**使用的账号 ID。
|
|
27
|
+
*
|
|
28
|
+
* 为什么要暴露:`ModelRouter` 必须知道「主通道现在占着哪个账号」,
|
|
29
|
+
* 才能给辅助通道挑一个**不同的**账号(同账号并行会立刻触发
|
|
30
|
+
* 「请等待其他对话生成完毕」)。Python 版是直接读 `provider._account_id`
|
|
31
|
+
* 私有字段;TS 用显式方法,避免到处访问私有成员。
|
|
32
|
+
*
|
|
33
|
+
* ⚠️ 主通道被限流**换号后**返回值会变,调用方不能缓存它。
|
|
34
|
+
*/
|
|
35
|
+
getAccountId() {
|
|
36
|
+
return 'default';
|
|
37
|
+
}
|
|
38
|
+
/** 辅助通道标识(非空表示这是独立通道实例,不是主通道)。 */
|
|
39
|
+
getChannelKey() {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
/** 标记「刚被使用过」(更新空闲计时)。*/
|
|
43
|
+
async markUsed() {
|
|
44
|
+
// 默认空实现:只有需要空闲超时的 Provider 才关心
|
|
45
|
+
}
|
|
46
|
+
/** 是否支持指定模型。 */
|
|
47
|
+
supportsModel(model) {
|
|
48
|
+
return this.models.includes(model);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAsCH,qBAAqB;AACrB,MAAM,OAAgB,YAAY;IAChC,iCAAiC;IACjB,QAAQ,CAAS;IAEjC,6BAA6B;IACtB,MAAM,GAAa,EAAE,CAAC;IAE7B,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAiBD,iBAAiB;IACjB,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;;;;;;OASG;IACH,YAAY;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,kCAAkC;IAClC,aAAa;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,wBAAwB;IACxB,KAAK,CAAC,QAAQ;QACZ,+BAA+B;IACjC,CAAC;IAED,gBAAgB;IAChB,aAAa,CAAC,KAAa;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;CACF"}
|