@zqagent/core 0.3.12 → 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.
@@ -353,6 +353,17 @@ declare class OpenAIProvider implements ProviderClient {
353
353
  */
354
354
  private _apiMode;
355
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
+ */
356
367
  apiKey?: string;
357
368
  baseURL?: string;
358
369
  /** LLM 请求日志根目录,按日期分目录,不传则不记录 */
@@ -353,6 +353,17 @@ declare class OpenAIProvider implements ProviderClient {
353
353
  */
354
354
  private _apiMode;
355
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
+ */
356
367
  apiKey?: string;
357
368
  baseURL?: string;
358
369
  /** LLM 请求日志根目录,按日期分目录,不传则不记录 */
package/dist/index.cjs CHANGED
@@ -4631,9 +4631,30 @@ var ResponsesApiError = class extends Error {
4631
4631
  };
4632
4632
  var NO_AUTH_KEY = "not-needed";
4633
4633
  var degradedModes = /* @__PURE__ */ new Map();
4634
+ var DEGRADED_TTL_MS = 30 * 6e4;
4635
+ var DEGRADED_MAX = 500;
4634
4636
  function modeKey(baseURL, model) {
4635
4637
  return `${baseURL}::${model}`;
4636
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
+ }
4637
4658
  var OpenAIProvider = class {
4638
4659
  /** OpenAI SDK 客户端 */
4639
4660
  client;
@@ -4688,11 +4709,11 @@ var OpenAIProvider = class {
4688
4709
  */
4689
4710
  _resolveMode(model) {
4690
4711
  if (this._apiMode !== "auto") return this._apiMode;
4691
- return degradedModes.get(modeKey(this._baseURL, model)) ?? "responses";
4712
+ return isDegraded(this._baseURL, model) ? "chat" : "responses";
4692
4713
  }
4693
4714
  /** 记录「该端点+模型不支持 Responses」,后续同进程内的请求直走 Chat */
4694
4715
  _markChatMode(model) {
4695
- degradedModes.set(modeKey(this._baseURL, model), "chat");
4716
+ markDegraded(this._baseURL, model);
4696
4717
  }
4697
4718
  /**
4698
4719
  * Responses 失败的分类(决定「能不能改走 Chat Completions」以及要不要缓存降级)。