@zqagent/core 0.3.10 → 0.3.12
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/{TurnEngine-BPKhWuSI.d.cts → TurnEngine-BSciNywD.d.cts} +23 -4
- package/dist/{TurnEngine-DtGEuVLT.d.ts → TurnEngine-BU4R7q_0.d.ts} +23 -4
- package/dist/index.cjs +144 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -4
- package/dist/index.d.ts +53 -4
- package/dist/index.js +142 -21
- package/dist/index.js.map +1 -1
- package/dist/internal/engine/FileLogHook.d.cts +2 -1
- package/dist/internal/engine/FileLogHook.d.ts +2 -1
- package/dist/internal/llmConfig.cjs +15 -0
- package/dist/internal/llmConfig.cjs.map +1 -1
- package/dist/internal/llmConfig.d.cts +15 -0
- package/dist/internal/llmConfig.d.ts +15 -0
- package/dist/internal/llmConfig.js +15 -0
- package/dist/internal/llmConfig.js.map +1 -1
- package/dist/internal/providers/diagnostics.cjs +39 -5
- package/dist/internal/providers/diagnostics.cjs.map +1 -1
- package/dist/internal/providers/diagnostics.d.cts +35 -3
- package/dist/internal/providers/diagnostics.d.ts +35 -3
- package/dist/internal/providers/diagnostics.js +34 -4
- package/dist/internal/providers/diagnostics.js.map +1 -1
- package/dist/internal/providers/models.cjs.map +1 -1
- package/dist/internal/providers/models.js.map +1 -1
- package/dist/internal/update/controller.cjs +2 -2
- package/dist/internal/update/controller.cjs.map +1 -1
- package/dist/internal/update/controller.js +1 -1
- package/dist/internal/update/platform.cjs +2 -2
- package/dist/internal/update/platform.cjs.map +1 -1
- package/dist/internal/update/platform.js +1 -1
- package/dist/tools/explore.cjs +76 -4
- package/dist/tools/explore.cjs.map +1 -1
- package/dist/tools/explore.d.cts +2 -1
- package/dist/tools/explore.d.ts +2 -1
- package/dist/tools/explore.js +76 -4
- package/dist/tools/explore.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { T as TokenUsage, M as Message, a as ToolSchema, R as ReasoningEffort, S as StreamChunk, b as MessageAttachment, c as StoredAttachment } from './types-BYyXWWPW.cjs';
|
|
2
2
|
import { a as ToolMetadata, T as ToolRegistry } from './ToolRegistry-DouDvn9E.cjs';
|
|
3
|
+
import { ApiMode } from './internal/providers/diagnostics.cjs';
|
|
3
4
|
import { ChatCompletionMessageParam } from 'openai/resources/chat/completions.js';
|
|
4
5
|
import { RequestOptions } from 'openai/core.mjs';
|
|
5
6
|
import { ModelCapability } from '@zqagent/shared/model-capabilities';
|
|
@@ -344,22 +345,40 @@ declare class OpenAIProvider implements ProviderClient {
|
|
|
344
345
|
private _logDir?;
|
|
345
346
|
/** 服务端点 baseURL(用于识别 DeepSeek 等特定供应商) */
|
|
346
347
|
private _baseURL;
|
|
347
|
-
/**
|
|
348
|
-
|
|
348
|
+
/**
|
|
349
|
+
* 本实例的 API 模式。
|
|
350
|
+
*
|
|
351
|
+
* 显式配置 > 全局 `OPENAI_FORCE_API_MODE` > auto(先 Responses 再降级)。
|
|
352
|
+
* 早先只有全局环境变量一种表达方式,一个节点挂两家供应商时无法各自指定。
|
|
353
|
+
*/
|
|
354
|
+
private _apiMode;
|
|
349
355
|
constructor(opts: {
|
|
350
356
|
apiKey?: string;
|
|
351
357
|
baseURL?: string;
|
|
352
358
|
/** LLM 请求日志根目录,按日期分目录,不传则不记录 */
|
|
353
359
|
logDir?: string;
|
|
360
|
+
/**
|
|
361
|
+
* 单次请求超时(毫秒)。缺省/非法时回落到 `OPENAI_TIMEOUT_MS`,再回落 10 分钟。
|
|
362
|
+
*
|
|
363
|
+
* 必须能按供应商设置:推理模型的合理预算与普通模型差一个数量级,共用一个全局值
|
|
364
|
+
* 只能二选一(慢模型被掐断,或快模型失败时干等十分钟)。
|
|
365
|
+
*/
|
|
366
|
+
timeoutMs?: number | null;
|
|
367
|
+
/**
|
|
368
|
+
* API 模式(auto / responses / chat)。缺省时读 `OPENAI_FORCE_API_MODE`,再缺省 auto。
|
|
369
|
+
*/
|
|
370
|
+
apiMode?: ApiMode | null;
|
|
354
371
|
});
|
|
355
372
|
/**
|
|
356
373
|
* 解析指定模型的 API 模式。
|
|
357
374
|
*
|
|
358
|
-
*
|
|
359
|
-
* >
|
|
375
|
+
* 优先级:本实例的显式配置(responses|chat)
|
|
376
|
+
* > 运行时降级缓存(该端点+模型曾因"不支持"失败而缓存为 chat)
|
|
360
377
|
* > 默认 responses(Responses 优先)。
|
|
361
378
|
*/
|
|
362
379
|
private _resolveMode;
|
|
380
|
+
/** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
|
|
381
|
+
private _markChatMode;
|
|
363
382
|
/**
|
|
364
383
|
* Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。
|
|
365
384
|
*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { T as TokenUsage, M as Message, a as ToolSchema, R as ReasoningEffort, S as StreamChunk, b as MessageAttachment, c as StoredAttachment } from './types-BYyXWWPW.js';
|
|
2
2
|
import { a as ToolMetadata, T as ToolRegistry } from './ToolRegistry-Cy0fQxrb.js';
|
|
3
|
+
import { ApiMode } from './internal/providers/diagnostics.js';
|
|
3
4
|
import { ChatCompletionMessageParam } from 'openai/resources/chat/completions.js';
|
|
4
5
|
import { RequestOptions } from 'openai/core.mjs';
|
|
5
6
|
import { ModelCapability } from '@zqagent/shared/model-capabilities';
|
|
@@ -344,22 +345,40 @@ declare class OpenAIProvider implements ProviderClient {
|
|
|
344
345
|
private _logDir?;
|
|
345
346
|
/** 服务端点 baseURL(用于识别 DeepSeek 等特定供应商) */
|
|
346
347
|
private _baseURL;
|
|
347
|
-
/**
|
|
348
|
-
|
|
348
|
+
/**
|
|
349
|
+
* 本实例的 API 模式。
|
|
350
|
+
*
|
|
351
|
+
* 显式配置 > 全局 `OPENAI_FORCE_API_MODE` > auto(先 Responses 再降级)。
|
|
352
|
+
* 早先只有全局环境变量一种表达方式,一个节点挂两家供应商时无法各自指定。
|
|
353
|
+
*/
|
|
354
|
+
private _apiMode;
|
|
349
355
|
constructor(opts: {
|
|
350
356
|
apiKey?: string;
|
|
351
357
|
baseURL?: string;
|
|
352
358
|
/** LLM 请求日志根目录,按日期分目录,不传则不记录 */
|
|
353
359
|
logDir?: string;
|
|
360
|
+
/**
|
|
361
|
+
* 单次请求超时(毫秒)。缺省/非法时回落到 `OPENAI_TIMEOUT_MS`,再回落 10 分钟。
|
|
362
|
+
*
|
|
363
|
+
* 必须能按供应商设置:推理模型的合理预算与普通模型差一个数量级,共用一个全局值
|
|
364
|
+
* 只能二选一(慢模型被掐断,或快模型失败时干等十分钟)。
|
|
365
|
+
*/
|
|
366
|
+
timeoutMs?: number | null;
|
|
367
|
+
/**
|
|
368
|
+
* API 模式(auto / responses / chat)。缺省时读 `OPENAI_FORCE_API_MODE`,再缺省 auto。
|
|
369
|
+
*/
|
|
370
|
+
apiMode?: ApiMode | null;
|
|
354
371
|
});
|
|
355
372
|
/**
|
|
356
373
|
* 解析指定模型的 API 模式。
|
|
357
374
|
*
|
|
358
|
-
*
|
|
359
|
-
* >
|
|
375
|
+
* 优先级:本实例的显式配置(responses|chat)
|
|
376
|
+
* > 运行时降级缓存(该端点+模型曾因"不支持"失败而缓存为 chat)
|
|
360
377
|
* > 默认 responses(Responses 优先)。
|
|
361
378
|
*/
|
|
362
379
|
private _resolveMode;
|
|
380
|
+
/** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
|
|
381
|
+
private _markChatMode;
|
|
363
382
|
/**
|
|
364
383
|
* Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。
|
|
365
384
|
*
|
package/dist/index.cjs
CHANGED
|
@@ -125,6 +125,8 @@ __export(src_exports, {
|
|
|
125
125
|
registerTerminalTools: () => registerTerminalTools,
|
|
126
126
|
registerTodoTool: () => registerTodoTool,
|
|
127
127
|
registerWebTools: () => registerWebTools,
|
|
128
|
+
repairToolCallHistory: () => repairToolCallHistory,
|
|
129
|
+
repairToolCallHistoryDetailed: () => repairToolCallHistoryDetailed,
|
|
128
130
|
resetFfmpegCache: () => resetFfmpegCache,
|
|
129
131
|
resetSandboxCache: () => resetSandboxCache,
|
|
130
132
|
resolveMedia: () => resolveMedia,
|
|
@@ -345,10 +347,22 @@ function authErrorHints(message, code = "") {
|
|
|
345
347
|
"\u51ED\u636E\u65E0\u6548\uFF1A\u82E5\u7528\u7684\u662F\u300C\u5FD7\u524D\u5927\u6A21\u578B\uFF08\u5185\u7F6E\uFF09\u300D\uFF0C\u5728\u8282\u70B9\u8BBE\u7F6E\u7684\u6A21\u578B\u9875\u70B9\u300C\u5237\u65B0\u5185\u7F6E\u6A21\u578B\u300D\u91CD\u65B0\u9886\u53D6 Key\uFF08\u5728\u63A7\u5236\u53F0\u91CD\u7F6E\u8FC7 Key \u540E\u9700\u8981\u8FD9\u4E00\u6B65\uFF09\uFF1B\u82E5\u662F\u81EA\u586B\u7684\u4F9B\u5E94\u5546\uFF0C\u8BF7\u68C0\u67E5 Key \u662F\u5426\u6B63\u786E\u6216\u5DF2\u8FC7\u671F"
|
|
346
348
|
];
|
|
347
349
|
}
|
|
350
|
+
function toolCallHistoryHints(message, code = "") {
|
|
351
|
+
const text = `${message} ${code}`;
|
|
352
|
+
if (!/tool_calls|tool[_ ]?call[_ ]?id/i.test(text) || !/must be followed by tool messages|insufficient tool messages|no tool output found|tool messages responding/i.test(
|
|
353
|
+
text
|
|
354
|
+
)) {
|
|
355
|
+
return [];
|
|
356
|
+
}
|
|
357
|
+
return [
|
|
358
|
+
"\u8FD9\u4E0D\u662F\u6A21\u578B\u6216\u4F59\u989D\u95EE\u9898\uFF1A\u4F1A\u8BDD\u5386\u53F2\u91CC\u6709\u4E00\u6761\u300C\u5DE5\u5177\u8C03\u7528\u6CA1\u6709\u62FF\u5230\u7ED3\u679C\u300D\u7684\u8BB0\u5F55\uFF08\u901A\u5E38\u662F\u4E0A\u6B21\u5728\u5DE5\u5177\u6267\u884C\u4E2D\u6309\u4E86 Ctrl+C\uFF0C\u6216\u8FDB\u7A0B\u88AB\u4E2D\u65AD\uFF09",
|
|
359
|
+
"\u5F15\u64CE\u5DF2\u81EA\u52A8\u6E05\u7406\u5E76\u91CD\u8BD5\uFF1B\u5982\u679C\u4ECD\u62A5\u540C\u6837\u7684\u9519\u8BEF\uFF0C\u7528 /new \u5F00\u4E00\u4E2A\u65B0\u4F1A\u8BDD\u5373\u53EF\uFF08\u65E7\u4F1A\u8BDD\u7684\u5386\u53F2\u91CC\u8FD8\u7559\u7740\u8FD9\u6761\u8BB0\u5F55\uFF09"
|
|
360
|
+
];
|
|
361
|
+
}
|
|
348
362
|
function paramErrorHints(message, code = "") {
|
|
349
363
|
const text = `${message} ${code}`;
|
|
350
364
|
const hints = [];
|
|
351
|
-
if (/not[_\s]*(activated|enabled|purchased)|arrearage|quota|subscription|insufficient
|
|
365
|
+
if (/not[_\s]*(activated|enabled|purchased)|arrearage|quota|subscription|billing|未开通|欠费|额度|余额不足|insufficient[_\s]*(quota|balance|credit|funds)/i.test(
|
|
352
366
|
text
|
|
353
367
|
)) {
|
|
354
368
|
hints.push(
|
|
@@ -372,9 +386,23 @@ function paramErrorHints(message, code = "") {
|
|
|
372
386
|
}
|
|
373
387
|
return hints;
|
|
374
388
|
}
|
|
375
|
-
|
|
389
|
+
var DEFAULT_LLM_TIMEOUT_MS = 6e5;
|
|
390
|
+
function normLlmTimeoutMs(v) {
|
|
391
|
+
if (v === null || v === void 0 || v === "") return null;
|
|
392
|
+
const n = Number(v);
|
|
393
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
394
|
+
return Math.min(Math.round(n), 30 * 6e4);
|
|
395
|
+
}
|
|
396
|
+
function llmTimeoutMs(explicit) {
|
|
397
|
+
const fromArg = normLlmTimeoutMs(explicit);
|
|
398
|
+
if (fromArg) return fromArg;
|
|
376
399
|
const n = Number(process.env.OPENAI_TIMEOUT_MS);
|
|
377
|
-
return Number.isFinite(n) && n > 0 ? n :
|
|
400
|
+
return Number.isFinite(n) && n > 0 ? n : DEFAULT_LLM_TIMEOUT_MS;
|
|
401
|
+
}
|
|
402
|
+
function normApiMode(v) {
|
|
403
|
+
const s = typeof v === "string" ? v.trim().toLowerCase() : "";
|
|
404
|
+
if (s === "auto" || s === "responses" || s === "chat") return s;
|
|
405
|
+
return null;
|
|
378
406
|
}
|
|
379
407
|
function llmStreamIdleMs() {
|
|
380
408
|
const n = Number(process.env.OPENAI_STREAM_IDLE_MS);
|
|
@@ -2220,6 +2248,76 @@ function applyToolResultBudget(tool, result, opts = {}) {
|
|
|
2220
2248
|
return { content, truncated: true, savedPath };
|
|
2221
2249
|
}
|
|
2222
2250
|
|
|
2251
|
+
// src/engine/history.ts
|
|
2252
|
+
function repairToolCallHistoryDetailed(messages) {
|
|
2253
|
+
const out = [];
|
|
2254
|
+
let droppedCalls = 0;
|
|
2255
|
+
let droppedResults = 0;
|
|
2256
|
+
let droppedMessages = 0;
|
|
2257
|
+
let i = 0;
|
|
2258
|
+
while (i < messages.length) {
|
|
2259
|
+
const m = messages[i];
|
|
2260
|
+
if (m.role === "tool") {
|
|
2261
|
+
droppedResults += 1;
|
|
2262
|
+
i += 1;
|
|
2263
|
+
continue;
|
|
2264
|
+
}
|
|
2265
|
+
const calls = m.role === "assistant" ? m.tool_calls : void 0;
|
|
2266
|
+
if (!calls?.length) {
|
|
2267
|
+
if (m.role === "assistant" && m.tool_calls) {
|
|
2268
|
+
const { tool_calls, ...rest } = m;
|
|
2269
|
+
void tool_calls;
|
|
2270
|
+
out.push(rest);
|
|
2271
|
+
} else {
|
|
2272
|
+
out.push(m);
|
|
2273
|
+
}
|
|
2274
|
+
i += 1;
|
|
2275
|
+
continue;
|
|
2276
|
+
}
|
|
2277
|
+
const responders = /* @__PURE__ */ new Map();
|
|
2278
|
+
const notices = [];
|
|
2279
|
+
let j = i + 1;
|
|
2280
|
+
while (j < messages.length) {
|
|
2281
|
+
const t = messages[j];
|
|
2282
|
+
if (t.role === "notice") {
|
|
2283
|
+
notices.push(t);
|
|
2284
|
+
j += 1;
|
|
2285
|
+
continue;
|
|
2286
|
+
}
|
|
2287
|
+
if (t.role !== "tool") break;
|
|
2288
|
+
if (t.tool_call_id && !responders.has(t.tool_call_id)) {
|
|
2289
|
+
responders.set(t.tool_call_id, t);
|
|
2290
|
+
}
|
|
2291
|
+
j += 1;
|
|
2292
|
+
}
|
|
2293
|
+
const kept = calls.filter((tc) => tc.id && responders.has(tc.id));
|
|
2294
|
+
droppedCalls += calls.length - kept.length;
|
|
2295
|
+
droppedResults += responders.size - kept.length;
|
|
2296
|
+
if (kept.length === 0) {
|
|
2297
|
+
const { tool_calls, ...rest } = m;
|
|
2298
|
+
void tool_calls;
|
|
2299
|
+
if ((rest.content ?? "").trim() !== "") out.push(rest);
|
|
2300
|
+
else droppedMessages += 1;
|
|
2301
|
+
out.push(...notices);
|
|
2302
|
+
} else {
|
|
2303
|
+
out.push(kept.length === calls.length ? m : { ...m, tool_calls: kept });
|
|
2304
|
+
for (const tc of kept) out.push(responders.get(tc.id));
|
|
2305
|
+
out.push(...notices);
|
|
2306
|
+
}
|
|
2307
|
+
i = j;
|
|
2308
|
+
}
|
|
2309
|
+
const unchanged = out.length === messages.length && out.every((m, idx) => m === messages[idx]);
|
|
2310
|
+
return {
|
|
2311
|
+
messages: unchanged ? messages : out,
|
|
2312
|
+
droppedCalls,
|
|
2313
|
+
droppedResults,
|
|
2314
|
+
droppedMessages
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
function repairToolCallHistory(messages) {
|
|
2318
|
+
return repairToolCallHistoryDetailed(messages).messages;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2223
2321
|
// src/engine/TurnEngine.ts
|
|
2224
2322
|
var crypto = __toESM(require("crypto"), 1);
|
|
2225
2323
|
var fs3 = __toESM(require("fs"), 1);
|
|
@@ -2758,6 +2856,7 @@ ${notice}` : text,
|
|
|
2758
2856
|
attachments = routed.attachments;
|
|
2759
2857
|
this.taskId = taskId;
|
|
2760
2858
|
this._turnStartTime = Date.now();
|
|
2859
|
+
this.messages = repairToolCallHistory(this.messages);
|
|
2761
2860
|
this.messages.push({
|
|
2762
2861
|
role: "user",
|
|
2763
2862
|
content: userInput,
|
|
@@ -3759,7 +3858,7 @@ ${notice}` : text,
|
|
|
3759
3858
|
/** 过滤 notice + 剥离 display-only 字段,得到最终发送视图 */
|
|
3760
3859
|
_finalizeOutbound(sourceMessages) {
|
|
3761
3860
|
const _STRIP = /* @__PURE__ */ new Set(["source", "_display", "ts", "reasoning", "usage", "attachmentRefs"]);
|
|
3762
|
-
|
|
3861
|
+
const stripped = sourceMessages.filter((m) => m.role !== "notice").map((m) => {
|
|
3763
3862
|
if (m.role === "tool") {
|
|
3764
3863
|
return {
|
|
3765
3864
|
role: "tool",
|
|
@@ -3768,15 +3867,16 @@ ${notice}` : text,
|
|
|
3768
3867
|
};
|
|
3769
3868
|
}
|
|
3770
3869
|
const staleAttachments = Boolean(m.attachments?.length) && (m.ts ?? 0) < this._turnStartTime;
|
|
3771
|
-
const
|
|
3870
|
+
const plain = {};
|
|
3772
3871
|
for (const [k, v] of Object.entries(m)) {
|
|
3773
3872
|
if (staleAttachments && k === "attachments") continue;
|
|
3774
3873
|
if (!_STRIP.has(k)) {
|
|
3775
|
-
|
|
3874
|
+
plain[k] = v;
|
|
3776
3875
|
}
|
|
3777
3876
|
}
|
|
3778
|
-
return
|
|
3877
|
+
return plain;
|
|
3779
3878
|
});
|
|
3879
|
+
return repairToolCallHistory(stripped);
|
|
3780
3880
|
}
|
|
3781
3881
|
/** 软阈值(token 数):达到它只淘汰旧工具结果 */
|
|
3782
3882
|
_softTriggerTokens() {
|
|
@@ -4529,6 +4629,11 @@ var ResponsesApiError = class extends Error {
|
|
|
4529
4629
|
type;
|
|
4530
4630
|
requestId;
|
|
4531
4631
|
};
|
|
4632
|
+
var NO_AUTH_KEY = "not-needed";
|
|
4633
|
+
var degradedModes = /* @__PURE__ */ new Map();
|
|
4634
|
+
function modeKey(baseURL, model) {
|
|
4635
|
+
return `${baseURL}::${model}`;
|
|
4636
|
+
}
|
|
4532
4637
|
var OpenAIProvider = class {
|
|
4533
4638
|
/** OpenAI SDK 客户端 */
|
|
4534
4639
|
client;
|
|
@@ -4536,23 +4641,31 @@ var OpenAIProvider = class {
|
|
|
4536
4641
|
_logDir;
|
|
4537
4642
|
/** 服务端点 baseURL(用于识别 DeepSeek 等特定供应商) */
|
|
4538
4643
|
_baseURL;
|
|
4539
|
-
/**
|
|
4540
|
-
|
|
4644
|
+
/**
|
|
4645
|
+
* 本实例的 API 模式。
|
|
4646
|
+
*
|
|
4647
|
+
* 显式配置 > 全局 `OPENAI_FORCE_API_MODE` > auto(先 Responses 再降级)。
|
|
4648
|
+
* 早先只有全局环境变量一种表达方式,一个节点挂两家供应商时无法各自指定。
|
|
4649
|
+
*/
|
|
4650
|
+
_apiMode;
|
|
4541
4651
|
constructor(opts) {
|
|
4652
|
+
const explicitKey = opts.apiKey !== void 0;
|
|
4542
4653
|
const apiKey = cleanLlmValue(opts.apiKey ?? process.env.OPENAI_API_KEY);
|
|
4543
4654
|
const baseURL = normalizeBaseURL(opts.baseURL ?? process.env.OPENAI_BASE_URL);
|
|
4544
|
-
if (!apiKey) {
|
|
4655
|
+
if (!apiKey && !explicitKey) {
|
|
4545
4656
|
throw new Error(sanitizeEmoji("\u274C \u672A\u8BBE\u7F6E OPENAI_API_KEY \u73AF\u5883\u53D8\u91CF"));
|
|
4546
4657
|
}
|
|
4658
|
+
const effectiveKey = apiKey ?? NO_AUTH_KEY;
|
|
4547
4659
|
this._baseURL = baseURL ?? "";
|
|
4660
|
+
this._apiMode = normApiMode(opts.apiMode) ?? normApiMode(process.env.OPENAI_FORCE_API_MODE) ?? "auto";
|
|
4548
4661
|
const agent = socksAgent();
|
|
4549
4662
|
const proxyHint = unsupportedProxyHint();
|
|
4550
4663
|
if (proxyHint) console.warn(`[llm] ${proxyHint}`);
|
|
4551
4664
|
const baseFetch = agent ? makeSocksFetch(agent) : ((input, init) => globalThis.fetch(input, init));
|
|
4552
4665
|
this.client = new import_openai.default({
|
|
4553
|
-
apiKey,
|
|
4666
|
+
apiKey: effectiveKey,
|
|
4554
4667
|
...baseURL ? { baseURL } : {},
|
|
4555
|
-
timeout: llmTimeoutMs(),
|
|
4668
|
+
timeout: llmTimeoutMs(opts.timeoutMs),
|
|
4556
4669
|
maxRetries: llmMaxRetries(),
|
|
4557
4670
|
// 类型:SDK 期望 (RequestInfo, RequestInit) => Promise<Response>,
|
|
4558
4671
|
// node-fetch 的 Response 与 DOM Response 结构不同,此处显式放宽
|
|
@@ -4569,14 +4682,17 @@ var OpenAIProvider = class {
|
|
|
4569
4682
|
/**
|
|
4570
4683
|
* 解析指定模型的 API 模式。
|
|
4571
4684
|
*
|
|
4572
|
-
*
|
|
4573
|
-
* >
|
|
4685
|
+
* 优先级:本实例的显式配置(responses|chat)
|
|
4686
|
+
* > 运行时降级缓存(该端点+模型曾因"不支持"失败而缓存为 chat)
|
|
4574
4687
|
* > 默认 responses(Responses 优先)。
|
|
4575
4688
|
*/
|
|
4576
4689
|
_resolveMode(model) {
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4690
|
+
if (this._apiMode !== "auto") return this._apiMode;
|
|
4691
|
+
return degradedModes.get(modeKey(this._baseURL, model)) ?? "responses";
|
|
4692
|
+
}
|
|
4693
|
+
/** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
|
|
4694
|
+
_markChatMode(model) {
|
|
4695
|
+
degradedModes.set(modeKey(this._baseURL, model), "chat");
|
|
4580
4696
|
}
|
|
4581
4697
|
/**
|
|
4582
4698
|
* Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。
|
|
@@ -4652,7 +4768,7 @@ var OpenAIProvider = class {
|
|
|
4652
4768
|
} catch (err) {
|
|
4653
4769
|
const kind = this._responsesFailureKind(err, true);
|
|
4654
4770
|
if (kind) {
|
|
4655
|
-
if (kind === "endpoint") this.
|
|
4771
|
+
if (kind === "endpoint") this._markChatMode(model);
|
|
4656
4772
|
console.warn(
|
|
4657
4773
|
`[llm] ${model} Responses API \u4E0D\u53EF\u7528(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
|
|
4658
4774
|
err?.message ?? err
|
|
@@ -4726,7 +4842,7 @@ var OpenAIProvider = class {
|
|
|
4726
4842
|
} catch (err) {
|
|
4727
4843
|
const kind = this._responsesFailureKind(err, true);
|
|
4728
4844
|
if (kind) {
|
|
4729
|
-
if (kind === "endpoint") this.
|
|
4845
|
+
if (kind === "endpoint") this._markChatMode(model);
|
|
4730
4846
|
console.warn(
|
|
4731
4847
|
`[llm] ${model} Responses API \u4E0D\u53EF\u7528(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
|
|
4732
4848
|
err?.message ?? err
|
|
@@ -4772,7 +4888,7 @@ var OpenAIProvider = class {
|
|
|
4772
4888
|
} catch (err) {
|
|
4773
4889
|
const kind = emitted ? null : this._responsesFailureKind(err, false);
|
|
4774
4890
|
if (!kind) throw enrichLlmError(err, this._baseURL);
|
|
4775
|
-
if (kind === "endpoint") this.
|
|
4891
|
+
if (kind === "endpoint") this._markChatMode(ctx.model);
|
|
4776
4892
|
console.warn(
|
|
4777
4893
|
`[llm] ${ctx.model} Responses \u6D41\u5185\u5931\u8D25(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
|
|
4778
4894
|
err?.message ?? err
|
|
@@ -7296,6 +7412,9 @@ var ConsoleHook = class {
|
|
|
7296
7412
|
for (const hint of authErrorHints(error, errorType)) {
|
|
7297
7413
|
cliLog(` \u{1F4A1} ${hint}`);
|
|
7298
7414
|
}
|
|
7415
|
+
for (const hint of toolCallHistoryHints(error, errorType)) {
|
|
7416
|
+
cliLog(` \u{1F4A1} ${hint}`);
|
|
7417
|
+
}
|
|
7299
7418
|
for (const hint of paramErrorHints(error)) {
|
|
7300
7419
|
cliLog(` \u{1F4A1} ${hint}`);
|
|
7301
7420
|
}
|
|
@@ -13298,6 +13417,8 @@ function createDefaultEngine(opts) {
|
|
|
13298
13417
|
mode = "interactive" /* INTERACTIVE */,
|
|
13299
13418
|
maxIterations = DEFAULT_MAX_ITERATIONS,
|
|
13300
13419
|
reasoningEffort,
|
|
13420
|
+
timeoutMs,
|
|
13421
|
+
apiMode,
|
|
13301
13422
|
allowedCommands = [],
|
|
13302
13423
|
shellPolicy = "approve",
|
|
13303
13424
|
sandbox,
|
|
@@ -13318,7 +13439,7 @@ function createDefaultEngine(opts) {
|
|
|
13318
13439
|
} = opts;
|
|
13319
13440
|
const envEffort = process.env.OPENAI_REASONING_EFFORT?.toLowerCase();
|
|
13320
13441
|
const effectiveEffort = reasoningEffort ?? (envEffort === "low" || envEffort === "medium" || envEffort === "high" ? envEffort : void 0);
|
|
13321
|
-
const effectiveProvider = provider ?? new OpenAIProvider({ logDir });
|
|
13442
|
+
const effectiveProvider = provider ?? new OpenAIProvider({ logDir, timeoutMs, apiMode });
|
|
13322
13443
|
const sandboxPlan = resolveSandbox({ ...sandbox, workspace });
|
|
13323
13444
|
const registry = new ToolRegistry();
|
|
13324
13445
|
const conflictGuard = new ConflictGuard();
|
|
@@ -13489,6 +13610,8 @@ function createDefaultEngine(opts) {
|
|
|
13489
13610
|
registerTerminalTools,
|
|
13490
13611
|
registerTodoTool,
|
|
13491
13612
|
registerWebTools,
|
|
13613
|
+
repairToolCallHistory,
|
|
13614
|
+
repairToolCallHistoryDetailed,
|
|
13492
13615
|
resetFfmpegCache,
|
|
13493
13616
|
resetSandboxCache,
|
|
13494
13617
|
resolveMedia,
|