@zqagent/core 0.3.11 → 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.
Files changed (33) hide show
  1. package/dist/{TurnEngine-BPKhWuSI.d.cts → TurnEngine-BSciNywD.d.cts} +23 -4
  2. package/dist/{TurnEngine-DtGEuVLT.d.ts → TurnEngine-BU4R7q_0.d.ts} +23 -4
  3. package/dist/index.cjs +48 -16
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +7 -2
  6. package/dist/index.d.ts +7 -2
  7. package/dist/index.js +48 -16
  8. package/dist/index.js.map +1 -1
  9. package/dist/internal/engine/FileLogHook.d.cts +2 -1
  10. package/dist/internal/engine/FileLogHook.d.ts +2 -1
  11. package/dist/internal/llmConfig.cjs +15 -0
  12. package/dist/internal/llmConfig.cjs.map +1 -1
  13. package/dist/internal/llmConfig.d.cts +15 -0
  14. package/dist/internal/llmConfig.d.ts +15 -0
  15. package/dist/internal/llmConfig.js +15 -0
  16. package/dist/internal/llmConfig.js.map +1 -1
  17. package/dist/internal/providers/diagnostics.cjs +22 -2
  18. package/dist/internal/providers/diagnostics.cjs.map +1 -1
  19. package/dist/internal/providers/diagnostics.d.cts +25 -3
  20. package/dist/internal/providers/diagnostics.d.ts +25 -3
  21. package/dist/internal/providers/diagnostics.js +19 -2
  22. package/dist/internal/providers/diagnostics.js.map +1 -1
  23. package/dist/internal/providers/models.cjs.map +1 -1
  24. package/dist/internal/providers/models.js.map +1 -1
  25. package/dist/internal/update/controller.cjs +1 -1
  26. package/dist/internal/update/controller.js +1 -1
  27. package/dist/internal/update/platform.cjs +1 -1
  28. package/dist/internal/update/platform.js +1 -1
  29. package/dist/tools/explore.cjs.map +1 -1
  30. package/dist/tools/explore.d.cts +2 -1
  31. package/dist/tools/explore.d.ts +2 -1
  32. package/dist/tools/explore.js.map +1 -1
  33. package/package.json +4 -3
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as Mode, S as ShellPolicy, E as EngineHook, C as CompactionStartInfo, a as CompactionDoneInfo, b as EventType, c as EngineErrorInfo, P as ProviderClient, T as TurnEngine } from './TurnEngine-BPKhWuSI.cjs';
2
- export { A as ApprovalOutcome, d as Approver, e as CompactionTrigger, D as Decision, O as OpenAIProvider, f as PermissionEngine, g as PermissionRequest, h as ShellSandboxStatus, i as TurnEngineOpts, W as WsEvent } from './TurnEngine-BPKhWuSI.cjs';
1
+ import { M as Mode, S as ShellPolicy, E as EngineHook, C as CompactionStartInfo, a as CompactionDoneInfo, b as EventType, c as EngineErrorInfo, P as ProviderClient, T as TurnEngine } from './TurnEngine-BSciNywD.cjs';
2
+ export { A as ApprovalOutcome, d as Approver, e as CompactionTrigger, D as Decision, O as OpenAIProvider, f as PermissionEngine, g as PermissionRequest, h as ShellSandboxStatus, i as TurnEngineOpts, W as WsEvent } from './TurnEngine-BSciNywD.cjs';
3
3
  import { T as TokenUsage, M as Message, R as ReasoningEffort } from './types-BYyXWWPW.cjs';
4
4
  export { A as ATTACHMENT_DIR, d as AssistantTurn, e as AttachmentError, f as MAX_ATTACHMENTS, g as MAX_ATTACHMENT_BYTES, b as MessageAttachment, c as StoredAttachment, S as StreamChunk, h as ToolCall, a as ToolSchema, U as UPLOAD_DIR, W as WorkspaceFileRef, i as attachmentBytes, j as buildWorkspaceFileNotice, k as hasNonImageAttachments, n as normalizeAttachments, r as readStoredAttachment, s as saveAttachments, l as saveAttachmentsToWorkspace, m as splitByCapability, o as stripAttachments } from './types-BYyXWWPW.cjs';
5
5
  import { T as ToolRegistry } from './ToolRegistry-DouDvn9E.cjs';
@@ -24,6 +24,7 @@ export { registerMediaTool } from './tools/media.cjs';
24
24
  export { QuestionHandler, parsePicks, registerAskTool, setQuestionHandler } from './tools/ask.cjs';
25
25
  export { PlanHandler, PlanReply, interpretPlanReply, isAffirmativeText, isRejectionText, registerPlanTool, setPlanHandler } from './internal/tools/plan.cjs';
26
26
  export { DirectoryHandler, registerDirectoryTool, setDirectoryHandler } from './tools/directories.cjs';
27
+ import { ApiMode } from './internal/providers/diagnostics.cjs';
27
28
  import 'openai/resources/chat/completions.js';
28
29
  import 'openai/core.mjs';
29
30
  import '@zqagent/shared/model-capabilities';
@@ -1098,6 +1099,10 @@ interface CreateEngineOpts {
1098
1099
  * DeepSeek 自动跳过。
1099
1100
  */
1100
1101
  reasoningEffort?: ReasoningEffort;
1102
+ /** 单次请求超时(毫秒)。缺省取 OPENAI_TIMEOUT_MS,再缺省 10 分钟 */
1103
+ timeoutMs?: number | null;
1104
+ /** API 模式。缺省取 OPENAI_FORCE_API_MODE,再缺省 auto(Responses 优先) */
1105
+ apiMode?: ApiMode | null;
1101
1106
  /** 命令白名单(Auto 模式下自动放行的命令前缀,默认空数组) */
1102
1107
  allowedCommands?: string[];
1103
1108
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as Mode, S as ShellPolicy, E as EngineHook, C as CompactionStartInfo, a as CompactionDoneInfo, b as EventType, c as EngineErrorInfo, P as ProviderClient, T as TurnEngine } from './TurnEngine-DtGEuVLT.js';
2
- export { A as ApprovalOutcome, d as Approver, e as CompactionTrigger, D as Decision, O as OpenAIProvider, f as PermissionEngine, g as PermissionRequest, h as ShellSandboxStatus, i as TurnEngineOpts, W as WsEvent } from './TurnEngine-DtGEuVLT.js';
1
+ import { M as Mode, S as ShellPolicy, E as EngineHook, C as CompactionStartInfo, a as CompactionDoneInfo, b as EventType, c as EngineErrorInfo, P as ProviderClient, T as TurnEngine } from './TurnEngine-BU4R7q_0.js';
2
+ export { A as ApprovalOutcome, d as Approver, e as CompactionTrigger, D as Decision, O as OpenAIProvider, f as PermissionEngine, g as PermissionRequest, h as ShellSandboxStatus, i as TurnEngineOpts, W as WsEvent } from './TurnEngine-BU4R7q_0.js';
3
3
  import { T as TokenUsage, M as Message, R as ReasoningEffort } from './types-BYyXWWPW.js';
4
4
  export { A as ATTACHMENT_DIR, d as AssistantTurn, e as AttachmentError, f as MAX_ATTACHMENTS, g as MAX_ATTACHMENT_BYTES, b as MessageAttachment, c as StoredAttachment, S as StreamChunk, h as ToolCall, a as ToolSchema, U as UPLOAD_DIR, W as WorkspaceFileRef, i as attachmentBytes, j as buildWorkspaceFileNotice, k as hasNonImageAttachments, n as normalizeAttachments, r as readStoredAttachment, s as saveAttachments, l as saveAttachmentsToWorkspace, m as splitByCapability, o as stripAttachments } from './types-BYyXWWPW.js';
5
5
  import { T as ToolRegistry } from './ToolRegistry-Cy0fQxrb.js';
@@ -24,6 +24,7 @@ export { registerMediaTool } from './tools/media.js';
24
24
  export { QuestionHandler, parsePicks, registerAskTool, setQuestionHandler } from './tools/ask.js';
25
25
  export { PlanHandler, PlanReply, interpretPlanReply, isAffirmativeText, isRejectionText, registerPlanTool, setPlanHandler } from './internal/tools/plan.js';
26
26
  export { DirectoryHandler, registerDirectoryTool, setDirectoryHandler } from './tools/directories.js';
27
+ import { ApiMode } from './internal/providers/diagnostics.js';
27
28
  import 'openai/resources/chat/completions.js';
28
29
  import 'openai/core.mjs';
29
30
  import '@zqagent/shared/model-capabilities';
@@ -1098,6 +1099,10 @@ interface CreateEngineOpts {
1098
1099
  * DeepSeek 自动跳过。
1099
1100
  */
1100
1101
  reasoningEffort?: ReasoningEffort;
1102
+ /** 单次请求超时(毫秒)。缺省取 OPENAI_TIMEOUT_MS,再缺省 10 分钟 */
1103
+ timeoutMs?: number | null;
1104
+ /** API 模式。缺省取 OPENAI_FORCE_API_MODE,再缺省 auto(Responses 优先) */
1105
+ apiMode?: ApiMode | null;
1101
1106
  /** 命令白名单(Auto 模式下自动放行的命令前缀,默认空数组) */
1102
1107
  allowedCommands?: string[];
1103
1108
  /**
package/dist/index.js CHANGED
@@ -255,9 +255,23 @@ function paramErrorHints(message, code = "") {
255
255
  }
256
256
  return hints;
257
257
  }
258
- function llmTimeoutMs() {
258
+ var DEFAULT_LLM_TIMEOUT_MS = 6e5;
259
+ function normLlmTimeoutMs(v) {
260
+ if (v === null || v === void 0 || v === "") return null;
261
+ const n = Number(v);
262
+ if (!Number.isFinite(n) || n <= 0) return null;
263
+ return Math.min(Math.round(n), 30 * 6e4);
264
+ }
265
+ function llmTimeoutMs(explicit) {
266
+ const fromArg = normLlmTimeoutMs(explicit);
267
+ if (fromArg) return fromArg;
259
268
  const n = Number(process.env.OPENAI_TIMEOUT_MS);
260
- return Number.isFinite(n) && n > 0 ? n : 6e5;
269
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_LLM_TIMEOUT_MS;
270
+ }
271
+ function normApiMode(v) {
272
+ const s = typeof v === "string" ? v.trim().toLowerCase() : "";
273
+ if (s === "auto" || s === "responses" || s === "chat") return s;
274
+ return null;
261
275
  }
262
276
  function llmStreamIdleMs() {
263
277
  const n = Number(process.env.OPENAI_STREAM_IDLE_MS);
@@ -4486,6 +4500,11 @@ var ResponsesApiError = class extends Error {
4486
4500
  type;
4487
4501
  requestId;
4488
4502
  };
4503
+ var NO_AUTH_KEY = "not-needed";
4504
+ var degradedModes = /* @__PURE__ */ new Map();
4505
+ function modeKey(baseURL, model) {
4506
+ return `${baseURL}::${model}`;
4507
+ }
4489
4508
  var OpenAIProvider = class {
4490
4509
  /** OpenAI SDK 客户端 */
4491
4510
  client;
@@ -4493,23 +4512,31 @@ var OpenAIProvider = class {
4493
4512
  _logDir;
4494
4513
  /** 服务端点 baseURL(用于识别 DeepSeek 等特定供应商) */
4495
4514
  _baseURL;
4496
- /** 模型 → API 模式缓存:某模型不支持 Responses 后,后续直走 Chat */
4497
- _modeByModel = /* @__PURE__ */ new Map();
4515
+ /**
4516
+ * 本实例的 API 模式。
4517
+ *
4518
+ * 显式配置 > 全局 `OPENAI_FORCE_API_MODE` > auto(先 Responses 再降级)。
4519
+ * 早先只有全局环境变量一种表达方式,一个节点挂两家供应商时无法各自指定。
4520
+ */
4521
+ _apiMode;
4498
4522
  constructor(opts) {
4523
+ const explicitKey = opts.apiKey !== void 0;
4499
4524
  const apiKey = cleanLlmValue(opts.apiKey ?? process.env.OPENAI_API_KEY);
4500
4525
  const baseURL = normalizeBaseURL(opts.baseURL ?? process.env.OPENAI_BASE_URL);
4501
- if (!apiKey) {
4526
+ if (!apiKey && !explicitKey) {
4502
4527
  throw new Error(sanitizeEmoji("\u274C \u672A\u8BBE\u7F6E OPENAI_API_KEY \u73AF\u5883\u53D8\u91CF"));
4503
4528
  }
4529
+ const effectiveKey = apiKey ?? NO_AUTH_KEY;
4504
4530
  this._baseURL = baseURL ?? "";
4531
+ this._apiMode = normApiMode(opts.apiMode) ?? normApiMode(process.env.OPENAI_FORCE_API_MODE) ?? "auto";
4505
4532
  const agent = socksAgent();
4506
4533
  const proxyHint = unsupportedProxyHint();
4507
4534
  if (proxyHint) console.warn(`[llm] ${proxyHint}`);
4508
4535
  const baseFetch = agent ? makeSocksFetch(agent) : ((input, init) => globalThis.fetch(input, init));
4509
4536
  this.client = new OpenAI({
4510
- apiKey,
4537
+ apiKey: effectiveKey,
4511
4538
  ...baseURL ? { baseURL } : {},
4512
- timeout: llmTimeoutMs(),
4539
+ timeout: llmTimeoutMs(opts.timeoutMs),
4513
4540
  maxRetries: llmMaxRetries(),
4514
4541
  // 类型:SDK 期望 (RequestInfo, RequestInit) => Promise<Response>,
4515
4542
  // node-fetch 的 Response 与 DOM Response 结构不同,此处显式放宽
@@ -4526,14 +4553,17 @@ var OpenAIProvider = class {
4526
4553
  /**
4527
4554
  * 解析指定模型的 API 模式。
4528
4555
  *
4529
- * 优先级:环境变量 OPENAI_FORCE_API_MODE(responses|chat)强制指定
4530
- * > 运行时降级缓存(该模型曾因"不支持"失败而缓存为 chat)
4556
+ * 优先级:本实例的显式配置(responses|chat)
4557
+ * > 运行时降级缓存(该端点+模型曾因"不支持"失败而缓存为 chat)
4531
4558
  * > 默认 responses(Responses 优先)。
4532
4559
  */
4533
4560
  _resolveMode(model) {
4534
- const forced = process.env.OPENAI_FORCE_API_MODE?.toLowerCase();
4535
- if (forced === "responses" || forced === "chat") return forced;
4536
- return this._modeByModel.get(model) ?? "responses";
4561
+ if (this._apiMode !== "auto") return this._apiMode;
4562
+ return degradedModes.get(modeKey(this._baseURL, model)) ?? "responses";
4563
+ }
4564
+ /** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
4565
+ _markChatMode(model) {
4566
+ degradedModes.set(modeKey(this._baseURL, model), "chat");
4537
4567
  }
4538
4568
  /**
4539
4569
  * Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。
@@ -4609,7 +4639,7 @@ var OpenAIProvider = class {
4609
4639
  } catch (err) {
4610
4640
  const kind = this._responsesFailureKind(err, true);
4611
4641
  if (kind) {
4612
- if (kind === "endpoint") this._modeByModel.set(model, "chat");
4642
+ if (kind === "endpoint") this._markChatMode(model);
4613
4643
  console.warn(
4614
4644
  `[llm] ${model} Responses API \u4E0D\u53EF\u7528(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
4615
4645
  err?.message ?? err
@@ -4683,7 +4713,7 @@ var OpenAIProvider = class {
4683
4713
  } catch (err) {
4684
4714
  const kind = this._responsesFailureKind(err, true);
4685
4715
  if (kind) {
4686
- if (kind === "endpoint") this._modeByModel.set(model, "chat");
4716
+ if (kind === "endpoint") this._markChatMode(model);
4687
4717
  console.warn(
4688
4718
  `[llm] ${model} Responses API \u4E0D\u53EF\u7528(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
4689
4719
  err?.message ?? err
@@ -4729,7 +4759,7 @@ var OpenAIProvider = class {
4729
4759
  } catch (err) {
4730
4760
  const kind = emitted ? null : this._responsesFailureKind(err, false);
4731
4761
  if (!kind) throw enrichLlmError(err, this._baseURL);
4732
- if (kind === "endpoint") this._modeByModel.set(ctx.model, "chat");
4762
+ if (kind === "endpoint") this._markChatMode(ctx.model);
4733
4763
  console.warn(
4734
4764
  `[llm] ${ctx.model} Responses \u6D41\u5185\u5931\u8D25(${kind})\uFF0C\u6539\u7528 Chat Completions (${String(
4735
4765
  err?.message ?? err
@@ -13262,6 +13292,8 @@ function createDefaultEngine(opts) {
13262
13292
  mode = "interactive" /* INTERACTIVE */,
13263
13293
  maxIterations = DEFAULT_MAX_ITERATIONS,
13264
13294
  reasoningEffort,
13295
+ timeoutMs,
13296
+ apiMode,
13265
13297
  allowedCommands = [],
13266
13298
  shellPolicy = "approve",
13267
13299
  sandbox,
@@ -13282,7 +13314,7 @@ function createDefaultEngine(opts) {
13282
13314
  } = opts;
13283
13315
  const envEffort = process.env.OPENAI_REASONING_EFFORT?.toLowerCase();
13284
13316
  const effectiveEffort = reasoningEffort ?? (envEffort === "low" || envEffort === "medium" || envEffort === "high" ? envEffort : void 0);
13285
- const effectiveProvider = provider ?? new OpenAIProvider({ logDir });
13317
+ const effectiveProvider = provider ?? new OpenAIProvider({ logDir, timeoutMs, apiMode });
13286
13318
  const sandboxPlan = resolveSandbox({ ...sandbox, workspace });
13287
13319
  const registry = new ToolRegistry();
13288
13320
  const conflictGuard = new ConflictGuard();