@zhongqian97-code/ecode 0.5.45 → 0.5.47
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/dist/{chunk-FPB3QTP5.js → chunk-N3IDMSG5.js} +1 -1
- package/dist/chunk-SIQQG6FT.js +727 -0
- package/dist/{chunk-I4VLKL2I.js → chunk-V3JQ7HAU.js} +3 -452
- package/dist/index.js +7 -7
- package/dist/{ui-3K5WAFNO.js → ui-6WIYQZ7Y.js} +4 -71
- package/dist/{web-ONRJYFTB.js → web-XPP3PJJZ.js} +5 -4
- package/package.json +1 -1
- package/dist/chunk-72HNTRAP.js +0 -278
|
@@ -4,454 +4,7 @@ import {
|
|
|
4
4
|
createSessionMetadata,
|
|
5
5
|
updateSessionMetadata,
|
|
6
6
|
writeSessionMetadata
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
|
|
9
|
-
// src/providers/openai.ts
|
|
10
|
-
import OpenAI from "openai";
|
|
11
|
-
function createOpenAIProvider(profile) {
|
|
12
|
-
const THINK_END = "</think>";
|
|
13
|
-
const openai = new OpenAI({
|
|
14
|
-
baseURL: profile.baseUrl,
|
|
15
|
-
apiKey: profile.apiKey
|
|
16
|
-
});
|
|
17
|
-
const capabilities = Object.freeze(
|
|
18
|
-
Object.defineProperties({}, {
|
|
19
|
-
supportsTools: { value: true, writable: false, enumerable: true, configurable: false },
|
|
20
|
-
supportsReasoningStream: { value: true, writable: false, enumerable: true, configurable: false },
|
|
21
|
-
supportsImages: { value: false, writable: false, enumerable: true, configurable: false },
|
|
22
|
-
supportsJsonSchema: { value: true, writable: false, enumerable: true, configurable: false }
|
|
23
|
-
})
|
|
24
|
-
);
|
|
25
|
-
return {
|
|
26
|
-
capabilities,
|
|
27
|
-
/**
|
|
28
|
-
* stream 方法向 LLM 发起一次流式对话请求,返回异步可迭代的 chunk 序列。
|
|
29
|
-
*
|
|
30
|
-
* 实现细节:
|
|
31
|
-
* - 使用 `Symbol.asyncIterator` + async generator 实现懒执行:
|
|
32
|
-
* 只有调用方执行 `for await` 时才真正发起 HTTP 请求,避免浪费连接
|
|
33
|
-
* - 内部维护两个累加器:
|
|
34
|
-
* 1. `tcAccumulator`:按 index 聚合工具调用的分片参数(JSON 字符串)
|
|
35
|
-
* 2. `reasoningAccumulator`:拼接思考链的所有分片文本
|
|
36
|
-
* - 只在最终 chunk(`finish_reason !== null`)中 yield done=true 的完整信息
|
|
37
|
-
*
|
|
38
|
-
* @param messages 完整的对话历史,包含 user/assistant/tool 所有轮次
|
|
39
|
-
* @param tools 可选的工具列表,不传或传空数组时不附加 tools 字段
|
|
40
|
-
* @param signal 可选的 AbortSignal,用于取消请求
|
|
41
|
-
*/
|
|
42
|
-
stream(messages, tools, signal) {
|
|
43
|
-
return {
|
|
44
|
-
[Symbol.asyncIterator]: async function* () {
|
|
45
|
-
var _a, _b, _c;
|
|
46
|
-
let thinkPhase = "pre";
|
|
47
|
-
let scanningForClose = false;
|
|
48
|
-
let closeSearchBuffer = "";
|
|
49
|
-
let visibleTextTail = "";
|
|
50
|
-
function rememberVisibleText(text) {
|
|
51
|
-
if (!text) return;
|
|
52
|
-
visibleTextTail = (visibleTextTail + text).slice(-256);
|
|
53
|
-
}
|
|
54
|
-
function hasNearbyVisibleOpenThink(maxDistance = 4) {
|
|
55
|
-
const openIdx = visibleTextTail.lastIndexOf("<think>");
|
|
56
|
-
const closeIdx = visibleTextTail.lastIndexOf(THINK_END);
|
|
57
|
-
if (openIdx === -1 || openIdx < closeIdx) return false;
|
|
58
|
-
return visibleTextTail.length - (openIdx + "<think>".length) <= maxDistance;
|
|
59
|
-
}
|
|
60
|
-
function processContent(raw) {
|
|
61
|
-
if (!raw) return { text: "", thinking: "" };
|
|
62
|
-
if (thinkPhase === "post") return { text: raw, thinking: "" };
|
|
63
|
-
if (thinkPhase === "pre") {
|
|
64
|
-
if (raw.startsWith("<think>")) {
|
|
65
|
-
thinkPhase = "in";
|
|
66
|
-
raw = raw.slice(7);
|
|
67
|
-
} else {
|
|
68
|
-
thinkPhase = "post";
|
|
69
|
-
return { text: raw, thinking: "" };
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
const endIdx = raw.indexOf(THINK_END);
|
|
73
|
-
if (endIdx === -1) return { text: "", thinking: raw };
|
|
74
|
-
const thinking = raw.slice(0, endIdx);
|
|
75
|
-
thinkPhase = "post";
|
|
76
|
-
return { text: raw.slice(endIdx + THINK_END.length), thinking };
|
|
77
|
-
}
|
|
78
|
-
const requestParams = {
|
|
79
|
-
model: profile.model,
|
|
80
|
-
messages,
|
|
81
|
-
stream: true,
|
|
82
|
-
stream_options: { include_usage: true }
|
|
83
|
-
};
|
|
84
|
-
if (tools && tools.length > 0) {
|
|
85
|
-
requestParams.tools = tools;
|
|
86
|
-
}
|
|
87
|
-
const response = await openai.chat.completions.create(
|
|
88
|
-
requestParams,
|
|
89
|
-
signal ? { signal } : void 0
|
|
90
|
-
);
|
|
91
|
-
const tcAccumulator = /* @__PURE__ */ new Map();
|
|
92
|
-
let reasoningAccumulator = "";
|
|
93
|
-
const reasoningDetailsAcc = /* @__PURE__ */ new Map();
|
|
94
|
-
for await (const chunk of response) {
|
|
95
|
-
const choice = chunk.choices[0];
|
|
96
|
-
if (!choice) continue;
|
|
97
|
-
const delta = choice.delta;
|
|
98
|
-
if (delta.reasoning_content) {
|
|
99
|
-
reasoningAccumulator += delta.reasoning_content;
|
|
100
|
-
}
|
|
101
|
-
if (delta.reasoning_details && delta.reasoning_details.length > 0) {
|
|
102
|
-
scanningForClose = true;
|
|
103
|
-
for (const rd of delta.reasoning_details) {
|
|
104
|
-
const id = rd.id ?? "";
|
|
105
|
-
const text = rd.text ?? "";
|
|
106
|
-
if (!reasoningDetailsAcc.has(id)) {
|
|
107
|
-
reasoningDetailsAcc.set(id, {
|
|
108
|
-
type: rd.type ?? "reasoning.text",
|
|
109
|
-
id,
|
|
110
|
-
format: rd.format ?? "",
|
|
111
|
-
index: rd.index ?? 0,
|
|
112
|
-
text: ""
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
const existing = reasoningDetailsAcc.get(id);
|
|
116
|
-
existing.text += text;
|
|
117
|
-
if (!delta.reasoning_content && text) {
|
|
118
|
-
reasoningAccumulator += text;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (delta.tool_calls) {
|
|
123
|
-
for (const tc of delta.tool_calls) {
|
|
124
|
-
if (!tcAccumulator.has(tc.index)) {
|
|
125
|
-
tcAccumulator.set(tc.index, {
|
|
126
|
-
id: tc.id ?? "",
|
|
127
|
-
name: ((_a = tc.function) == null ? void 0 : _a.name) ?? "",
|
|
128
|
-
arguments: ""
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
const existing = tcAccumulator.get(tc.index);
|
|
132
|
-
if (tc.id) existing.id = tc.id;
|
|
133
|
-
if ((_b = tc.function) == null ? void 0 : _b.name) existing.name = tc.function.name;
|
|
134
|
-
existing.arguments += ((_c = tc.function) == null ? void 0 : _c.arguments) ?? "";
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const isLast = choice.finish_reason != null;
|
|
138
|
-
let rawToProcess;
|
|
139
|
-
if (delta.reasoning_details && delta.reasoning_details.length > 0) {
|
|
140
|
-
rawToProcess = "";
|
|
141
|
-
} else if (scanningForClose) {
|
|
142
|
-
closeSearchBuffer += delta.content ?? "";
|
|
143
|
-
const closeIdx = closeSearchBuffer.indexOf(THINK_END);
|
|
144
|
-
if (closeIdx !== -1) {
|
|
145
|
-
const openIdx = closeSearchBuffer.lastIndexOf("<think>", closeIdx);
|
|
146
|
-
const hasNearbyLiteralPair = openIdx !== -1 && closeIdx - (openIdx + "<think>".length) <= 8;
|
|
147
|
-
const afterClose = closeSearchBuffer.slice(closeIdx + THINK_END.length);
|
|
148
|
-
rawToProcess = hasNearbyLiteralPair ? closeSearchBuffer : afterClose.length > 0 ? afterClose : closeSearchBuffer.slice(0, closeIdx);
|
|
149
|
-
scanningForClose = false;
|
|
150
|
-
closeSearchBuffer = "";
|
|
151
|
-
thinkPhase = "post";
|
|
152
|
-
} else if (isLast) {
|
|
153
|
-
rawToProcess = closeSearchBuffer;
|
|
154
|
-
scanningForClose = false;
|
|
155
|
-
closeSearchBuffer = "";
|
|
156
|
-
thinkPhase = "post";
|
|
157
|
-
} else {
|
|
158
|
-
rawToProcess = "";
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
rawToProcess = delta.content ?? "";
|
|
162
|
-
}
|
|
163
|
-
if (thinkPhase === "post" && rawToProcess.endsWith(THINK_END) && !rawToProcess.includes("<think>") && !hasNearbyVisibleOpenThink()) {
|
|
164
|
-
rawToProcess = rawToProcess.slice(0, -THINK_END.length);
|
|
165
|
-
}
|
|
166
|
-
const { text: filteredText, thinking: thinkContent } = processContent(rawToProcess);
|
|
167
|
-
rememberVisibleText(filteredText);
|
|
168
|
-
if (thinkContent) {
|
|
169
|
-
reasoningAccumulator += thinkContent;
|
|
170
|
-
}
|
|
171
|
-
if (isLast) {
|
|
172
|
-
const rawUsage = chunk.usage;
|
|
173
|
-
yield {
|
|
174
|
-
text: filteredText,
|
|
175
|
-
done: true,
|
|
176
|
-
finishReason: choice.finish_reason,
|
|
177
|
-
// tcAccumulator 为空说明本轮没有工具调用,传 undefined 而非空数组,
|
|
178
|
-
// 让调用方用 if (chunk.toolCalls) 做简洁判断
|
|
179
|
-
toolCalls: tcAccumulator.size > 0 ? Array.from(tcAccumulator.values()) : void 0,
|
|
180
|
-
reasoning: reasoningAccumulator || void 0,
|
|
181
|
-
// reasoningDetails 仅在流中出现过结构化推理时返回(MiniMax 兼容)
|
|
182
|
-
reasoningDetails: reasoningDetailsAcc.size > 0 ? Array.from(reasoningDetailsAcc.values()) : void 0,
|
|
183
|
-
// 将 snake_case 的原始字段映射为 camelCase,对外接口保持一致
|
|
184
|
-
usage: rawUsage ? {
|
|
185
|
-
promptTokens: rawUsage.prompt_tokens,
|
|
186
|
-
completionTokens: rawUsage.completion_tokens,
|
|
187
|
-
totalTokens: rawUsage.total_tokens
|
|
188
|
-
} : void 0
|
|
189
|
-
};
|
|
190
|
-
} else {
|
|
191
|
-
const incrementalReasoning = delta.reasoning_content || thinkContent || (delta.reasoning_details && delta.reasoning_details.length > 0 ? delta.reasoning_details.map((rd) => rd.text ?? "").join("") : void 0) || void 0;
|
|
192
|
-
yield {
|
|
193
|
-
text: filteredText,
|
|
194
|
-
reasoning: incrementalReasoning || void 0,
|
|
195
|
-
done: false
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// src/providers/anthropic.ts
|
|
206
|
-
import https from "https";
|
|
207
|
-
import { URL as URL2 } from "url";
|
|
208
|
-
function convertMessagesToAnthropic(messages) {
|
|
209
|
-
let system = "";
|
|
210
|
-
const anthropicMessages = [];
|
|
211
|
-
for (let i = 0; i < messages.length; i++) {
|
|
212
|
-
const msg = messages[i];
|
|
213
|
-
if (msg.role === "system") {
|
|
214
|
-
system = msg.content;
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
if (msg.role === "user") {
|
|
218
|
-
anthropicMessages.push({ role: "user", content: msg.content });
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
if (msg.role === "tool") {
|
|
222
|
-
const toolResults = [];
|
|
223
|
-
while (i < messages.length && messages[i].role === "tool") {
|
|
224
|
-
const toolMsg = messages[i];
|
|
225
|
-
toolResults.push({
|
|
226
|
-
type: "tool_result",
|
|
227
|
-
tool_use_id: toolMsg.tool_call_id,
|
|
228
|
-
content: toolMsg.content
|
|
229
|
-
});
|
|
230
|
-
i++;
|
|
231
|
-
}
|
|
232
|
-
i--;
|
|
233
|
-
anthropicMessages.push({ role: "user", content: toolResults });
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
if (msg.role === "assistant") {
|
|
237
|
-
if (msg.tool_calls && msg.tool_calls.length > 0) {
|
|
238
|
-
const content = [];
|
|
239
|
-
if (msg.content) content.push({ type: "text", text: msg.content });
|
|
240
|
-
for (const tc of msg.tool_calls) {
|
|
241
|
-
let input = {};
|
|
242
|
-
try {
|
|
243
|
-
input = JSON.parse(tc.function.arguments);
|
|
244
|
-
} catch {
|
|
245
|
-
input = {};
|
|
246
|
-
}
|
|
247
|
-
content.push({ type: "tool_use", id: tc.id, name: tc.function.name, input });
|
|
248
|
-
}
|
|
249
|
-
anthropicMessages.push({ role: "assistant", content });
|
|
250
|
-
} else {
|
|
251
|
-
anthropicMessages.push({ role: "assistant", content: msg.content ?? "" });
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
return { system, anthropicMessages };
|
|
256
|
-
}
|
|
257
|
-
function convertToolsToAnthropic(tools) {
|
|
258
|
-
return tools.map((tool) => ({
|
|
259
|
-
name: tool.function.name,
|
|
260
|
-
description: tool.function.description,
|
|
261
|
-
input_schema: tool.function.parameters
|
|
262
|
-
}));
|
|
263
|
-
}
|
|
264
|
-
function createAnthropicProvider(profile) {
|
|
265
|
-
const capabilities = Object.freeze(
|
|
266
|
-
Object.defineProperties({}, {
|
|
267
|
-
supportsTools: { value: true, writable: false, enumerable: true },
|
|
268
|
-
supportsReasoningStream: { value: false, writable: false, enumerable: true },
|
|
269
|
-
supportsImages: { value: true, writable: false, enumerable: true },
|
|
270
|
-
supportsJsonSchema: { value: true, writable: false, enumerable: true }
|
|
271
|
-
})
|
|
272
|
-
);
|
|
273
|
-
return {
|
|
274
|
-
capabilities,
|
|
275
|
-
stream(messages, tools, signal) {
|
|
276
|
-
return streamAnthropicResponse(profile, messages, tools, signal);
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
async function* streamAnthropicResponse(profile, messages, tools, signal) {
|
|
281
|
-
const { system, anthropicMessages } = convertMessagesToAnthropic(messages);
|
|
282
|
-
const endpointUrl = new URL2(`${profile.baseUrl.replace(/\/v1\/?$/, "").replace(/\/$/, "")}/v1/messages`);
|
|
283
|
-
const requestBody = {
|
|
284
|
-
model: profile.model,
|
|
285
|
-
max_tokens: 8192,
|
|
286
|
-
messages: anthropicMessages,
|
|
287
|
-
stream: true
|
|
288
|
-
};
|
|
289
|
-
if (system) requestBody.system = system;
|
|
290
|
-
if (tools && tools.length > 0) requestBody.tools = convertToolsToAnthropic(tools);
|
|
291
|
-
const bodyStr = JSON.stringify(requestBody);
|
|
292
|
-
yield* makeHttpsStream(endpointUrl, profile.apiKey, bodyStr, signal);
|
|
293
|
-
}
|
|
294
|
-
async function* makeHttpsStream(url, apiKey, body, signal) {
|
|
295
|
-
var _a;
|
|
296
|
-
const queue = [];
|
|
297
|
-
let notify = null;
|
|
298
|
-
function push(item) {
|
|
299
|
-
queue.push(item);
|
|
300
|
-
if (notify) {
|
|
301
|
-
const fn = notify;
|
|
302
|
-
notify = null;
|
|
303
|
-
fn();
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
const port = url.port ? parseInt(url.port, 10) : 443;
|
|
307
|
-
const req = https.request(
|
|
308
|
-
{
|
|
309
|
-
hostname: url.hostname,
|
|
310
|
-
port,
|
|
311
|
-
path: url.pathname + url.search,
|
|
312
|
-
method: "POST",
|
|
313
|
-
headers: {
|
|
314
|
-
"x-api-key": apiKey,
|
|
315
|
-
"anthropic-version": "2023-06-01",
|
|
316
|
-
"content-type": "application/json",
|
|
317
|
-
accept: "text/event-stream",
|
|
318
|
-
"content-length": String(Buffer.byteLength(body, "utf8"))
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
(res) => {
|
|
322
|
-
const statusCode = res.statusCode;
|
|
323
|
-
if (statusCode !== 200) {
|
|
324
|
-
push(new Error(`Anthropic API error: HTTP ${statusCode}`));
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
const r = res;
|
|
328
|
-
r.on("data", (chunk) => push(chunk));
|
|
329
|
-
r.on("end", () => push(null));
|
|
330
|
-
r.on("error", (err) => push(err));
|
|
331
|
-
}
|
|
332
|
-
);
|
|
333
|
-
req.on("error", (err) => push(err));
|
|
334
|
-
if (signal) {
|
|
335
|
-
signal.addEventListener(
|
|
336
|
-
"abort",
|
|
337
|
-
() => {
|
|
338
|
-
req.destroy();
|
|
339
|
-
push(null);
|
|
340
|
-
},
|
|
341
|
-
{ once: true }
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
req.write(body);
|
|
345
|
-
req.end();
|
|
346
|
-
let buffer = "";
|
|
347
|
-
const toolBlocks = /* @__PURE__ */ new Map();
|
|
348
|
-
let stopReason = null;
|
|
349
|
-
let inputTokens = 0;
|
|
350
|
-
let outputTokens = 0;
|
|
351
|
-
while (true) {
|
|
352
|
-
let item;
|
|
353
|
-
if (queue.length > 0) {
|
|
354
|
-
item = queue.shift();
|
|
355
|
-
} else {
|
|
356
|
-
await new Promise((resolve4) => {
|
|
357
|
-
notify = resolve4;
|
|
358
|
-
});
|
|
359
|
-
item = queue.shift();
|
|
360
|
-
}
|
|
361
|
-
if (item === null) break;
|
|
362
|
-
if (item instanceof Error) throw item;
|
|
363
|
-
buffer += item.toString("utf8");
|
|
364
|
-
const lines = buffer.split("\n");
|
|
365
|
-
buffer = lines.pop() ?? "";
|
|
366
|
-
for (const line of lines) {
|
|
367
|
-
if (!line.startsWith("data: ")) continue;
|
|
368
|
-
const data = line.slice(6).trim();
|
|
369
|
-
if (data === "[DONE]") break;
|
|
370
|
-
let event;
|
|
371
|
-
try {
|
|
372
|
-
event = JSON.parse(data);
|
|
373
|
-
} catch {
|
|
374
|
-
continue;
|
|
375
|
-
}
|
|
376
|
-
const eventType = event.type;
|
|
377
|
-
if (eventType === "message_start") {
|
|
378
|
-
const msg = event.message;
|
|
379
|
-
if ((_a = msg == null ? void 0 : msg.usage) == null ? void 0 : _a.input_tokens) inputTokens = msg.usage.input_tokens;
|
|
380
|
-
} else if (eventType === "content_block_start") {
|
|
381
|
-
const block = event.content_block;
|
|
382
|
-
const index = event.index;
|
|
383
|
-
if ((block == null ? void 0 : block.type) === "tool_use" && block.id && block.name) {
|
|
384
|
-
toolBlocks.set(index, { id: block.id, name: block.name, jsonAccum: "" });
|
|
385
|
-
}
|
|
386
|
-
} else if (eventType === "content_block_delta") {
|
|
387
|
-
const delta = event.delta;
|
|
388
|
-
const index = event.index;
|
|
389
|
-
if ((delta == null ? void 0 : delta.type) === "text_delta" && delta.text) {
|
|
390
|
-
yield { text: delta.text, done: false };
|
|
391
|
-
} else if ((delta == null ? void 0 : delta.type) === "input_json_delta" && delta.partial_json) {
|
|
392
|
-
const tool = toolBlocks.get(index);
|
|
393
|
-
if (tool) tool.jsonAccum += delta.partial_json;
|
|
394
|
-
}
|
|
395
|
-
} else if (eventType === "message_delta") {
|
|
396
|
-
const delta = event.delta;
|
|
397
|
-
stopReason = (delta == null ? void 0 : delta.stop_reason) ?? null;
|
|
398
|
-
const usage = event.usage;
|
|
399
|
-
if (usage == null ? void 0 : usage.output_tokens) outputTokens = usage.output_tokens;
|
|
400
|
-
} else if (eventType === "message_stop") {
|
|
401
|
-
const toolCalls = [...toolBlocks.values()].map((t) => ({
|
|
402
|
-
id: t.id,
|
|
403
|
-
name: t.name,
|
|
404
|
-
arguments: t.jsonAccum
|
|
405
|
-
}));
|
|
406
|
-
yield {
|
|
407
|
-
done: true,
|
|
408
|
-
text: "",
|
|
409
|
-
finishReason: stopReason,
|
|
410
|
-
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
411
|
-
usage: {
|
|
412
|
-
promptTokens: inputTokens,
|
|
413
|
-
completionTokens: outputTokens,
|
|
414
|
-
totalTokens: inputTokens + outputTokens
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
yield { done: true, text: "", finishReason: stopReason };
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// src/providers/index.ts
|
|
425
|
-
function createProvider(profile) {
|
|
426
|
-
const useAnthropic = profile.apiFormat === "anthropic" || profile.baseUrl.includes("anthropic");
|
|
427
|
-
return useAnthropic ? createAnthropicProvider(profile) : createOpenAIProvider(profile);
|
|
428
|
-
}
|
|
429
|
-
function resolveActiveProfile(config, providerName) {
|
|
430
|
-
var _a, _b;
|
|
431
|
-
if (providerName !== void 0) {
|
|
432
|
-
const profile = (_a = config.providers) == null ? void 0 : _a[providerName];
|
|
433
|
-
if (!profile) {
|
|
434
|
-
throw new Error(`Provider '${providerName}' not found`);
|
|
435
|
-
}
|
|
436
|
-
return profile;
|
|
437
|
-
}
|
|
438
|
-
if (config.defaultProvider) {
|
|
439
|
-
const profile = (_b = config.providers) == null ? void 0 : _b[config.defaultProvider];
|
|
440
|
-
if (profile) return profile;
|
|
441
|
-
}
|
|
442
|
-
if (config.providers) {
|
|
443
|
-
if (config.providers["default"]) {
|
|
444
|
-
return config.providers["default"];
|
|
445
|
-
}
|
|
446
|
-
const first = Object.values(config.providers)[0];
|
|
447
|
-
if (first) return first;
|
|
448
|
-
}
|
|
449
|
-
return {
|
|
450
|
-
baseUrl: config.baseUrl,
|
|
451
|
-
apiKey: config.apiKey,
|
|
452
|
-
model: config.model
|
|
453
|
-
};
|
|
454
|
-
}
|
|
7
|
+
} from "./chunk-SIQQG6FT.js";
|
|
455
8
|
|
|
456
9
|
// src/skills/loader.ts
|
|
457
10
|
import { readFile, readdir, stat } from "fs/promises";
|
|
@@ -866,7 +419,7 @@ async function grepFiles(params) {
|
|
|
866
419
|
|
|
867
420
|
// src/tools/web_fetch.ts
|
|
868
421
|
import * as http from "http";
|
|
869
|
-
import * as
|
|
422
|
+
import * as https from "https";
|
|
870
423
|
var WEB_FETCH_TOOL = {
|
|
871
424
|
type: "function",
|
|
872
425
|
function: {
|
|
@@ -1027,7 +580,7 @@ async function nodeHttpFetch(url, signal) {
|
|
|
1027
580
|
return new Promise((resolve4, reject) => {
|
|
1028
581
|
const parsed = new URL(url);
|
|
1029
582
|
const isHttps = parsed.protocol === "https:";
|
|
1030
|
-
const lib = isHttps ?
|
|
583
|
+
const lib = isHttps ? https : http;
|
|
1031
584
|
const onAbort = () => {
|
|
1032
585
|
req.destroy();
|
|
1033
586
|
const err = new Error("The user aborted a request.");
|
|
@@ -2153,8 +1706,6 @@ ${prompt}` : prompt;
|
|
|
2153
1706
|
}
|
|
2154
1707
|
|
|
2155
1708
|
export {
|
|
2156
|
-
createProvider,
|
|
2157
|
-
resolveActiveProfile,
|
|
2158
1709
|
isTrustedSkillPath,
|
|
2159
1710
|
loadSkillsFromDir,
|
|
2160
1711
|
READ_TOOL,
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
cmdSessionsInspect,
|
|
6
6
|
cmdSessionsList,
|
|
7
7
|
cmdSessionsReplay
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-N3IDMSG5.js";
|
|
9
9
|
import {
|
|
10
10
|
APPLY_PATCH_TOOL,
|
|
11
11
|
BASH_TOOL,
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
classifyCommand,
|
|
24
24
|
createLogger,
|
|
25
25
|
createLoggerAtPath,
|
|
26
|
-
createProvider,
|
|
27
26
|
editFile,
|
|
28
27
|
executeBash,
|
|
29
28
|
globFiles,
|
|
@@ -31,18 +30,19 @@ import {
|
|
|
31
30
|
handleTaskTool,
|
|
32
31
|
loadSkillsFromDir,
|
|
33
32
|
readFile,
|
|
34
|
-
resolveActiveProfile,
|
|
35
33
|
todo,
|
|
36
34
|
webFetch,
|
|
37
35
|
writeFile
|
|
38
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-V3JQ7HAU.js";
|
|
39
37
|
import {
|
|
38
|
+
createProvider,
|
|
40
39
|
createSessionMetadata,
|
|
41
40
|
generateTitle,
|
|
42
41
|
loadConfig,
|
|
42
|
+
resolveActiveProfile,
|
|
43
43
|
updateSessionMetadata,
|
|
44
44
|
writeSessionMetadata
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-SIQQG6FT.js";
|
|
46
46
|
|
|
47
47
|
// src/index.ts
|
|
48
48
|
import { createRequire } from "module";
|
|
@@ -814,7 +814,7 @@ if (rawArgs[0] === "web") {
|
|
|
814
814
|
webAutoApprove = true;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
const { buildServer, generateAccessToken } = await import("./web-
|
|
817
|
+
const { buildServer, generateAccessToken } = await import("./web-XPP3PJJZ.js");
|
|
818
818
|
const token = finalConfig.webToken ?? generateAccessToken();
|
|
819
819
|
const manager = new SessionManager(finalConfig);
|
|
820
820
|
const __webDirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -923,6 +923,6 @@ Node.js 16/18 \u8BF7\u4F7F\u7528 --web \u6216 --pipe \u6A21\u5F0F\u3002
|
|
|
923
923
|
);
|
|
924
924
|
process.exit(1);
|
|
925
925
|
}
|
|
926
|
-
const { App, React, render } = await import("./ui-
|
|
926
|
+
const { App, React, render } = await import("./ui-6WIYQZ7Y.js");
|
|
927
927
|
render(React.createElement(App, { config: finalConfig, version: VERSION, autoMode, registry, trustedSkillDirs, initialMessages }));
|
|
928
928
|
}
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
WRITE_TOOL,
|
|
14
14
|
applyPatch,
|
|
15
15
|
createLogger,
|
|
16
|
-
createProvider,
|
|
17
16
|
editFile,
|
|
18
17
|
executeBash,
|
|
19
18
|
globFiles,
|
|
@@ -22,11 +21,10 @@ import {
|
|
|
22
21
|
handleTaskTool,
|
|
23
22
|
isTrustedSkillPath,
|
|
24
23
|
readFile,
|
|
25
|
-
resolveActiveProfile,
|
|
26
24
|
todo,
|
|
27
25
|
webFetch,
|
|
28
26
|
writeFile
|
|
29
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-V3JQ7HAU.js";
|
|
30
28
|
import {
|
|
31
29
|
handleSkillInput,
|
|
32
30
|
loadJobs,
|
|
@@ -34,12 +32,14 @@ import {
|
|
|
34
32
|
upsertJob
|
|
35
33
|
} from "./chunk-ZPGOARYH.js";
|
|
36
34
|
import {
|
|
35
|
+
createProvider,
|
|
37
36
|
createSessionMetadata,
|
|
38
37
|
generateTitle,
|
|
39
38
|
getContextLimit,
|
|
39
|
+
resolveActiveProfile,
|
|
40
40
|
updateSessionMetadata,
|
|
41
41
|
writeSessionMetadata
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-SIQQG6FT.js";
|
|
43
43
|
|
|
44
44
|
// src/ui/index.ts
|
|
45
45
|
import { default as default2 } from "react";
|
|
@@ -758,35 +758,6 @@ function confirmSelection(inputText, selectedPath) {
|
|
|
758
758
|
return `${prefix}@${selectedPath} `;
|
|
759
759
|
}
|
|
760
760
|
|
|
761
|
-
// src/ui/mouseInput.ts
|
|
762
|
-
var SGR_MOUSE_RE = /^\x1b\[<(\d+);\d+;\d+[Mm]/;
|
|
763
|
-
function mouseEventLength(data) {
|
|
764
|
-
const s = typeof data === "string" ? data : data.toString("binary");
|
|
765
|
-
if (!s) return 0;
|
|
766
|
-
const sgrMatch = SGR_MOUSE_RE.exec(s);
|
|
767
|
-
if (sgrMatch) return sgrMatch[0].length;
|
|
768
|
-
if (s.length >= 6 && s.charCodeAt(0) === 27 && s[1] === "[" && s[2] === "M") return 6;
|
|
769
|
-
return 0;
|
|
770
|
-
}
|
|
771
|
-
function parseMouseScroll(data) {
|
|
772
|
-
const s = typeof data === "string" ? data : data.toString("binary");
|
|
773
|
-
if (!s) return null;
|
|
774
|
-
const sgrMatch = SGR_MOUSE_RE.exec(s);
|
|
775
|
-
if (sgrMatch) {
|
|
776
|
-
const cb = parseInt(sgrMatch[1], 10);
|
|
777
|
-
if (cb === 64) return { direction: "up" };
|
|
778
|
-
if (cb === 65) return { direction: "down" };
|
|
779
|
-
return null;
|
|
780
|
-
}
|
|
781
|
-
if (s.length >= 6 && s.charCodeAt(0) === 27 && s[1] === "[" && s[2] === "M") {
|
|
782
|
-
const buttonByte = s.charCodeAt(3);
|
|
783
|
-
if (buttonByte === 96) return { direction: "up" };
|
|
784
|
-
if (buttonByte === 97) return { direction: "down" };
|
|
785
|
-
return null;
|
|
786
|
-
}
|
|
787
|
-
return null;
|
|
788
|
-
}
|
|
789
|
-
|
|
790
761
|
// src/ui/App.tsx
|
|
791
762
|
import { homedir as homedir2 } from "os";
|
|
792
763
|
import { join as join4 } from "path";
|
|
@@ -2424,44 +2395,6 @@ function App({ config, version, autoMode = false, registry, trustedSkillDirs = [
|
|
|
2424
2395
|
automationManagerRef.current.stop();
|
|
2425
2396
|
};
|
|
2426
2397
|
}, []);
|
|
2427
|
-
useEffect3(() => {
|
|
2428
|
-
if (!stdin || !stdout) return;
|
|
2429
|
-
stdout.write("\x1B[?1000h\x1B[?1006h");
|
|
2430
|
-
const origEmit = stdin.emit;
|
|
2431
|
-
stdin.emit = function(event, ...args) {
|
|
2432
|
-
if (event === "readable") {
|
|
2433
|
-
const chunk = stdin.read();
|
|
2434
|
-
if (chunk !== null) {
|
|
2435
|
-
const s = typeof chunk === "string" ? chunk : chunk.toString("binary");
|
|
2436
|
-
const mouseLen = mouseEventLength(s);
|
|
2437
|
-
if (mouseLen > 0) {
|
|
2438
|
-
const mouseStr = s.slice(0, mouseLen);
|
|
2439
|
-
const scrollEvent = parseMouseScroll(mouseStr);
|
|
2440
|
-
if (scrollEvent) {
|
|
2441
|
-
if (scrollEvent.direction === "up") {
|
|
2442
|
-
setScrollOffset((prev) => Math.min(prev + 3, Math.max(0, totalLinesRef.current - 1)));
|
|
2443
|
-
} else {
|
|
2444
|
-
setScrollOffset((prev) => Math.max(0, prev - 3));
|
|
2445
|
-
}
|
|
2446
|
-
}
|
|
2447
|
-
const remainder = s.slice(mouseLen);
|
|
2448
|
-
if (remainder.length > 0) {
|
|
2449
|
-
stdin.unshift(
|
|
2450
|
-
typeof chunk === "string" ? remainder : Buffer.from(remainder, "binary")
|
|
2451
|
-
);
|
|
2452
|
-
}
|
|
2453
|
-
} else {
|
|
2454
|
-
stdin.unshift(chunk);
|
|
2455
|
-
}
|
|
2456
|
-
}
|
|
2457
|
-
}
|
|
2458
|
-
return origEmit.apply(stdin, [event, ...args]);
|
|
2459
|
-
};
|
|
2460
|
-
return () => {
|
|
2461
|
-
stdout.write("\x1B[?1000l\x1B[?1006l");
|
|
2462
|
-
stdin.emit = origEmit;
|
|
2463
|
-
};
|
|
2464
|
-
}, [stdin, stdout]);
|
|
2465
2398
|
useEffect3(() => {
|
|
2466
2399
|
const atFragment = extractAtQuery(fileAcState.query);
|
|
2467
2400
|
if (atFragment === null) {
|
|
@@ -3,7 +3,7 @@ const _ew=process.emitWarning.bind(process);process.emitWarning=function(w,...a)
|
|
|
3
3
|
import {
|
|
4
4
|
cmdSessionsFork,
|
|
5
5
|
cmdSessionsReplay
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-N3IDMSG5.js";
|
|
7
7
|
import {
|
|
8
8
|
handleSkillInput,
|
|
9
9
|
loadJobs,
|
|
@@ -15,8 +15,9 @@ import {
|
|
|
15
15
|
findSession,
|
|
16
16
|
listSessions,
|
|
17
17
|
loadMessagesFromJsonl,
|
|
18
|
+
resolveActiveProfile,
|
|
18
19
|
saveConfig
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-SIQQG6FT.js";
|
|
20
21
|
|
|
21
22
|
// src/web/server.ts
|
|
22
23
|
import Fastify from "fastify";
|
|
@@ -1604,7 +1605,7 @@ async function chatRoutes(app, opts) {
|
|
|
1604
1605
|
if (opts.autoApprove) {
|
|
1605
1606
|
sessionOpts.autoApproveNormal = true;
|
|
1606
1607
|
}
|
|
1607
|
-
if (!opts.config.apiKey) {
|
|
1608
|
+
if (!resolveActiveProfile(opts.config).apiKey) {
|
|
1608
1609
|
return reply.code(400).send({
|
|
1609
1610
|
success: false,
|
|
1610
1611
|
error: "\u672A\u914D\u7F6E API Key\uFF0C\u8BF7\u5148\u70B9\u51FB\u53F3\u4E0A\u89D2\u300C\u914D\u7F6E\u300D\u6309\u94AE\u586B\u5199"
|
|
@@ -1665,7 +1666,7 @@ async function chatRoutes(app, opts) {
|
|
|
1665
1666
|
if (manager.getSession(id)) {
|
|
1666
1667
|
return reply.send({ success: true, resumed: false });
|
|
1667
1668
|
}
|
|
1668
|
-
if (!opts.config.apiKey) {
|
|
1669
|
+
if (!resolveActiveProfile(opts.config).apiKey) {
|
|
1669
1670
|
return reply.code(400).send({
|
|
1670
1671
|
success: false,
|
|
1671
1672
|
error: "\u672A\u914D\u7F6E API Key\uFF0C\u8BF7\u5148\u70B9\u51FB\u53F3\u4E0A\u89D2\u300C\u914D\u7F6E\u300D\u6309\u94AE\u586B\u5199"
|