@zqagent/core 0.3.11 → 0.3.13
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-DtGEuVLT.d.ts → TurnEngine-BZjUGic_.d.ts} +34 -4
- package/dist/{TurnEngine-BPKhWuSI.d.cts → TurnEngine-CMGdcSdp.d.cts} +34 -4
- package/dist/index.cjs +69 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +69 -16
- 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 +30 -5
- package/dist/internal/llmConfig.cjs.map +1 -1
- package/dist/internal/llmConfig.d.cts +32 -1
- package/dist/internal/llmConfig.d.ts +32 -1
- package/dist/internal/llmConfig.js +30 -5
- package/dist/internal/llmConfig.js.map +1 -1
- package/dist/internal/providers/diagnostics.cjs +22 -2
- package/dist/internal/providers/diagnostics.cjs.map +1 -1
- package/dist/internal/providers/diagnostics.d.cts +25 -3
- package/dist/internal/providers/diagnostics.d.ts +25 -3
- package/dist/internal/providers/diagnostics.js +19 -2
- 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 +1 -1
- package/dist/internal/update/controller.js +1 -1
- package/dist/internal/update/platform.cjs +1 -1
- package/dist/internal/update/platform.js +1 -1
- 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.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.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,51 @@ 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: {
|
|
356
|
+
/**
|
|
357
|
+
* API Key。
|
|
358
|
+
*
|
|
359
|
+
* - 显式 `""`(含纯空白):**明确表示该端点不需要鉴权**(本地 Ollama /
|
|
360
|
+
* llama.cpp、内网网关),不会回落到环境变量,SDK 收到占位 Key。
|
|
361
|
+
* - `undefined`:回落到 `OPENAI_API_KEY`;两者都没有时抛错(多数情况是
|
|
362
|
+
* 真的没配,早点给出可读提示好过让用户对着 401 猜)。
|
|
363
|
+
*
|
|
364
|
+
* 调用方不要用「配置里 Key 为空」来推断无需鉴权:那也可能只是还没填,
|
|
365
|
+
* 见 `LlmProviderEntry.noApiKey`。
|
|
366
|
+
*/
|
|
350
367
|
apiKey?: string;
|
|
351
368
|
baseURL?: string;
|
|
352
369
|
/** LLM 请求日志根目录,按日期分目录,不传则不记录 */
|
|
353
370
|
logDir?: string;
|
|
371
|
+
/**
|
|
372
|
+
* 单次请求超时(毫秒)。缺省/非法时回落到 `OPENAI_TIMEOUT_MS`,再回落 10 分钟。
|
|
373
|
+
*
|
|
374
|
+
* 必须能按供应商设置:推理模型的合理预算与普通模型差一个数量级,共用一个全局值
|
|
375
|
+
* 只能二选一(慢模型被掐断,或快模型失败时干等十分钟)。
|
|
376
|
+
*/
|
|
377
|
+
timeoutMs?: number | null;
|
|
378
|
+
/**
|
|
379
|
+
* API 模式(auto / responses / chat)。缺省时读 `OPENAI_FORCE_API_MODE`,再缺省 auto。
|
|
380
|
+
*/
|
|
381
|
+
apiMode?: ApiMode | null;
|
|
354
382
|
});
|
|
355
383
|
/**
|
|
356
384
|
* 解析指定模型的 API 模式。
|
|
357
385
|
*
|
|
358
|
-
*
|
|
359
|
-
* >
|
|
386
|
+
* 优先级:本实例的显式配置(responses|chat)
|
|
387
|
+
* > 运行时降级缓存(该端点+模型曾因"不支持"失败而缓存为 chat)
|
|
360
388
|
* > 默认 responses(Responses 优先)。
|
|
361
389
|
*/
|
|
362
390
|
private _resolveMode;
|
|
391
|
+
/** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
|
|
392
|
+
private _markChatMode;
|
|
363
393
|
/**
|
|
364
394
|
* Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。
|
|
365
395
|
*
|
|
@@ -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,51 @@ 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: {
|
|
356
|
+
/**
|
|
357
|
+
* API Key。
|
|
358
|
+
*
|
|
359
|
+
* - 显式 `""`(含纯空白):**明确表示该端点不需要鉴权**(本地 Ollama /
|
|
360
|
+
* llama.cpp、内网网关),不会回落到环境变量,SDK 收到占位 Key。
|
|
361
|
+
* - `undefined`:回落到 `OPENAI_API_KEY`;两者都没有时抛错(多数情况是
|
|
362
|
+
* 真的没配,早点给出可读提示好过让用户对着 401 猜)。
|
|
363
|
+
*
|
|
364
|
+
* 调用方不要用「配置里 Key 为空」来推断无需鉴权:那也可能只是还没填,
|
|
365
|
+
* 见 `LlmProviderEntry.noApiKey`。
|
|
366
|
+
*/
|
|
350
367
|
apiKey?: string;
|
|
351
368
|
baseURL?: string;
|
|
352
369
|
/** LLM 请求日志根目录,按日期分目录,不传则不记录 */
|
|
353
370
|
logDir?: string;
|
|
371
|
+
/**
|
|
372
|
+
* 单次请求超时(毫秒)。缺省/非法时回落到 `OPENAI_TIMEOUT_MS`,再回落 10 分钟。
|
|
373
|
+
*
|
|
374
|
+
* 必须能按供应商设置:推理模型的合理预算与普通模型差一个数量级,共用一个全局值
|
|
375
|
+
* 只能二选一(慢模型被掐断,或快模型失败时干等十分钟)。
|
|
376
|
+
*/
|
|
377
|
+
timeoutMs?: number | null;
|
|
378
|
+
/**
|
|
379
|
+
* API 模式(auto / responses / chat)。缺省时读 `OPENAI_FORCE_API_MODE`,再缺省 auto。
|
|
380
|
+
*/
|
|
381
|
+
apiMode?: ApiMode | null;
|
|
354
382
|
});
|
|
355
383
|
/**
|
|
356
384
|
* 解析指定模型的 API 模式。
|
|
357
385
|
*
|
|
358
|
-
*
|
|
359
|
-
* >
|
|
386
|
+
* 优先级:本实例的显式配置(responses|chat)
|
|
387
|
+
* > 运行时降级缓存(该端点+模型曾因"不支持"失败而缓存为 chat)
|
|
360
388
|
* > 默认 responses(Responses 优先)。
|
|
361
389
|
*/
|
|
362
390
|
private _resolveMode;
|
|
391
|
+
/** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
|
|
392
|
+
private _markChatMode;
|
|
363
393
|
/**
|
|
364
394
|
* Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。
|
|
365
395
|
*
|
package/dist/index.cjs
CHANGED
|
@@ -386,9 +386,23 @@ function paramErrorHints(message, code = "") {
|
|
|
386
386
|
}
|
|
387
387
|
return hints;
|
|
388
388
|
}
|
|
389
|
-
|
|
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;
|
|
390
399
|
const n = Number(process.env.OPENAI_TIMEOUT_MS);
|
|
391
|
-
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;
|
|
392
406
|
}
|
|
393
407
|
function llmStreamIdleMs() {
|
|
394
408
|
const n = Number(process.env.OPENAI_STREAM_IDLE_MS);
|
|
@@ -4615,6 +4629,32 @@ var ResponsesApiError = class extends Error {
|
|
|
4615
4629
|
type;
|
|
4616
4630
|
requestId;
|
|
4617
4631
|
};
|
|
4632
|
+
var NO_AUTH_KEY = "not-needed";
|
|
4633
|
+
var degradedModes = /* @__PURE__ */ new Map();
|
|
4634
|
+
var DEGRADED_TTL_MS = 30 * 6e4;
|
|
4635
|
+
var DEGRADED_MAX = 500;
|
|
4636
|
+
function modeKey(baseURL, model) {
|
|
4637
|
+
return `${baseURL}::${model}`;
|
|
4638
|
+
}
|
|
4639
|
+
function isDegraded(baseURL, model) {
|
|
4640
|
+
const k = modeKey(baseURL, model);
|
|
4641
|
+
const hit = degradedModes.get(k);
|
|
4642
|
+
if (!hit) return false;
|
|
4643
|
+
if (Date.now() - hit.at > DEGRADED_TTL_MS) {
|
|
4644
|
+
degradedModes.delete(k);
|
|
4645
|
+
return false;
|
|
4646
|
+
}
|
|
4647
|
+
return true;
|
|
4648
|
+
}
|
|
4649
|
+
function markDegraded(baseURL, model) {
|
|
4650
|
+
degradedModes.delete(modeKey(baseURL, model));
|
|
4651
|
+
degradedModes.set(modeKey(baseURL, model), { at: Date.now() });
|
|
4652
|
+
while (degradedModes.size > DEGRADED_MAX) {
|
|
4653
|
+
const oldest = degradedModes.keys().next();
|
|
4654
|
+
if (oldest.done) break;
|
|
4655
|
+
degradedModes.delete(oldest.value);
|
|
4656
|
+
}
|
|
4657
|
+
}
|
|
4618
4658
|
var OpenAIProvider = class {
|
|
4619
4659
|
/** OpenAI SDK 客户端 */
|
|
4620
4660
|
client;
|
|
@@ -4622,23 +4662,31 @@ var OpenAIProvider = class {
|
|
|
4622
4662
|
_logDir;
|
|
4623
4663
|
/** 服务端点 baseURL(用于识别 DeepSeek 等特定供应商) */
|
|
4624
4664
|
_baseURL;
|
|
4625
|
-
/**
|
|
4626
|
-
|
|
4665
|
+
/**
|
|
4666
|
+
* 本实例的 API 模式。
|
|
4667
|
+
*
|
|
4668
|
+
* 显式配置 > 全局 `OPENAI_FORCE_API_MODE` > auto(先 Responses 再降级)。
|
|
4669
|
+
* 早先只有全局环境变量一种表达方式,一个节点挂两家供应商时无法各自指定。
|
|
4670
|
+
*/
|
|
4671
|
+
_apiMode;
|
|
4627
4672
|
constructor(opts) {
|
|
4673
|
+
const explicitKey = opts.apiKey !== void 0;
|
|
4628
4674
|
const apiKey = cleanLlmValue(opts.apiKey ?? process.env.OPENAI_API_KEY);
|
|
4629
4675
|
const baseURL = normalizeBaseURL(opts.baseURL ?? process.env.OPENAI_BASE_URL);
|
|
4630
|
-
if (!apiKey) {
|
|
4676
|
+
if (!apiKey && !explicitKey) {
|
|
4631
4677
|
throw new Error(sanitizeEmoji("\u274C \u672A\u8BBE\u7F6E OPENAI_API_KEY \u73AF\u5883\u53D8\u91CF"));
|
|
4632
4678
|
}
|
|
4679
|
+
const effectiveKey = apiKey ?? NO_AUTH_KEY;
|
|
4633
4680
|
this._baseURL = baseURL ?? "";
|
|
4681
|
+
this._apiMode = normApiMode(opts.apiMode) ?? normApiMode(process.env.OPENAI_FORCE_API_MODE) ?? "auto";
|
|
4634
4682
|
const agent = socksAgent();
|
|
4635
4683
|
const proxyHint = unsupportedProxyHint();
|
|
4636
4684
|
if (proxyHint) console.warn(`[llm] ${proxyHint}`);
|
|
4637
4685
|
const baseFetch = agent ? makeSocksFetch(agent) : ((input, init) => globalThis.fetch(input, init));
|
|
4638
4686
|
this.client = new import_openai.default({
|
|
4639
|
-
apiKey,
|
|
4687
|
+
apiKey: effectiveKey,
|
|
4640
4688
|
...baseURL ? { baseURL } : {},
|
|
4641
|
-
timeout: llmTimeoutMs(),
|
|
4689
|
+
timeout: llmTimeoutMs(opts.timeoutMs),
|
|
4642
4690
|
maxRetries: llmMaxRetries(),
|
|
4643
4691
|
// 类型:SDK 期望 (RequestInfo, RequestInit) => Promise<Response>,
|
|
4644
4692
|
// node-fetch 的 Response 与 DOM Response 结构不同,此处显式放宽
|
|
@@ -4655,14 +4703,17 @@ var OpenAIProvider = class {
|
|
|
4655
4703
|
/**
|
|
4656
4704
|
* 解析指定模型的 API 模式。
|
|
4657
4705
|
*
|
|
4658
|
-
*
|
|
4659
|
-
* >
|
|
4706
|
+
* 优先级:本实例的显式配置(responses|chat)
|
|
4707
|
+
* > 运行时降级缓存(该端点+模型曾因"不支持"失败而缓存为 chat)
|
|
4660
4708
|
* > 默认 responses(Responses 优先)。
|
|
4661
4709
|
*/
|
|
4662
4710
|
_resolveMode(model) {
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4711
|
+
if (this._apiMode !== "auto") return this._apiMode;
|
|
4712
|
+
return isDegraded(this._baseURL, model) ? "chat" : "responses";
|
|
4713
|
+
}
|
|
4714
|
+
/** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
|
|
4715
|
+
_markChatMode(model) {
|
|
4716
|
+
markDegraded(this._baseURL, model);
|
|
4666
4717
|
}
|
|
4667
4718
|
/**
|
|
4668
4719
|
* Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。
|
|
@@ -4738,7 +4789,7 @@ var OpenAIProvider = class {
|
|
|
4738
4789
|
} catch (err) {
|
|
4739
4790
|
const kind = this._responsesFailureKind(err, true);
|
|
4740
4791
|
if (kind) {
|
|
4741
|
-
if (kind === "endpoint") this.
|
|
4792
|
+
if (kind === "endpoint") this._markChatMode(model);
|
|
4742
4793
|
console.warn(
|
|
4743
4794
|
`[llm] ${model} Responses API \u4E0D\u53EF\u7528(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
|
|
4744
4795
|
err?.message ?? err
|
|
@@ -4812,7 +4863,7 @@ var OpenAIProvider = class {
|
|
|
4812
4863
|
} catch (err) {
|
|
4813
4864
|
const kind = this._responsesFailureKind(err, true);
|
|
4814
4865
|
if (kind) {
|
|
4815
|
-
if (kind === "endpoint") this.
|
|
4866
|
+
if (kind === "endpoint") this._markChatMode(model);
|
|
4816
4867
|
console.warn(
|
|
4817
4868
|
`[llm] ${model} Responses API \u4E0D\u53EF\u7528(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
|
|
4818
4869
|
err?.message ?? err
|
|
@@ -4858,7 +4909,7 @@ var OpenAIProvider = class {
|
|
|
4858
4909
|
} catch (err) {
|
|
4859
4910
|
const kind = emitted ? null : this._responsesFailureKind(err, false);
|
|
4860
4911
|
if (!kind) throw enrichLlmError(err, this._baseURL);
|
|
4861
|
-
if (kind === "endpoint") this.
|
|
4912
|
+
if (kind === "endpoint") this._markChatMode(ctx.model);
|
|
4862
4913
|
console.warn(
|
|
4863
4914
|
`[llm] ${ctx.model} Responses \u6D41\u5185\u5931\u8D25(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
|
|
4864
4915
|
err?.message ?? err
|
|
@@ -13387,6 +13438,8 @@ function createDefaultEngine(opts) {
|
|
|
13387
13438
|
mode = "interactive" /* INTERACTIVE */,
|
|
13388
13439
|
maxIterations = DEFAULT_MAX_ITERATIONS,
|
|
13389
13440
|
reasoningEffort,
|
|
13441
|
+
timeoutMs,
|
|
13442
|
+
apiMode,
|
|
13390
13443
|
allowedCommands = [],
|
|
13391
13444
|
shellPolicy = "approve",
|
|
13392
13445
|
sandbox,
|
|
@@ -13407,7 +13460,7 @@ function createDefaultEngine(opts) {
|
|
|
13407
13460
|
} = opts;
|
|
13408
13461
|
const envEffort = process.env.OPENAI_REASONING_EFFORT?.toLowerCase();
|
|
13409
13462
|
const effectiveEffort = reasoningEffort ?? (envEffort === "low" || envEffort === "medium" || envEffort === "high" ? envEffort : void 0);
|
|
13410
|
-
const effectiveProvider = provider ?? new OpenAIProvider({ logDir });
|
|
13463
|
+
const effectiveProvider = provider ?? new OpenAIProvider({ logDir, timeoutMs, apiMode });
|
|
13411
13464
|
const sandboxPlan = resolveSandbox({ ...sandbox, workspace });
|
|
13412
13465
|
const registry = new ToolRegistry();
|
|
13413
13466
|
const conflictGuard = new ConflictGuard();
|