@eddyskywalker/dsh-chatgpt-subscription 0.19.1 → 0.20.0

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 (34) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/lib/client.js +274 -4
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +525 -155
  5. package/lib/types/client/minimax-code/MinimaxCodeSection.d.ts.map +1 -1
  6. package/lib/types/client/minimax-code/api.d.ts +30 -0
  7. package/lib/types/client/minimax-code/api.d.ts.map +1 -1
  8. package/lib/types/client/minimax-code/locales.d.ts +62 -2
  9. package/lib/types/client/minimax-code/locales.d.ts.map +1 -1
  10. package/lib/types/client/minimax-code/styles.d.ts.map +1 -1
  11. package/lib/types/client/minimax-code/useMinimaxCodeSection.d.ts +50 -1
  12. package/lib/types/client/minimax-code/useMinimaxCodeSection.d.ts.map +1 -1
  13. package/lib/types/host/antigravity/adapter.d.ts.map +1 -1
  14. package/lib/types/host/claude/adapter.d.ts.map +1 -1
  15. package/lib/types/host/command-code/adapter.d.ts.map +1 -1
  16. package/lib/types/host/common/idle-watchdog.d.ts +13 -1
  17. package/lib/types/host/common/idle-watchdog.d.ts.map +1 -1
  18. package/lib/types/host/glm-coding-plan/adapter.d.ts.map +1 -1
  19. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  20. package/lib/types/host/minimax-code/adapter.d.ts.map +1 -1
  21. package/lib/types/host/minimax-code/reset-card.d.ts +136 -0
  22. package/lib/types/host/minimax-code/reset-card.d.ts.map +1 -0
  23. package/lib/types/host/minimax-code/routes.d.ts.map +1 -1
  24. package/lib/types/host/ollama/adapter.d.ts.map +1 -1
  25. package/lib/types/host/ollama/client.d.ts +8 -1
  26. package/lib/types/host/ollama/client.d.ts.map +1 -1
  27. package/lib/types/host/responses-client.d.ts +11 -1
  28. package/lib/types/host/responses-client.d.ts.map +1 -1
  29. package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
  30. package/lib/types/index.d.ts +8 -0
  31. package/lib/types/index.d.ts.map +1 -1
  32. package/lib/types/shared/minimax-code-contracts.d.ts +35 -0
  33. package/lib/types/shared/minimax-code-contracts.d.ts.map +1 -1
  34. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -13,11 +13,11 @@ import http, { createServer } from "node:http";
13
13
  import { WebError } from "@deepseek-ai/dsh-web";
14
14
  import { lookup } from "node:dns/promises";
15
15
  import { isIP } from "node:net";
16
+ import { MAX_TIMER_DELAY_MS, idleWatchdog, timeoutOf } from "@deepseek-ai/dsh-timeout";
16
17
  import { boundContextSummary, createUserMessage } from "@deepseek-ai/dsh-llm/message";
17
18
  import { defineTool } from "@deepseek-ai/dsh-tools";
18
19
  import { ProxyAgent, fetch as fetch$1 } from "undici";
19
20
  import * as SettingsModule from "@deepseek-ai/dsh-settings";
20
- import { idleWatchdog, timeoutOf } from "@deepseek-ai/dsh-timeout";
21
21
  import { URL as URL$1, URLSearchParams as URLSearchParams$1, fileURLToPath } from "node:url";
22
22
  //#region src/host/common/output-reservation.ts
23
23
  /**
@@ -786,7 +786,7 @@ async function rehydrateSnapshot(key) {
786
786
  * so a backend that flattens the envelope does not read as an empty catalog.
787
787
  */
788
788
  function parseListing(payload) {
789
- const record = asRecord$13(payload);
789
+ const record = asRecord$14(payload);
790
790
  const models = Array.isArray(payload) ? payload : record?.models;
791
791
  if (!Array.isArray(models)) return [];
792
792
  return models.flatMap((item) => parseListingEntry$1(item));
@@ -800,7 +800,7 @@ function parseListing(payload) {
800
800
  * back to a conservative answer rather than to a guess.
801
801
  */
802
802
  function parseListingEntry$1(value) {
803
- const record = asRecord$13(value);
803
+ const record = asRecord$14(value);
804
804
  if (record === void 0) return [];
805
805
  const id = asString$23(record.slug) ?? asString$23(record.id);
806
806
  if (id === void 0) return [];
@@ -836,7 +836,7 @@ function parseEfforts(value) {
836
836
  if (!Array.isArray(value)) return null;
837
837
  const out = [];
838
838
  for (const item of value) {
839
- const effort = asString$23(item) ?? asString$23(asRecord$13(item)?.effort);
839
+ const effort = asString$23(item) ?? asString$23(asRecord$14(item)?.effort);
840
840
  if (effort !== void 0 && !out.includes(effort)) out.push(effort);
841
841
  }
842
842
  return out.length > 0 ? out : null;
@@ -851,7 +851,7 @@ function parseEfforts(value) {
851
851
  function accountKeyFor$1(credentials) {
852
852
  return credentials.accountId || "default";
853
853
  }
854
- function asRecord$13(value) {
854
+ function asRecord$14(value) {
855
855
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
856
856
  }
857
857
  function asString$23(value) {
@@ -3915,6 +3915,53 @@ function createCodexFetchProvider(options = {}) {
3915
3915
  };
3916
3916
  }
3917
3917
  //#endregion
3918
+ //#region src/host/common/idle-watchdog.ts
3919
+ const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
3920
+ const STREAM_IDLE_TIMEOUT_CODE$7 = "LLM_STREAM_IDLE_TIMEOUT";
3921
+ /**
3922
+ * The same budget under the name every provider adapter passes it by.
3923
+ *
3924
+ * Six provider `types.ts` files each declared their own
3925
+ * `STREAM_IDLE_TIMEOUT_MS = 300_000`, so one line ended up importing a sibling
3926
+ * line's copy just to name the same number. This alias is the single home: the
3927
+ * value is unchanged, and an adapter that took the constant from another line
3928
+ * can now take it from here without renaming its local usage.
3929
+ */
3930
+ const STREAM_IDLE_TIMEOUT_MS$7 = DEFAULT_STREAM_IDLE_TIMEOUT_MS;
3931
+ /**
3932
+ * 为异步流包裹可复位的空闲超时看门狗。
3933
+ * 当流式 chunk 产出之间的间隔超过指定阈值时,主动终止并抛出带有 TIMEOUT 的 LlmError。
3934
+ */
3935
+ async function* wrapStreamWithWatchdog(source, upstreamSignal, timeoutMs = DEFAULT_STREAM_IDLE_TIMEOUT_MS, timeoutCode = STREAM_IDLE_TIMEOUT_CODE$7, providerTag = "llm") {
3936
+ const consumer = new AbortController();
3937
+ const watchdog = idleWatchdog(upstreamSignal === void 0 ? consumer.signal : AbortSignal.any([upstreamSignal, consumer.signal]), timeoutMs, timeoutCode);
3938
+ const iterator = source(watchdog.signal, { pulse: () => {
3939
+ watchdog.pulse();
3940
+ } })[Symbol.asyncIterator]();
3941
+ let exhausted = false;
3942
+ try {
3943
+ while (true) {
3944
+ const result = await watchdog.next(iterator);
3945
+ if (timeoutOf(watchdog.signal, timeoutCode) !== void 0) throw new LlmError(`${providerTag} stream idle timeout after ${timeoutMs}ms`, "TIMEOUT");
3946
+ if (result.done) {
3947
+ exhausted = true;
3948
+ return;
3949
+ }
3950
+ yield result.value;
3951
+ }
3952
+ } catch (error) {
3953
+ if (timeoutOf(watchdog.signal, timeoutCode) !== void 0) throw new LlmError(`${providerTag} stream idle timeout after ${timeoutMs}ms`, "TIMEOUT", { cause: error });
3954
+ if (upstreamSignal?.aborted) throw new LlmError(`${providerTag} request aborted by caller`, "ABORTED", { cause: error });
3955
+ throw error;
3956
+ } finally {
3957
+ consumer.abort(`${providerTag} stream consumer stopped`);
3958
+ if (!exhausted) try {
3959
+ await iterator.return?.(void 0);
3960
+ } catch {}
3961
+ watchdog[Symbol.dispose]();
3962
+ }
3963
+ }
3964
+ //#endregion
3918
3965
  //#region src/host/common/llm-compat.ts
3919
3966
  /** This package's kind in the harness message-source map. */
3920
3967
  const PLUGIN_MESSAGE_SOURCE_KIND = "dsh-chatgpt-subscription";
@@ -5725,51 +5772,6 @@ const toToolCallId = (id) => {
5725
5772
  return (mod.ToolCallId ?? mod.CallId ?? ((x) => x))(id);
5726
5773
  };
5727
5774
  //#endregion
5728
- //#region src/host/common/idle-watchdog.ts
5729
- const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
5730
- const STREAM_IDLE_TIMEOUT_CODE$7 = "LLM_STREAM_IDLE_TIMEOUT";
5731
- /**
5732
- * The same budget under the name every provider adapter passes it by.
5733
- *
5734
- * Six provider `types.ts` files each declared their own
5735
- * `STREAM_IDLE_TIMEOUT_MS = 300_000`, so one line ended up importing a sibling
5736
- * line's copy just to name the same number. This alias is the single home: the
5737
- * value is unchanged, and an adapter that took the constant from another line
5738
- * can now take it from here without renaming its local usage.
5739
- */
5740
- const STREAM_IDLE_TIMEOUT_MS$7 = DEFAULT_STREAM_IDLE_TIMEOUT_MS;
5741
- /**
5742
- * 为异步流包裹可复位的空闲超时看门狗。
5743
- * 当流式 chunk 产出之间的间隔超过指定阈值时,主动终止并抛出带有 TIMEOUT 的 LlmError。
5744
- */
5745
- async function* wrapStreamWithWatchdog(source, upstreamSignal, timeoutMs = DEFAULT_STREAM_IDLE_TIMEOUT_MS, timeoutCode = STREAM_IDLE_TIMEOUT_CODE$7, providerTag = "llm") {
5746
- const consumer = new AbortController();
5747
- const watchdog = idleWatchdog(upstreamSignal === void 0 ? consumer.signal : AbortSignal.any([upstreamSignal, consumer.signal]), timeoutMs, timeoutCode);
5748
- const iterator = source(watchdog.signal)[Symbol.asyncIterator]();
5749
- let exhausted = false;
5750
- try {
5751
- while (true) {
5752
- const result = await watchdog.next(iterator);
5753
- if (timeoutOf(watchdog.signal, timeoutCode) !== void 0) throw new LlmError(`${providerTag} stream idle timeout after ${timeoutMs}ms`, "TIMEOUT");
5754
- if (result.done) {
5755
- exhausted = true;
5756
- return;
5757
- }
5758
- yield result.value;
5759
- }
5760
- } catch (error) {
5761
- if (timeoutOf(watchdog.signal, timeoutCode) !== void 0) throw new LlmError(`${providerTag} stream idle timeout after ${timeoutMs}ms`, "TIMEOUT", { cause: error });
5762
- if (upstreamSignal?.aborted) throw new LlmError(`${providerTag} request aborted by caller`, "ABORTED", { cause: error });
5763
- throw error;
5764
- } finally {
5765
- consumer.abort(`${providerTag} stream consumer stopped`);
5766
- if (!exhausted) try {
5767
- await iterator.return?.(void 0);
5768
- } catch {}
5769
- watchdog[Symbol.dispose]();
5770
- }
5771
- }
5772
- //#endregion
5773
5775
  //#region src/host/responses-mapper.ts
5774
5776
  /**
5775
5777
  * Base64 image payload one Codex request may carry.
@@ -6314,6 +6316,7 @@ var ResponsesClient = class {
6314
6316
  fastMode;
6315
6317
  reasoningSummary;
6316
6318
  accountPool;
6319
+ codexStreamIdleTimeoutMs;
6317
6320
  /**
6318
6321
  * Opaque backend routing state, keyed by a unique model-request nonce.
6319
6322
  * The host does not expose a reliable human-turn identity, so this is the
@@ -6341,6 +6344,7 @@ var ResponsesClient = class {
6341
6344
  this.fastMode = options.fastMode ?? (() => false);
6342
6345
  this.reasoningSummary = options.reasoningSummary ?? (() => null);
6343
6346
  this.accountPool = options.accountPool ?? null;
6347
+ this.codexStreamIdleTimeoutMs = options.codexStreamIdleTimeoutMs ?? 3e5;
6344
6348
  }
6345
6349
  localRawImages;
6346
6350
  async *stream(rawOptions) {
@@ -6375,7 +6379,7 @@ var ResponsesClient = class {
6375
6379
  }
6376
6380
  }
6377
6381
  try {
6378
- yield* wrapStreamWithWatchdog((watchdogSignal) => parseResponsesStream(response, watchdogSignal, hiddenSandboxControls), options.signal, 3e5, "LLM_STREAM_IDLE_TIMEOUT", "Codex");
6382
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => parseResponsesStream(response, watchdogSignal, hiddenSandboxControls, activity), options.signal, this.codexStreamIdleTimeoutMs, "LLM_STREAM_IDLE_TIMEOUT", "Codex");
6379
6383
  } catch (error) {
6380
6384
  throw streamFailure(error, options.signal);
6381
6385
  } finally {
@@ -6582,7 +6586,7 @@ function perRequestNonce() {
6582
6586
  requestCounter += 1;
6583
6587
  return requestCounter;
6584
6588
  }
6585
- async function* parseResponsesStream(response, signal, hiddenSandboxControls = /* @__PURE__ */ new Set()) {
6589
+ async function* parseResponsesStream(response, signal, hiddenSandboxControls = /* @__PURE__ */ new Set(), activity) {
6586
6590
  if (response.body === null) throw new LlmError("Codex returned no response stream.", "PROVIDER_ERROR");
6587
6591
  const reader = response.body.getReader();
6588
6592
  const abortReader = () => {
@@ -6782,10 +6786,12 @@ async function* parseResponsesStream(response, signal, hiddenSandboxControls = /
6782
6786
  if (signal?.aborted) throw signal.reason ?? new DOMException("Aborted", "AbortError");
6783
6787
  const { done, value } = await reader.read();
6784
6788
  if (done) break;
6789
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
6785
6790
  buffer += decoder.decode(value, { stream: true });
6786
6791
  const frames = buffer.split(/\r?\n\r?\n/);
6787
6792
  buffer = frames.pop() ?? "";
6788
6793
  for (const frame of frames) {
6794
+ activity?.pulse();
6789
6795
  const data = frame.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
6790
6796
  if (data === "" || data === "[DONE]") continue;
6791
6797
  let event;
@@ -7487,8 +7493,8 @@ function parseCodexUsage(value) {
7487
7493
  for (const [index, value] of additional.entries()) {
7488
7494
  const limit = record$1(value);
7489
7495
  if (limit === null) continue;
7490
- const idSource = text$1(limit.limit_name) ?? text$1(limit.metered_feature) ?? `additional-${index + 1}`;
7491
- addBucket(buckets, usedIds, uniqueId(slug(idSource), usedIds), readableLimitName(text$1(limit.limit_name) ?? text$1(limit.metered_feature) ?? idSource), planType, limit.rate_limit);
7496
+ const idSource = text$2(limit.limit_name) ?? text$2(limit.metered_feature) ?? `additional-${index + 1}`;
7497
+ addBucket(buckets, usedIds, uniqueId(slug(idSource), usedIds), readableLimitName(text$2(limit.limit_name) ?? text$2(limit.metered_feature) ?? idSource), planType, limit.rate_limit);
7492
7498
  }
7493
7499
  return {
7494
7500
  buckets,
@@ -7573,7 +7579,7 @@ function parseResetCredits(value) {
7573
7579
  availableCreditIds: []
7574
7580
  };
7575
7581
  const available = (Array.isArray(data.credits) ? data.credits : []).map(record$1).filter((credit) => credit !== null && credit.status === "available").map((credit) => ({
7576
- id: text$1(credit.id),
7582
+ id: text$2(credit.id),
7577
7583
  expiresAt: timestamp(credit.expires_at)
7578
7584
  })).filter((credit) => credit.id !== null).sort((left, right) => (left.expiresAt ?? Number.MAX_SAFE_INTEGER) - (right.expiresAt ?? Number.MAX_SAFE_INTEGER));
7579
7585
  const reported = numeric(data.available_count);
@@ -7607,7 +7613,7 @@ function decimalText(value) {
7607
7613
  const trimmed = value.trim();
7608
7614
  return trimmed !== "" ? trimmed : null;
7609
7615
  }
7610
- function text$1(value) {
7616
+ function text$2(value) {
7611
7617
  return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
7612
7618
  }
7613
7619
  function slug(value) {
@@ -11217,12 +11223,12 @@ var AntigravityAdapter = class extends LlmAdapter {
11217
11223
  ...options,
11218
11224
  reasoningEffort: effectiveEffort
11219
11225
  } : options;
11220
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream({
11226
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream({
11221
11227
  ...effectiveOptions,
11222
11228
  maxTokens: options.maxTokens ?? model.maxTokens
11223
- }, model, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS$6, STREAM_IDLE_TIMEOUT_CODE$6, "Antigravity");
11229
+ }, model, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS$6, STREAM_IDLE_TIMEOUT_CODE$6, "Antigravity");
11224
11230
  }
11225
- async *requestStream(options, model, signal) {
11231
+ async *requestStream(options, model, signal, activity) {
11226
11232
  const fetchFn = this.options.fetchFn ?? fetch;
11227
11233
  const effort = String(options.reasoningEffort || "medium").toLowerCase();
11228
11234
  const routing = ROUTING[model.id];
@@ -11346,12 +11352,14 @@ var AntigravityAdapter = class extends LlmAdapter {
11346
11352
  while (true) {
11347
11353
  const { done, value } = await reader.read();
11348
11354
  if (done) break;
11355
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
11349
11356
  buffer += decoder.decode(value, { stream: true });
11350
11357
  const lines = buffer.split("\n");
11351
11358
  buffer = lines.pop() || "";
11352
11359
  for (const line of lines) {
11353
11360
  const trimmed = line.trim();
11354
11361
  if (!trimmed) continue;
11362
+ activity?.pulse();
11355
11363
  const chunks = processStreamLine$3(trimmed, state);
11356
11364
  for (const chunk of chunks) {
11357
11365
  recordUsageChunk(chunk, statsSessionId, statsAccountId);
@@ -13305,7 +13313,7 @@ function timeoutSignal$3(signal, ms) {
13305
13313
  function isRecord$31(value) {
13306
13314
  return typeof value === "object" && value !== null && !Array.isArray(value);
13307
13315
  }
13308
- function asRecord$12(value) {
13316
+ function asRecord$13(value) {
13309
13317
  return isRecord$31(value) ? value : void 0;
13310
13318
  }
13311
13319
  function asString$21(value) {
@@ -13384,16 +13392,16 @@ const ORG_KEYS = [
13384
13392
  ];
13385
13393
  /** Map `/alpha/whoami` (or a stored key's own facts) onto the public account DTO. */
13386
13394
  function parseWhoami(payload, fallback = {}) {
13387
- const root = asRecord$12(payload) ?? {};
13388
- const data = asRecord$12(root.data) ?? root;
13389
- const user = asRecord$12(deepValue(data, USER_KEYS)) ?? {};
13390
- const org = asRecord$12(deepValue(data, ORG_KEYS)) ?? {};
13391
- const key = asRecord$12(deepValue(data, [
13395
+ const root = asRecord$13(payload) ?? {};
13396
+ const data = asRecord$13(root.data) ?? root;
13397
+ const user = asRecord$13(deepValue(data, USER_KEYS)) ?? {};
13398
+ const org = asRecord$13(deepValue(data, ORG_KEYS)) ?? {};
13399
+ const key = asRecord$13(deepValue(data, [
13392
13400
  "apiKey",
13393
13401
  "key",
13394
13402
  "credential"
13395
13403
  ])) ?? {};
13396
- const subscription = asRecord$12(deepValue(data, [
13404
+ const subscription = asRecord$13(deepValue(data, [
13397
13405
  "subscription",
13398
13406
  "plan",
13399
13407
  "tier"
@@ -13497,14 +13505,14 @@ function humanizeWindowKey$1(key) {
13497
13505
  * — so they are read here first, by name.
13498
13506
  */
13499
13507
  function parseWindowLimits(payload, consumed = []) {
13500
- const root = asRecord$12(payload) ?? {};
13501
- const limits = asRecord$12(deepValue(asRecord$12(root.data) ?? root, ["windowLimits", "window_limits"]));
13508
+ const root = asRecord$13(payload) ?? {};
13509
+ const limits = asRecord$13(deepValue(asRecord$13(root.data) ?? root, ["windowLimits", "window_limits"]));
13502
13510
  if (limits === void 0) return [];
13503
13511
  const keys = [...WINDOW_ORDER$1.filter((key) => limits[key] !== void 0), ...Object.keys(limits).filter((key) => !WINDOW_ORDER$1.includes(key))];
13504
13512
  const meters = [];
13505
13513
  for (const key of keys) {
13506
13514
  if (key === "limited" || key === "exceeded") continue;
13507
- const record = asRecord$12(limits[key]);
13515
+ const record = asRecord$13(limits[key]);
13508
13516
  if (record === void 0) continue;
13509
13517
  const cap = firstNumber$2(record, [
13510
13518
  "cap",
@@ -13538,8 +13546,8 @@ function parseWindowLimits(payload, consumed = []) {
13538
13546
  * source for a remaining balance.
13539
13547
  */
13540
13548
  function parseCreditBalances(payload, consumed = []) {
13541
- const root = asRecord$12(payload) ?? {};
13542
- const credits = asRecord$12(deepValue(asRecord$12(root.data) ?? root, ["credits"]));
13549
+ const root = asRecord$13(payload) ?? {};
13550
+ const credits = asRecord$13(deepValue(asRecord$13(root.data) ?? root, ["credits"]));
13543
13551
  if (credits === void 0) return [];
13544
13552
  const monthly = firstNumber$2(credits, ["monthlyCredits", "monthly_credits"]);
13545
13553
  const purchased = firstNumber$2(credits, ["purchasedCredits", "purchased_credits"]);
@@ -13586,13 +13594,13 @@ function parsePlanId(payloads) {
13586
13594
  * subscription's remaining credits as usable would be worse than showing none.
13587
13595
  */
13588
13596
  function parseSubscriptionStatus(payload) {
13589
- const root = asRecord$12(payload) ?? {};
13590
- return asString$21(deepValue(asRecord$12(root.data) ?? root, ["status"])) ?? null;
13597
+ const root = asRecord$13(payload) ?? {};
13598
+ return asString$21(deepValue(asRecord$13(root.data) ?? root, ["status"])) ?? null;
13591
13599
  }
13592
13600
  /** End of the current billing period, in Unix milliseconds. */
13593
13601
  function parseSubscriptionPeriodEnd(payload) {
13594
- const root = asRecord$12(payload) ?? {};
13595
- return parseTimestamp$1(deepValue(asRecord$12(root.data) ?? root, ["currentPeriodEnd", "current_period_end"]));
13602
+ const root = asRecord$13(payload) ?? {};
13603
+ return parseTimestamp$1(deepValue(asRecord$13(root.data) ?? root, ["currentPeriodEnd", "current_period_end"]));
13596
13604
  }
13597
13605
  /**
13598
13606
  * Turn one billing/usage payload into meters.
@@ -13809,9 +13817,9 @@ function parseUsageWindows$1(payload) {
13809
13817
  return windows;
13810
13818
  }
13811
13819
  function extractCreditsBalance(payload) {
13812
- const root = asRecord$12(payload) ?? {};
13813
- const data = asRecord$12(root.data) ?? root;
13814
- const credits = asRecord$12(data.credits);
13820
+ const root = asRecord$13(payload) ?? {};
13821
+ const data = asRecord$13(root.data) ?? root;
13822
+ const credits = asRecord$13(data.credits);
13815
13823
  if (credits !== void 0) {
13816
13824
  const pools = [
13817
13825
  "monthlyCredits",
@@ -13855,11 +13863,11 @@ let catalogInFlight$3 = null;
13855
13863
  const catalogSnapshotScopesLoaded$2 = /* @__PURE__ */ new Set();
13856
13864
  /** Parse the public `/provider/v1/models` payload. */
13857
13865
  function parseProviderModels(payload) {
13858
- const root = asRecord$12(payload) ?? {};
13866
+ const root = asRecord$13(payload) ?? {};
13859
13867
  const list = Array.isArray(root.data) ? root.data : Array.isArray(payload) ? payload : [];
13860
13868
  const models = [];
13861
13869
  for (const entry of list) {
13862
- const record = asRecord$12(entry);
13870
+ const record = asRecord$13(entry);
13863
13871
  if (!record) continue;
13864
13872
  const id = firstString$1(record, [
13865
13873
  "id",
@@ -16053,9 +16061,9 @@ var CommandCodeAdapter = class extends LlmAdapter {
16053
16061
  ...effectiveOptions,
16054
16062
  reasoningEffort: void 0
16055
16063
  };
16056
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream(resolvedOptions, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS$5, STREAM_IDLE_TIMEOUT_CODE$5, PROVIDER_NAME$6);
16064
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream(resolvedOptions, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS$5, STREAM_IDLE_TIMEOUT_CODE$5, PROVIDER_NAME$6);
16057
16065
  }
16058
- async *requestStream(options, signal) {
16066
+ async *requestStream(options, signal, activity) {
16059
16067
  const fetchFn = this.options.fetchFn ?? fetch;
16060
16068
  const catalogEntry = (await this.catalog()).find((entry) => entry.id === options.model);
16061
16069
  const wire = (catalogEntry === void 0 ? void 0 : wireForCatalogEntry$1(catalogEntry)) ?? wireForModel$2(options.model);
@@ -16172,10 +16180,12 @@ var CommandCodeAdapter = class extends LlmAdapter {
16172
16180
  while (true) {
16173
16181
  const { done, value } = await reader.read();
16174
16182
  if (done) break;
16183
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
16175
16184
  buffer += decoder.decode(value, { stream: true });
16176
16185
  const lines = buffer.split("\n");
16177
16186
  buffer = lines.pop() ?? "";
16178
16187
  for (const line of lines) {
16188
+ if (line.trim() !== "") activity?.pulse();
16179
16189
  for (const chunk of processLine$1(line, state, wire)) {
16180
16190
  outputStarted = true;
16181
16191
  yield chunk;
@@ -17768,7 +17778,7 @@ function chatUrl(wire) {
17768
17778
  * Response, because the caller has to decide between retrying this account and
17769
17779
  * failing the turn, and both need the status before any body is read.
17770
17780
  */
17771
- function startChat(fetchFn, credentials, wire, request) {
17781
+ function startChat(fetchFn, credentials, wire, request, activity) {
17772
17782
  let resolveStatus = () => void 0;
17773
17783
  let rejectStatus = () => void 0;
17774
17784
  const status = new Promise((resolve, reject) => {
@@ -17798,7 +17808,7 @@ function startChat(fetchFn, credentials, wire, request) {
17798
17808
  };
17799
17809
  return;
17800
17810
  }
17801
- yield* readStream(response, wire);
17811
+ yield* readStream(response, wire, activity);
17802
17812
  })(),
17803
17813
  status
17804
17814
  };
@@ -17811,7 +17821,7 @@ async function safeErrorText(response) {
17811
17821
  }
17812
17822
  }
17813
17823
  /** Parse the SSE stream of either surface. */
17814
- async function* readStream(response, wire) {
17824
+ async function* readStream(response, wire, activity) {
17815
17825
  const body = response.body;
17816
17826
  if (body === null) return;
17817
17827
  const decoder = new TextDecoder();
@@ -17822,12 +17832,14 @@ async function* readStream(response, wire) {
17822
17832
  for (;;) {
17823
17833
  const { done, value } = await reader.read();
17824
17834
  if (done) break;
17835
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
17825
17836
  buffer += decoder.decode(value, { stream: true });
17826
17837
  let newline = buffer.indexOf("\n");
17827
17838
  while (newline !== -1) {
17828
17839
  const line = buffer.slice(0, newline).trim();
17829
17840
  buffer = buffer.slice(newline + 1);
17830
17841
  newline = buffer.indexOf("\n");
17842
+ if (line !== "") activity?.pulse();
17831
17843
  if (line === "" || !line.startsWith("data:")) continue;
17832
17844
  const payload = line.slice(5).trim();
17833
17845
  if (payload === "" || payload === "[DONE]") continue;
@@ -18368,9 +18380,9 @@ var OllamaAdapter = class extends LlmAdapter {
18368
18380
  };
18369
18381
  }
18370
18382
  async *stream(options) {
18371
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream(options, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS$7, STREAM_IDLE_TIMEOUT_CODE$7, PROVIDER_NAME$5);
18383
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream(options, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS$7, STREAM_IDLE_TIMEOUT_CODE$7, PROVIDER_NAME$5);
18372
18384
  }
18373
- async *requestStream(rawOptions, signal) {
18385
+ async *requestStream(rawOptions, signal, activity) {
18374
18386
  const fetchFn = this.options.fetchFn ?? fetch;
18375
18387
  const options = normalizeGenerateOptions(rawOptions);
18376
18388
  const wire = wireForModel$1(options.model);
@@ -18412,7 +18424,7 @@ var OllamaAdapter = class extends LlmAdapter {
18412
18424
  const call = startChat(fetchFn, credentials, wire, {
18413
18425
  ...request,
18414
18426
  signal
18415
- });
18427
+ }, activity);
18416
18428
  const state = createStreamState$5();
18417
18429
  let openedStatus;
18418
18430
  call.status.then((value) => {
@@ -20406,14 +20418,14 @@ async function kimiIdentityHeaders(extra = {}) {
20406
20418
  * `AbortSignal.any` keeps whichever fires first, so an abandoned login stops
20407
20419
  * promptly while a hung endpoint still cannot hold the request forever.
20408
20420
  */
20409
- function withTimeout$7(signal, ms) {
20421
+ function withTimeout$8(signal, ms) {
20410
20422
  const timeout = AbortSignal.timeout(ms);
20411
20423
  return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
20412
20424
  }
20413
20425
  function oauthEndpoint(host, endpoint) {
20414
20426
  return `${host.replace(/\/+$/, "")}${endpoint}`;
20415
20427
  }
20416
- function asRecord$11(value) {
20428
+ function asRecord$12(value) {
20417
20429
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
20418
20430
  }
20419
20431
  /**
@@ -20424,8 +20436,8 @@ function asRecord$11(value) {
20424
20436
  * caller decides whether the flow continues.
20425
20437
  */
20426
20438
  function oauthErrorFields$2(payload) {
20427
- const root = asRecord$11(payload) ?? {};
20428
- const nested = asRecord$11(root.error);
20439
+ const root = asRecord$12(payload) ?? {};
20440
+ const nested = asRecord$12(root.error);
20429
20441
  if (nested !== void 0) return {
20430
20442
  code: typeof nested.code === "string" ? nested.code : "",
20431
20443
  description: String(nested.message ?? nested.error_description ?? nested.detail ?? nested.type ?? "")
@@ -20450,14 +20462,14 @@ async function requestDeviceAuthorization(options = {}) {
20450
20462
  accept: "application/json"
20451
20463
  }),
20452
20464
  body: new URLSearchParams$1({ client_id: KIMI_CODE_CLIENT_ID }).toString(),
20453
- signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$2)
20465
+ signal: withTimeout$8(options.signal, OAUTH_TIMEOUT_MS$2)
20454
20466
  });
20455
20467
  const payload = await response.json().catch(() => void 0);
20456
20468
  if (!response.ok) {
20457
20469
  const { description } = oauthErrorFields$2(payload);
20458
20470
  throw new Error(`Device authorization failed (${response.status})${description ? `: ${description}` : ""}`);
20459
20471
  }
20460
- const record = asRecord$11(payload) ?? {};
20472
+ const record = asRecord$12(payload) ?? {};
20461
20473
  const userCode = typeof record.user_code === "string" ? record.user_code : "";
20462
20474
  const deviceCode = typeof record.device_code === "string" ? record.device_code : "";
20463
20475
  const complete = typeof record.verification_uri_complete === "string" ? record.verification_uri_complete : "";
@@ -20496,10 +20508,10 @@ async function pollDeviceToken$1(host, deviceCode, options) {
20496
20508
  device_code: deviceCode,
20497
20509
  grant_type: DEVICE_CODE_GRANT_TYPE$1
20498
20510
  }).toString(),
20499
- signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$2)
20511
+ signal: withTimeout$8(options.signal, OAUTH_TIMEOUT_MS$2)
20500
20512
  });
20501
20513
  const payload = await response.json().catch(() => void 0);
20502
- const record = asRecord$11(payload) ?? {};
20514
+ const record = asRecord$12(payload) ?? {};
20503
20515
  if (response.status === 200 && typeof record.access_token === "string" && record.access_token !== "") return {
20504
20516
  kind: "success",
20505
20517
  token: parseTokenResponse$2(record)
@@ -20620,12 +20632,12 @@ async function refreshAccessToken$1(refreshToken, options = {}) {
20620
20632
  grant_type: "refresh_token",
20621
20633
  refresh_token: refreshToken
20622
20634
  }).toString(),
20623
- signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$2)
20635
+ signal: withTimeout$8(options.signal, OAUTH_TIMEOUT_MS$2)
20624
20636
  });
20625
20637
  const payload = await response.json().catch(() => void 0);
20626
20638
  const { code, description } = oauthErrorFields$2(payload);
20627
20639
  if (response.status === 401 || response.status === 403 || code === "invalid_grant") throw new KimiCodeUnauthorizedError(description || "Token refresh was rejected; sign in again.");
20628
- if (response.ok) return parseTokenResponse$2(asRecord$11(payload) ?? {});
20640
+ if (response.ok) return parseTokenResponse$2(asRecord$12(payload) ?? {});
20629
20641
  if (!RETRYABLE_REFRESH_STATUSES$1.has(response.status)) throw new Error(description || `Token refresh failed (HTTP ${response.status}).`);
20630
20642
  lastError = new KimiCodeRetryableError(description || `Token refresh failed (HTTP ${response.status}).`);
20631
20643
  } catch (error) {
@@ -20852,7 +20864,7 @@ const FIXED_POINT_CENTS = 1e6;
20852
20864
  function isRecord$26(value) {
20853
20865
  return typeof value === "object" && value !== null && !Array.isArray(value);
20854
20866
  }
20855
- function asRecord$10(value) {
20867
+ function asRecord$11(value) {
20856
20868
  return isRecord$26(value) ? value : void 0;
20857
20869
  }
20858
20870
  function asString$16(value) {
@@ -20995,7 +21007,7 @@ function parseThinkingType(record) {
20995
21007
  return raw === "only" || raw === "no" || raw === "both" ? raw : void 0;
20996
21008
  }
20997
21009
  function parseCatalogModel(value) {
20998
- const record = asRecord$10(value);
21010
+ const record = asRecord$11(value);
20999
21011
  if (record === void 0) return void 0;
21000
21012
  const id = asString$16(record.id);
21001
21013
  if (id === void 0) return void 0;
@@ -21003,10 +21015,10 @@ function parseCatalogModel(value) {
21003
21015
  if (status !== void 0 && RETIRED_MODEL_STATUSES.has(status)) return void 0;
21004
21016
  const contextWindow = firstNumber(record, ["context_length", "contextLength"]);
21005
21017
  if (contextWindow === void 0 || contextWindow <= 0) return void 0;
21006
- const declaredInput = firstNumber(asRecord$10(record.limit) ?? asRecord$10(record.limits) ?? {}, ["input"]) ?? firstNumber(record, ["max_input_tokens", "maxInputTokens"]);
21018
+ const declaredInput = firstNumber(asRecord$11(record.limit) ?? asRecord$11(record.limits) ?? {}, ["input"]) ?? firstNumber(record, ["max_input_tokens", "maxInputTokens"]);
21007
21019
  const maxInputTokens = declaredInput !== void 0 && declaredInput > 0 && declaredInput < contextWindow ? declaredInput : void 0;
21008
21020
  const thinkingType = parseThinkingType(record);
21009
- const efforts = asRecord$10(record.think_efforts) ?? asRecord$10(record.thinkEfforts);
21021
+ const efforts = asRecord$11(record.think_efforts) ?? asRecord$11(record.thinkEfforts);
21010
21022
  const validEfforts = Array.isArray(efforts?.valid_efforts) ? efforts.valid_efforts.filter((entry) => typeof entry === "string") : Array.isArray(efforts?.validEfforts) ? efforts.validEfforts.filter((entry) => typeof entry === "string") : void 0;
21011
21023
  const modalities = ["text"];
21012
21024
  if (record.supports_image_in === true || record.supportsImageIn === true) modalities.push("image");
@@ -21121,7 +21133,7 @@ async function performListing(options) {
21121
21133
  });
21122
21134
  if (!response.ok) throw new Error(`Kimi Code model listing failed (${response.status}).`);
21123
21135
  const payload = await response.json().catch(() => void 0);
21124
- const data = Array.isArray(payload) ? payload : asRecord$10(payload)?.data;
21136
+ const data = Array.isArray(payload) ? payload : asRecord$11(payload)?.data;
21125
21137
  if (!Array.isArray(data)) throw new Error("Kimi Code model listing was not in the documented shape.");
21126
21138
  const models = data.map(parseCatalogModel).filter((model) => model !== void 0);
21127
21139
  if (epoch !== catalogCacheEpoch$1) return models;
@@ -21455,7 +21467,7 @@ function usageWindow(id, record, descriptor) {
21455
21467
  * than a fabricated 0%.
21456
21468
  */
21457
21469
  function parseUsageWindows(payload) {
21458
- const root = asRecord$10(payload) ?? {};
21470
+ const root = asRecord$11(payload) ?? {};
21459
21471
  const windows = [];
21460
21472
  const seen = /* @__PURE__ */ new Set();
21461
21473
  const push = (id, record, descriptor) => {
@@ -21465,23 +21477,23 @@ function parseUsageWindows(payload) {
21465
21477
  seen.add(id);
21466
21478
  windows.push(parsed);
21467
21479
  };
21468
- const usages = asRecord$10(root.usages) ?? asRecord$10(root.usageWindows);
21480
+ const usages = asRecord$11(root.usages) ?? asRecord$11(root.usageWindows);
21469
21481
  if (usages !== void 0) {
21470
21482
  const keys = [...WINDOW_ORDER.filter((key) => usages[key] !== void 0), ...Object.keys(usages).filter((key) => !WINDOW_ORDER.includes(key))];
21471
21483
  for (const key of keys) {
21472
- const record = asRecord$10(usages[key]);
21484
+ const record = asRecord$11(usages[key]);
21473
21485
  if (record === void 0) continue;
21474
21486
  push(key, record, WINDOW_DESCRIPTORS[key]);
21475
21487
  }
21476
21488
  }
21477
- const topLevel = asRecord$10(root.usage);
21489
+ const topLevel = asRecord$11(root.usage);
21478
21490
  if (topLevel !== void 0 && seen.size === 0) push("limit_7d", topLevel, WINDOW_DESCRIPTORS.limit_7d);
21479
21491
  const limits = Array.isArray(root.limits) ? root.limits : [];
21480
21492
  for (const entry of limits) {
21481
- const record = asRecord$10(entry);
21493
+ const record = asRecord$11(entry);
21482
21494
  if (record === void 0) continue;
21483
- const detail = asRecord$10(record.detail) ?? record;
21484
- const window = asRecord$10(record.window);
21495
+ const detail = asRecord$11(record.detail) ?? record;
21496
+ const window = asRecord$11(record.window);
21485
21497
  const duration = firstNumber(window ?? {}, ["duration"]);
21486
21498
  const unit = asString$16(window?.timeUnit ?? window?.time_unit);
21487
21499
  const minutes = duration === void 0 ? null : unit === "TIME_UNIT_HOUR" ? duration * 60 : duration;
@@ -21514,13 +21526,13 @@ function fixedPointToCents(value) {
21514
21526
  * under-report a charge limit by six orders of magnitude.
21515
21527
  */
21516
21528
  function moneyCents(value) {
21517
- const record = asRecord$10(value);
21529
+ const record = asRecord$11(value);
21518
21530
  if (record === void 0) return null;
21519
21531
  const cents = asNumber$4(record.priceInCents ?? record.price_in_cents);
21520
21532
  return cents === void 0 || !Number.isFinite(cents) ? null : Math.round(cents);
21521
21533
  }
21522
21534
  function moneyCurrency(value) {
21523
- const record = asRecord$10(value);
21535
+ const record = asRecord$11(value);
21524
21536
  return record === void 0 ? void 0 : asString$16(record.currency);
21525
21537
  }
21526
21538
  /**
@@ -21531,10 +21543,10 @@ function moneyCurrency(value) {
21531
21543
  * cannot spend.
21532
21544
  */
21533
21545
  function parseExtraUsage(payload) {
21534
- const root = asRecord$10(payload) ?? {};
21535
- const wallet = asRecord$10(root.boosterWallet) ?? asRecord$10(root.booster_wallet) ?? asRecord$10(root.extraUsage);
21546
+ const root = asRecord$11(payload) ?? {};
21547
+ const wallet = asRecord$11(root.boosterWallet) ?? asRecord$11(root.booster_wallet) ?? asRecord$11(root.extraUsage);
21536
21548
  if (wallet === void 0) return null;
21537
- const balance = asRecord$10(wallet.balance);
21549
+ const balance = asRecord$11(wallet.balance);
21538
21550
  const balanceType = asString$16(balance?.type);
21539
21551
  const amount = asNumber$4(balance?.amount);
21540
21552
  if (balance === void 0 || balanceType !== "BOOSTER" || amount === void 0 || amount <= 0) return null;
@@ -21583,7 +21595,7 @@ function membershipLevelName(level) {
21583
21595
  * `user_level_name` still yields a readable tier instead of a raw enum.
21584
21596
  */
21585
21597
  function parsePlanName(payload) {
21586
- const root = asRecord$10(payload) ?? {};
21598
+ const root = asRecord$11(payload) ?? {};
21587
21599
  const direct = firstString(root, [
21588
21600
  "user_level_name",
21589
21601
  "userLevelName",
@@ -21591,17 +21603,17 @@ function parsePlanName(payload) {
21591
21603
  "plan_name"
21592
21604
  ]);
21593
21605
  if (direct !== void 0) return direct;
21594
- const membership = asRecord$10(asRecord$10(root.user)?.membership);
21606
+ const membership = asRecord$11(asRecord$11(root.user)?.membership);
21595
21607
  const named = asString$16(membership?.level_name ?? membership?.levelName);
21596
21608
  if (named !== void 0) return named;
21597
21609
  return membershipLevelName(asString$16(membership?.level) ?? null);
21598
21610
  }
21599
21611
  /** Machine tier level when the service reports one. */
21600
21612
  function parsePlanLevel(payload) {
21601
- const root = asRecord$10(payload) ?? {};
21613
+ const root = asRecord$11(payload) ?? {};
21602
21614
  const direct = firstNumber(root, ["user_level", "userLevel"]);
21603
21615
  if (direct !== void 0) return String(direct);
21604
- const membership = asRecord$10(asRecord$10(root.user)?.membership);
21616
+ const membership = asRecord$11(asRecord$11(root.user)?.membership);
21605
21617
  return asString$16(membership?.level ?? membership?.levelId ?? membership?.level_id) ?? null;
21606
21618
  }
21607
21619
  /**
@@ -21708,7 +21720,7 @@ function accountFromCredentials$2(credentials, payload, profile) {
21708
21720
  const planLevel = (profile === void 0 ? null : parsePlanLevel(profile)) ?? (payload === void 0 ? null : parsePlanLevel(payload));
21709
21721
  return {
21710
21722
  userId: credentials.userId ?? identity.userId ?? null,
21711
- nickname: (profile === void 0 ? null : firstString(asRecord$10(profile) ?? {}, [
21723
+ nickname: (profile === void 0 ? null : firstString(asRecord$11(profile) ?? {}, [
21712
21724
  "nickname",
21713
21725
  "username",
21714
21726
  "name"
@@ -24138,9 +24150,9 @@ var KimiCodeAdapter = class extends LlmAdapter {
24138
24150
  ...options,
24139
24151
  reasoningEffort: ReasoningEffortId(String(effort))
24140
24152
  };
24141
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream(effectiveOptions, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS$4, STREAM_IDLE_TIMEOUT_CODE$4, PROVIDER_NAME$4);
24153
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream(effectiveOptions, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS$4, STREAM_IDLE_TIMEOUT_CODE$4, PROVIDER_NAME$4);
24142
24154
  }
24143
- async *requestStream(options, signal) {
24155
+ async *requestStream(options, signal, activity) {
24144
24156
  const fetchFn = this.options.fetchFn ?? fetch;
24145
24157
  const catalog = await this.catalog().catch(() => []);
24146
24158
  const wire = wireForCatalogEntry(options.model, catalog);
@@ -24276,10 +24288,12 @@ var KimiCodeAdapter = class extends LlmAdapter {
24276
24288
  while (true) {
24277
24289
  const { done, value } = await reader.read();
24278
24290
  if (done) break;
24291
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
24279
24292
  buffer += decoder.decode(value, { stream: true });
24280
24293
  const lines = buffer.split("\n");
24281
24294
  buffer = lines.pop() ?? "";
24282
24295
  for (const line of lines) {
24296
+ activity?.pulse();
24283
24297
  for (const chunk of processLine(line, state, wire)) {
24284
24298
  outputStarted = true;
24285
24299
  yield chunk;
@@ -27891,11 +27905,11 @@ const OAUTH_HEADERS = {
27891
27905
  accept: "application/json",
27892
27906
  "content-type": "application/x-www-form-urlencoded"
27893
27907
  };
27894
- function withTimeout$6(signal, ms) {
27908
+ function withTimeout$7(signal, ms) {
27895
27909
  const timeout = AbortSignal.timeout(ms);
27896
27910
  return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
27897
27911
  }
27898
- function asRecord$9(value) {
27912
+ function asRecord$10(value) {
27899
27913
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
27900
27914
  }
27901
27915
  function asString$11(value) {
@@ -27909,8 +27923,8 @@ function asString$11(value) {
27909
27923
  * both are unwrapped before the caller decides what the failure means.
27910
27924
  */
27911
27925
  function oauthErrorFields$1(payload) {
27912
- const root = asRecord$9(payload) ?? {};
27913
- const nested = asRecord$9(root.error);
27926
+ const root = asRecord$10(payload) ?? {};
27927
+ const nested = asRecord$10(root.error);
27914
27928
  if (nested !== void 0) return {
27915
27929
  code: asString$11(nested.code) ?? "",
27916
27930
  description: String(nested.message ?? nested.error_description ?? nested.detail ?? nested.type ?? "")
@@ -27959,14 +27973,14 @@ async function requestDeviceAuthorization$1(options = {}) {
27959
27973
  code_challenge: pkce.challenge,
27960
27974
  code_challenge_method: PKCE_CHALLENGE_METHOD
27961
27975
  }).toString(),
27962
- signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
27976
+ signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$1)
27963
27977
  });
27964
27978
  const payload = await response.json().catch(() => void 0);
27965
27979
  if (!response.ok) {
27966
27980
  const { description } = oauthErrorFields$1(payload);
27967
27981
  throw new Error("MiniMax Code device authorization failed (" + response.status + ")" + (description === "" ? "" : ": " + description));
27968
27982
  }
27969
- const record = asRecord$9(payload) ?? {};
27983
+ const record = asRecord$10(payload) ?? {};
27970
27984
  const userCode = asString$11(record.user_code);
27971
27985
  const deviceCode = asString$11(record.device_code);
27972
27986
  if (userCode === void 0 || deviceCode === void 0) throw new Error("MiniMax Code device authorization response carried no device code or user code");
@@ -28017,10 +28031,10 @@ async function pollDeviceToken(authorization, options = {}) {
28017
28031
  code_verifier: authorization.codeVerifier,
28018
28032
  grant_type: DEVICE_CODE_GRANT_TYPE
28019
28033
  }).toString(),
28020
- signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
28034
+ signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$1)
28021
28035
  });
28022
28036
  const payload = await response.json().catch(() => void 0);
28023
- const record = asRecord$9(payload) ?? {};
28037
+ const record = asRecord$10(payload) ?? {};
28024
28038
  if (response.ok && asString$11(record.access_token) !== void 0) return {
28025
28039
  kind: "success",
28026
28040
  token: parseTokenResponse$1(record)
@@ -28079,12 +28093,12 @@ async function refreshAccessToken$2(refreshToken, options) {
28079
28093
  scope: MINIMAX_CODE_SCOPE,
28080
28094
  audience: MINIMAX_CODE_AUDIENCE
28081
28095
  }).toString(),
28082
- signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
28096
+ signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$1)
28083
28097
  });
28084
28098
  const payload = await response.json().catch(() => void 0);
28085
28099
  const { code, description } = oauthErrorFields$1(payload);
28086
28100
  if (response.status === 400 || response.status === 401 || response.status === 403 || code === "invalid_grant" || code === "invalid_client") throw new MinimaxCodeUnauthorizedError("MiniMax Code rejected the stored refresh token " + redactToken(refreshToken) + ". Sign in again in MiniMax Code, then reopen this card.");
28087
- if (response.ok) return parseTokenResponse$1(asRecord$9(payload) ?? {});
28101
+ if (response.ok) return parseTokenResponse$1(asRecord$10(payload) ?? {});
28088
28102
  if (!RETRYABLE_REFRESH_STATUSES.has(response.status)) throw new MinimaxCodeRetryableError(description || "MiniMax Code token refresh failed (HTTP " + response.status + ").");
28089
28103
  lastError = new MinimaxCodeRetryableError(description || "MiniMax Code token refresh failed (HTTP " + response.status + ").");
28090
28104
  } catch (error) {
@@ -28112,7 +28126,7 @@ async function revokeToken(token, options) {
28112
28126
  token,
28113
28127
  token_type_hint: "refresh_token"
28114
28128
  }).toString(),
28115
- signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
28129
+ signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$1)
28116
28130
  })).ok;
28117
28131
  } catch {
28118
28132
  return false;
@@ -28384,7 +28398,7 @@ async function pollWebLogin(store, loginId, options = {}) {
28384
28398
  */
28385
28399
  /** Timeout for the connection probe and any other one-shot call. */
28386
28400
  const PROBE_TIMEOUT_MS = 3e4;
28387
- function withTimeout$5(signal, ms) {
28401
+ function withTimeout$6(signal, ms) {
28388
28402
  const timeout = AbortSignal.timeout(ms);
28389
28403
  return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
28390
28404
  }
@@ -28414,7 +28428,7 @@ function probeRequestHeaders(accessToken) {
28414
28428
  accept: "application/json"
28415
28429
  };
28416
28430
  }
28417
- function asRecord$8(value) {
28431
+ function asRecord$9(value) {
28418
28432
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
28419
28433
  }
28420
28434
  function numberOr$4(value, fallback) {
@@ -28422,7 +28436,7 @@ function numberOr$4(value, fallback) {
28422
28436
  }
28423
28437
  /** Read the four token counters the Messages response reports. */
28424
28438
  function parseAnthropicUsage(payload) {
28425
- const usage = asRecord$8(asRecord$8(payload)?.usage);
28439
+ const usage = asRecord$9(asRecord$9(payload)?.usage);
28426
28440
  if (usage === void 0) return null;
28427
28441
  return {
28428
28442
  inputTokens: numberOr$4(usage.input_tokens, 0),
@@ -28436,13 +28450,13 @@ function summarizeFailureBody(raw) {
28436
28450
  const text = raw.replace(/[\r\n\t]+/g, " ").trim();
28437
28451
  if (text === "") return "";
28438
28452
  try {
28439
- const record = asRecord$8(JSON.parse(text));
28453
+ const record = asRecord$9(JSON.parse(text));
28440
28454
  if (record !== void 0) {
28441
28455
  const message = record.message ?? record.error_description ?? record.errorReason ?? record.error;
28442
28456
  if (typeof message === "string") return message.slice(0, 400);
28443
- const nestedMessage = asRecord$8(record.error)?.message;
28457
+ const nestedMessage = asRecord$9(record.error)?.message;
28444
28458
  if (typeof nestedMessage === "string") return nestedMessage.slice(0, 400);
28445
- const baseResp = asRecord$8(record.base_resp)?.status_msg;
28459
+ const baseResp = asRecord$9(record.base_resp)?.status_msg;
28446
28460
  if (typeof baseResp === "string") return baseResp.slice(0, 400);
28447
28461
  }
28448
28462
  } catch {}
@@ -28494,7 +28508,7 @@ async function testConnection(store, options = {}) {
28494
28508
  content: "ping"
28495
28509
  }]
28496
28510
  }),
28497
- signal: withTimeout$5(options.signal, PROBE_TIMEOUT_MS)
28511
+ signal: withTimeout$6(options.signal, PROBE_TIMEOUT_MS)
28498
28512
  });
28499
28513
  const latencyMs = Date.now() - startedAt;
28500
28514
  if (!response.ok) {
@@ -28559,7 +28573,7 @@ async function createMessage(store, request, options = {}) {
28559
28573
  content: request.prompt
28560
28574
  }]
28561
28575
  }),
28562
- signal: withTimeout$5(options.signal, PROBE_TIMEOUT_MS)
28576
+ signal: withTimeout$6(options.signal, PROBE_TIMEOUT_MS)
28563
28577
  });
28564
28578
  const payload = await response.json().catch(() => void 0);
28565
28579
  return {
@@ -28761,11 +28775,11 @@ function quotaWindow(input) {
28761
28775
  * card's graceful degradation.
28762
28776
  */
28763
28777
  function parseTokenPlanQuota(payload, now = Date.now()) {
28764
- const rows = asRecord$8(payload)?.model_remains;
28778
+ const rows = asRecord$9(payload)?.model_remains;
28765
28779
  if (!Array.isArray(rows)) return null;
28766
28780
  const entries = [];
28767
28781
  for (const raw of rows) {
28768
- const row = asRecord$8(raw);
28782
+ const row = asRecord$9(raw);
28769
28783
  if (row === void 0) continue;
28770
28784
  const name = typeof row.model_name === "string" && row.model_name !== "" ? row.model_name : "quota";
28771
28785
  const intervalTotal = numberOr$4(row.current_interval_total_count, 0);
@@ -28832,7 +28846,7 @@ async function fetchTokenPlanQuota(credentials, options = {}) {
28832
28846
  const response = await fetchFn(tokenPlanRemainsUrl(host), {
28833
28847
  method: "GET",
28834
28848
  headers: quotaRequestHeaders(credentials.accessToken, remainsPath),
28835
- signal: withTimeout$5(options.signal, QUOTA_TIMEOUT_MS)
28849
+ signal: withTimeout$6(options.signal, QUOTA_TIMEOUT_MS)
28836
28850
  });
28837
28851
  if (response.status === 401 || response.status === 403) {
28838
28852
  if (await options.isCredentialStale?.() === true) return null;
@@ -28841,7 +28855,7 @@ async function fetchTokenPlanQuota(credentials, options = {}) {
28841
28855
  }
28842
28856
  if (!response.ok) continue;
28843
28857
  const payload = await response.json().catch(() => void 0);
28844
- if (numberOr$4(asRecord$8(asRecord$8(payload)?.base_resp)?.status_code, 0) !== 0) {
28858
+ if (numberOr$4(asRecord$9(asRecord$9(payload)?.base_resp)?.status_code, 0) !== 0) {
28845
28859
  reason = "credential-not-accepted";
28846
28860
  break;
28847
28861
  }
@@ -29662,9 +29676,9 @@ var MinimaxCodeAdapter = class extends LlmAdapter {
29662
29676
  ...options,
29663
29677
  reasoningEffort: ReasoningEffortId(String(effort))
29664
29678
  };
29665
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream(effectiveOptions, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS$3, STREAM_IDLE_TIMEOUT_CODE$3, PROVIDER_NAME$3);
29679
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream(effectiveOptions, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS$3, STREAM_IDLE_TIMEOUT_CODE$3, PROVIDER_NAME$3);
29666
29680
  }
29667
- async *requestStream(options, signal) {
29681
+ async *requestStream(options, signal, activity) {
29668
29682
  const fetchFn = this.options.fetchFn ?? fetch;
29669
29683
  const settings = await this.settings();
29670
29684
  minimaxCodeModelDef(options.model);
@@ -29772,10 +29786,12 @@ var MinimaxCodeAdapter = class extends LlmAdapter {
29772
29786
  while (true) {
29773
29787
  const { done, value } = await reader.read();
29774
29788
  if (done) break;
29789
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
29775
29790
  buffer += decoder.decode(value, { stream: true });
29776
29791
  const lines = buffer.split("\n");
29777
29792
  buffer = lines.pop() ?? "";
29778
29793
  for (const line of lines) {
29794
+ activity?.pulse();
29779
29795
  for (const chunk of processMinimaxStreamLine(line, state)) {
29780
29796
  outputStarted = true;
29781
29797
  yield chunk;
@@ -30466,6 +30482,287 @@ function createMinimaxCodeAccountsHandler(pool, options = {}) {
30466
30482
  };
30467
30483
  }
30468
30484
  //#endregion
30485
+ //#region src/host/minimax-code/reset-card.ts
30486
+ /** Path that spends a card. */
30487
+ const RESET_CARD_USE_PATH = "/backend/account/reset_card/use";
30488
+ /** The flow window the panel shows, and the start `flows` is asked from. */
30489
+ const RESET_CARD_FLOW_WINDOW_MS = 720 * 60 * 60 * 1e3;
30490
+ /** Local timeout for one reset-card call. */
30491
+ const RESET_CARD_TIMEOUT_MS = 15e3;
30492
+ /** The outcomes the service reports, exactly. */
30493
+ const RESET_OUTCOMES = /* @__PURE__ */ new Set([
30494
+ "SUCCESS",
30495
+ "REPLAYED",
30496
+ "EXPIRED",
30497
+ "NOT_FOUND",
30498
+ "RETRYABLE_FAIL",
30499
+ "LOCK_BUSY"
30500
+ ]);
30501
+ /**
30502
+ * A reset-card call that failed.
30503
+ *
30504
+ * `statusCode` is the envelope's `base_resp.status_code` (the platform answers
30505
+ * HTTP 200 for a refusal), `httpStatus` the status line when the transport
30506
+ * itself refused. Both are kept so the route can answer 401 for an expired token
30507
+ * rather than the generic 502 it would otherwise send for an upstream refusal.
30508
+ */
30509
+ var MinimaxCodeResetCardError = class extends Error {
30510
+ httpStatus;
30511
+ statusCode;
30512
+ constructor(message, httpStatus, statusCode) {
30513
+ super(message);
30514
+ this.httpStatus = httpStatus;
30515
+ this.statusCode = statusCode;
30516
+ this.name = "MinimaxCodeResetCardError";
30517
+ }
30518
+ };
30519
+ /**
30520
+ * Status line one failure should be reported to the browser with.
30521
+ *
30522
+ * The envelope codes are mapped rather than flattened, because "rate limited"
30523
+ * and "your sign-in expired" ask the user for opposite things: one is a
30524
+ * "try in a minute", the other is a refresh this line performs on its own.
30525
+ */
30526
+ function resetCardHttpStatus(error) {
30527
+ if (!(error instanceof MinimaxCodeResetCardError)) return 502;
30528
+ if (error.httpStatus === 401 || error.httpStatus === 403) return 401;
30529
+ if (error.statusCode === 1002) return 429;
30530
+ if (error.statusCode === 1004) return 401;
30531
+ if (error.statusCode === 2013) return 404;
30532
+ return error.httpStatus !== null && error.httpStatus >= 400 ? 502 : 502;
30533
+ }
30534
+ function asRecord$8(value) {
30535
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
30536
+ }
30537
+ /** A finite number, or undefined. The service's epoch fields are milliseconds. */
30538
+ function ms(value) {
30539
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
30540
+ }
30541
+ /** A non-empty string, or undefined. */
30542
+ function text$1(value) {
30543
+ return typeof value === "string" && value !== "" ? value : void 0;
30544
+ }
30545
+ function withTimeout$5(signal, ms_) {
30546
+ const timeout = AbortSignal.timeout(ms_);
30547
+ return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
30548
+ }
30549
+ /**
30550
+ * Headers for one reset-card call.
30551
+ *
30552
+ * The bearer is the only credential field: measured, the desktop client's
30553
+ * literal `token:` header is refused with 401 by these routes. Nothing derived
30554
+ * from the token is ever logged, so a failure sentence can name the surface
30555
+ * without naming the credential.
30556
+ */
30557
+ function resetCardRequestHeaders(accessToken) {
30558
+ return {
30559
+ authorization: "Bearer " + accessToken,
30560
+ accept: "application/json",
30561
+ "content-type": "application/json",
30562
+ "user-agent": USER_AGENT$1
30563
+ };
30564
+ }
30565
+ /**
30566
+ * The host that last answered a reset-card call.
30567
+ *
30568
+ * Mirrors the usage read's own habit: only a live call settles which candidate
30569
+ * serves this subscription, so the winner is tried first from then on and the
30570
+ * remaining uncertainty stays in one place.
30571
+ */
30572
+ let resetCardHostInForce = null;
30573
+ /** Candidates for one region, the remembered winner first. */
30574
+ function orderedHosts(region) {
30575
+ const candidates = quotaHostCandidates(region);
30576
+ return resetCardHostInForce === null ? candidates : [resetCardHostInForce, ...candidates.filter((host) => host !== resetCardHostInForce)];
30577
+ }
30578
+ /** The envelope's verdict: 0 means the call did what it was asked. */
30579
+ function readStatusCode(payload) {
30580
+ return asRecord$8(asRecord$8(payload)?.base_resp)?.status_code === void 0 ? 0 : Number(asRecord$8(asRecord$8(payload)?.base_resp)?.status_code);
30581
+ }
30582
+ function statusMessage(payload, fallback) {
30583
+ const message = asRecord$8(asRecord$8(payload)?.base_resp)?.status_msg;
30584
+ return typeof message === "string" && message !== "" ? message : fallback;
30585
+ }
30586
+ /**
30587
+ * One JSON call, walking the host candidates.
30588
+ *
30589
+ * Every candidate is tried for a TRANSPORT or business failure alike: a 401 on
30590
+ * one host is a host that does not serve this route, not a verdict on the
30591
+ * credential — and the task this read serves (which card the user still holds)
30592
+ * is worth finding on the next candidate rather than failing over.
30593
+ */
30594
+ async function resetCardCall(input) {
30595
+ let response;
30596
+ try {
30597
+ response = await input.fetchFn(input.url, {
30598
+ method: input.method,
30599
+ headers: resetCardRequestHeaders(input.accessToken),
30600
+ ...input.body === void 0 ? {} : { body: input.body },
30601
+ signal: withTimeout$5(input.signal, RESET_CARD_TIMEOUT_MS)
30602
+ });
30603
+ } catch (error) {
30604
+ throw new MinimaxCodeResetCardError("reset-card call could not be reached: " + (error instanceof Error ? error.message : String(error)), null, null);
30605
+ }
30606
+ if (!response.ok) throw new MinimaxCodeResetCardError("reset-card call failed with HTTP " + response.status, response.status, null);
30607
+ const payload = await response.json().catch(() => void 0);
30608
+ const statusCode = readStatusCode(payload);
30609
+ if (statusCode !== 0) throw new MinimaxCodeResetCardError(statusMessage(payload, "reset-card call rejected with base_resp " + statusCode), response.status, statusCode);
30610
+ resetCardHostInForce = input.host;
30611
+ return payload;
30612
+ }
30613
+ /** Run one call against the candidate list, keeping the last failure to report. */
30614
+ async function callAcrossHosts(input) {
30615
+ const fetchFn = input.options.fetchFn ?? fetch;
30616
+ let lastError = null;
30617
+ for (const host of orderedHosts(input.credentials.region)) try {
30618
+ return await resetCardCall({
30619
+ url: host.replace(/\/+$/, "") + input.path,
30620
+ method: input.method,
30621
+ accessToken: input.credentials.accessToken,
30622
+ host,
30623
+ fetchFn,
30624
+ ...input.body === void 0 ? {} : { body: input.body },
30625
+ ...input.options.signal === void 0 ? {} : { signal: input.options.signal }
30626
+ });
30627
+ } catch (error) {
30628
+ lastError = error;
30629
+ }
30630
+ if (lastError instanceof MinimaxCodeResetCardError) throw lastError;
30631
+ throw new MinimaxCodeResetCardError("reset-card call had no usable host", null, null);
30632
+ }
30633
+ /** One card, or undefined when a required field is missing or mistyped. */
30634
+ function parseResetCard(raw) {
30635
+ const row = asRecord$8(raw);
30636
+ if (row === void 0) return void 0;
30637
+ const cardId = text$1(row.card_id);
30638
+ const sourceType = text$1(row.source_type);
30639
+ const outBizNo = text$1(row.out_biz_no);
30640
+ const expiresAtMs = ms(row.expire_time);
30641
+ const createdAtMs = ms(row.create_time);
30642
+ if (cardId === void 0 || sourceType === void 0 || outBizNo === void 0) return void 0;
30643
+ if (expiresAtMs === void 0 || createdAtMs === void 0) return void 0;
30644
+ return {
30645
+ cardId,
30646
+ sourceType,
30647
+ expiresAtMs,
30648
+ createdAtMs,
30649
+ outBizNo
30650
+ };
30651
+ }
30652
+ /**
30653
+ * One flow row.
30654
+ *
30655
+ * `event_type` is a closed vocabulary, and an unknown value is dropped rather
30656
+ * than passed through: the contract says GRANT | USE, and a card rendered with a
30657
+ * third value would be showing this plugin an assumption it cannot back.
30658
+ */
30659
+ function parseResetCardFlow(raw) {
30660
+ const row = asRecord$8(raw);
30661
+ if (row === void 0) return void 0;
30662
+ const cardId = text$1(row.card_id);
30663
+ const eventType = text$1(row.event_type);
30664
+ const createdAtMs = ms(row.create_time);
30665
+ if (cardId === void 0 || createdAtMs === void 0) return void 0;
30666
+ if (eventType !== "GRANT" && eventType !== "USE") return void 0;
30667
+ return {
30668
+ cardId,
30669
+ eventType,
30670
+ createdAtMs
30671
+ };
30672
+ }
30673
+ /** The available cards from one `list` document. */
30674
+ function parseResetCardList(payload) {
30675
+ const rows = asRecord$8(payload)?.cards;
30676
+ if (!Array.isArray(rows)) return [];
30677
+ const cards = [];
30678
+ for (const raw of rows) {
30679
+ const card = parseResetCard(raw);
30680
+ if (card !== void 0) cards.push(card);
30681
+ }
30682
+ return cards;
30683
+ }
30684
+ /** The flow rows from one `flows` document. */
30685
+ function parseResetCardFlows(payload) {
30686
+ const rows = asRecord$8(payload)?.flows;
30687
+ if (!Array.isArray(rows)) return [];
30688
+ const flows = [];
30689
+ for (const raw of rows) {
30690
+ const flow = parseResetCardFlow(raw);
30691
+ if (flow !== void 0) flows.push(flow);
30692
+ }
30693
+ return flows;
30694
+ }
30695
+ /** The query the flow read is sent with. `create_time` is mandatory. */
30696
+ function resetCardFlowsQuery(sinceMs, page = 1, size = 20) {
30697
+ return new URLSearchParams({
30698
+ create_time: String(Math.floor(sinceMs)),
30699
+ page: String(page),
30700
+ size: String(size)
30701
+ }).toString();
30702
+ }
30703
+ /** The query the list read is sent with. */
30704
+ function resetCardListQuery(page = 1, size = 20) {
30705
+ return new URLSearchParams({
30706
+ page: String(page),
30707
+ size: String(size)
30708
+ }).toString();
30709
+ }
30710
+ /**
30711
+ * The reset-card panel: the cards still held, plus the recent flow.
30712
+ *
30713
+ * Two requests, and the asymmetry between them is the point: the LIST is the
30714
+ * panel's substance, so a failure of it is reported; the FLOW is context, so its
30715
+ * failure degrades to an empty list and the cards still render. A user whose
30716
+ * flow read is refused loses a history row, not the button they came to press.
30717
+ */
30718
+ async function fetchResetCards(credentials, options = {}) {
30719
+ const now = (options.nowMs ?? Date.now)();
30720
+ return {
30721
+ cards: parseResetCardList(await callAcrossHosts({
30722
+ path: "/backend/account/reset_card/list?" + resetCardListQuery(),
30723
+ method: "GET",
30724
+ credentials,
30725
+ options
30726
+ })),
30727
+ flows: parseResetCardFlows(await callAcrossHosts({
30728
+ path: "/backend/account/reset_card/flows?" + resetCardFlowsQuery(now - RESET_CARD_FLOW_WINDOW_MS),
30729
+ method: "GET",
30730
+ credentials,
30731
+ options
30732
+ }).catch(() => null)),
30733
+ fetchedAtMs: now
30734
+ };
30735
+ }
30736
+ /**
30737
+ * Spend one card.
30738
+ *
30739
+ * The body is exactly two fields, both copied off the card. There is deliberately
30740
+ * no request id here: de-duplication is the service's, keyed on `out_biz_no`,
30741
+ * and a self-minted id would make a second click spend a second card — the exact
30742
+ * harm this line's contract warns about.
30743
+ *
30744
+ * The returned outcome is passed through rather than collapsed into a boolean,
30745
+ * because three of the six values mean "possibly spent, confirm with THIS card"
30746
+ * (REPLAYED, LOCK_BUSY, RETRYABLE_FAIL) and the caller has to be able to tell the
30747
+ * user to retry the same card instead of another one.
30748
+ */
30749
+ async function useResetCard(credentials, card, options = {}) {
30750
+ if (card.sourceType === "" || card.outBizNo === "") throw new MinimaxCodeResetCardError("the reset card is missing its source type or idempotency key", null, null);
30751
+ const payload = await callAcrossHosts({
30752
+ path: RESET_CARD_USE_PATH,
30753
+ method: "POST",
30754
+ credentials,
30755
+ body: JSON.stringify({
30756
+ source_type: card.sourceType,
30757
+ out_biz_no: card.outBizNo
30758
+ }),
30759
+ options
30760
+ });
30761
+ const outcome = text$1(asRecord$8(payload)?.outcome);
30762
+ if (outcome === void 0 || !RESET_OUTCOMES.has(outcome)) throw new MinimaxCodeResetCardError("reset-card use answered without a usable outcome", null, readStatusCode(payload));
30763
+ return outcome;
30764
+ }
30765
+ //#endregion
30469
30766
  //#region src/host/minimax-code/routes.ts
30470
30767
  /** Path the sibling lines register (\`/kimi-code/api\`, \`/workbuddy/api\`). */
30471
30768
  const MAX_BODY_BYTES$3 = 64 * 1024;
@@ -30624,6 +30921,20 @@ function registerMinimaxCodeRoutes(ctx, store = new MinimaxCodeCredentialStore()
30624
30921
  * had neither half.
30625
30922
  */
30626
30923
  const quotaRefresh = new QuotaRefresh();
30924
+ /**
30925
+ * The credential a reset-card call presents, read the same way `refreshQuota`
30926
+ * reads one.
30927
+ *
30928
+ * The pool is the rotation authority when it is installed, so the reset-card
30929
+ * surface must take its credential from the same place a model request would:
30930
+ * a second, independent reader would be a second refresh-token authority, and
30931
+ * two of them presenting the same rotating token is how a healthy account ends
30932
+ * up reported as needing a new sign-in.
30933
+ */
30934
+ const readResetCardCredential = async () => {
30935
+ if (options.accountPool !== void 0) return (await options.accountPool.getQuotaReadTarget(fetchFn).catch(() => null))?.credentials ?? null;
30936
+ return await ensureAccessToken$2(store, { fetchFn }).catch(() => null);
30937
+ };
30627
30938
  const handler = async (request, response) => {
30628
30939
  const path = subPathOf(request.url ?? "/");
30629
30940
  const method = request.method ?? "GET";
@@ -30685,6 +30996,51 @@ function registerMinimaxCodeRoutes(ctx, store = new MinimaxCodeCredentialStore()
30685
30996
  value: await getMinimaxCodeWebStatus(store, options, settings)
30686
30997
  });
30687
30998
  }
30999
+ if (path === "reset-cards") {
31000
+ if (method !== "GET") return sendMethodNotAllowed$3(response);
31001
+ const credentials = await readResetCardCredential();
31002
+ if (credentials === null) return sendJson$3(response, 401, {
31003
+ ok: false,
31004
+ error: "Not signed in."
31005
+ });
31006
+ return sendJson$3(response, 200, {
31007
+ ok: true,
31008
+ value: await fetchResetCards(credentials, { fetchFn })
31009
+ });
31010
+ }
31011
+ if (path === "reset-cards/use") {
31012
+ if (method !== "POST") return sendMethodNotAllowed$3(response);
31013
+ if (!isSameOriginMutation(request)) return sendCrossOrigin$1(response);
31014
+ const body = await readRequestJson$3(request);
31015
+ const cardId = typeof body.cardId === "string" ? body.cardId : "";
31016
+ if (cardId === "") return sendJson$3(response, 400, {
31017
+ ok: false,
31018
+ error: "cardId is required."
31019
+ });
31020
+ const credentials = await readResetCardCredential();
31021
+ if (credentials === null) return sendJson$3(response, 401, {
31022
+ ok: false,
31023
+ error: "Not signed in."
31024
+ });
31025
+ const before = await fetchResetCards(credentials, { fetchFn });
31026
+ const card = before.cards.find((entry) => entry.cardId === cardId);
31027
+ if (card === void 0) return sendJson$3(response, 404, {
31028
+ ok: false,
31029
+ error: "No reset card with that id is currently available."
31030
+ });
31031
+ const value = {
31032
+ outcome: await useResetCard(credentials, {
31033
+ sourceType: card.sourceType,
31034
+ outBizNo: card.outBizNo
31035
+ }, { fetchFn }),
31036
+ cards: await fetchResetCards(credentials, { fetchFn }).catch(() => before)
31037
+ };
31038
+ return sendJson$3(response, 200, {
31039
+ ok: true,
31040
+ value,
31041
+ ...value
31042
+ });
31043
+ }
30688
31044
  if (path === "checkin/now") {
30689
31045
  if (method !== "POST") return sendMethodNotAllowed$3(response);
30690
31046
  if (!isSameOriginMutation(request)) return sendCrossOrigin$1(response);
@@ -30811,6 +31167,10 @@ function registerMinimaxCodeRoutes(ctx, store = new MinimaxCodeCredentialStore()
30811
31167
  ok: false,
30812
31168
  error: error.message
30813
31169
  });
31170
+ if (error instanceof MinimaxCodeResetCardError) return sendJson$3(response, resetCardHttpStatus(error), {
31171
+ ok: false,
31172
+ error: error.message
31173
+ });
30814
31174
  return sendJson$3(response, 500, {
30815
31175
  ok: false,
30816
31176
  error: error instanceof Error ? error.message : String(error)
@@ -34928,7 +35288,7 @@ var WorkBuddyAdapter = class extends LlmAdapter {
34928
35288
  ...options,
34929
35289
  reasoningEffort: ReasoningEffortId(effort)
34930
35290
  };
34931
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream(effectiveOptions, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS$2, STREAM_IDLE_TIMEOUT_CODE$2, PROVIDER_NAME$2);
35291
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream(effectiveOptions, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS$2, STREAM_IDLE_TIMEOUT_CODE$2, PROVIDER_NAME$2);
34932
35292
  }
34933
35293
  /**
34934
35294
  * Effort this request should carry, or `undefined` to send none.
@@ -34957,7 +35317,7 @@ var WorkBuddyAdapter = class extends LlmAdapter {
34957
35317
  resolveWorkBuddyModel(options.model, catalog).defaultReasoningEffort ?? void 0
34958
35318
  ].find((candidate) => candidate !== void 0 && efforts.includes(candidate));
34959
35319
  }
34960
- async *requestStream(options, signal) {
35320
+ async *requestStream(options, signal, activity) {
34961
35321
  const fetchFn = this.options.fetchFn ?? fetch;
34962
35322
  const requestOptions = offloadOldestRequestImages$1(normalizeGenerateOptions(options));
34963
35323
  const images = await resolveRequestImages$1(requestOptions, this.options.attachments, signal);
@@ -35027,10 +35387,12 @@ var WorkBuddyAdapter = class extends LlmAdapter {
35027
35387
  while (true) {
35028
35388
  const { done, value } = await reader.read();
35029
35389
  if (done) break;
35390
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
35030
35391
  buffer += decoder.decode(value, { stream: true });
35031
35392
  const lines = buffer.split("\n");
35032
35393
  buffer = lines.pop() ?? "";
35033
35394
  for (const line of lines) {
35395
+ activity?.pulse();
35034
35396
  for (const chunk of processStreamLine$2(line, state)) yield chunk;
35035
35397
  if (state.finished) return;
35036
35398
  }
@@ -41370,7 +41732,7 @@ var ClaudeAdapter = class ClaudeAdapter extends LlmAdapter {
41370
41732
  };
41371
41733
  }
41372
41734
  async *stream(options) {
41373
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream(options, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS$1, STREAM_IDLE_TIMEOUT_CODE$1, PROVIDER_NAME);
41735
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream(options, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS$1, STREAM_IDLE_TIMEOUT_CODE$1, PROVIDER_NAME);
41374
41736
  }
41375
41737
  /**
41376
41738
  * Read one credential for this attempt.
@@ -41463,7 +41825,7 @@ var ClaudeAdapter = class ClaudeAdapter extends LlmAdapter {
41463
41825
  throw toLlmError(networkFailure(error));
41464
41826
  }
41465
41827
  }
41466
- async *requestStream(options, signal) {
41828
+ async *requestStream(options, signal, activity) {
41467
41829
  const fetchFn = this.options.fetchFn ?? fetch;
41468
41830
  const requestOptions = offloadOldestRequestImages(normalizeGenerateOptions(options));
41469
41831
  const images = await resolveRequestImages(requestOptions, this.options.attachments, signal);
@@ -41524,10 +41886,12 @@ var ClaudeAdapter = class ClaudeAdapter extends LlmAdapter {
41524
41886
  while (true) {
41525
41887
  const { done, value } = await reader.read();
41526
41888
  if (done) break;
41889
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
41527
41890
  buffer += decoder.decode(value, { stream: true });
41528
41891
  const lines = buffer.split("\n");
41529
41892
  buffer = lines.pop() ?? "";
41530
41893
  for (const line of lines) {
41894
+ if (line.trim() !== "") activity?.pulse();
41531
41895
  for (const chunk of processStreamLine$1(line, state)) {
41532
41896
  outputStarted = true;
41533
41897
  yield chunk;
@@ -48737,7 +49101,7 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
48737
49101
  };
48738
49102
  }
48739
49103
  async *stream(options) {
48740
- yield* wrapStreamWithWatchdog((watchdogSignal) => this.requestStream(options, watchdogSignal), options.signal, STREAM_IDLE_TIMEOUT_MS, STREAM_IDLE_TIMEOUT_CODE, PROVIDER_NAME$1);
49104
+ yield* wrapStreamWithWatchdog((watchdogSignal, activity) => this.requestStream(options, watchdogSignal, activity), options.signal, STREAM_IDLE_TIMEOUT_MS, STREAM_IDLE_TIMEOUT_CODE, PROVIDER_NAME$1);
48741
49105
  }
48742
49106
  /**
48743
49107
  * 一次请求的完整往返:选账号 → 定协议面 → 发 → 解析流。
@@ -48745,7 +49109,7 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
48745
49109
  * 账号轮转的循环只有一处:一次 429 或一次 AUTH 会把那个账号移出本次请求,
48746
49110
  * 由另一个账号来发**同一份**请求体。没有池时这个循环只跑一次。
48747
49111
  */
48748
- async *requestStream(options, signal) {
49112
+ async *requestStream(options, signal, activity) {
48749
49113
  const fetchFn = this.options.fetchFn ?? fetch;
48750
49114
  await this.settings();
48751
49115
  const requestOptions = offloadOldestRequestImages$2(normalizeGenerateOptions(options));
@@ -48830,10 +49194,12 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
48830
49194
  while (true) {
48831
49195
  const { done, value } = await reader.read();
48832
49196
  if (done) break;
49197
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
48833
49198
  buffer += decoder.decode(value, { stream: true });
48834
49199
  const lines = buffer.split("\n");
48835
49200
  buffer = lines.pop() ?? "";
48836
49201
  for (const line of lines) {
49202
+ activity?.pulse();
48837
49203
  for (const chunk of processGlmAnthropicStreamLine(line, state)) yield chunk;
48838
49204
  if (state.finished) return;
48839
49205
  }
@@ -48854,10 +49220,12 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
48854
49220
  while (true) {
48855
49221
  const { done, value } = await reader.read();
48856
49222
  if (done) break;
49223
+ if (value !== void 0 && value.byteLength > 0) activity?.pulse();
48857
49224
  buffer += decoder.decode(value, { stream: true });
48858
49225
  const lines = buffer.split("\n");
48859
49226
  buffer = lines.pop() ?? "";
48860
49227
  for (const line of lines) {
49228
+ activity?.pulse();
48861
49229
  for (const chunk of processStreamLine(line, state)) yield chunk;
48862
49230
  if (state.finished) return;
48863
49231
  }
@@ -53686,7 +54054,8 @@ const Config = z.object({
53686
54054
  subagentModelTools: z.array(z.string()).default([]),
53687
54055
  subagentModelInheritTools: z.array(z.string()).default(DEFAULT_SUBAGENT_INHERIT_TOOLS),
53688
54056
  subagentModelScope: z.union([z.const("session"), z.const("preference")]).default("session"),
53689
- reasoningCollapseGuard: z.union([z.object({}), z.const(false)]).default({})
54057
+ reasoningCollapseGuard: z.union([z.object({}), z.const(false)]).default({}),
54058
+ codexStreamIdleTimeoutMs: z.number().min(1).max(MAX_TIMER_DELAY_MS).step(1).default(DEFAULT_STREAM_IDLE_TIMEOUT_MS)
53690
54059
  });
53691
54060
  const inject = [
53692
54061
  "webServer",
@@ -53969,7 +54338,8 @@ function apply(ctx, pluginConfig = {}) {
53969
54338
  onGenerationFinished: () => usage.invalidate(),
53970
54339
  outputVerbosity: () => preferences.status().outputVerbosity,
53971
54340
  fastMode: () => preferences.status().fastMode,
53972
- reasoningSummary: () => preferences.status().reasoningSummary
54341
+ reasoningSummary: () => preferences.status().reasoningSummary,
54342
+ codexStreamIdleTimeoutMs: pluginConfig.codexStreamIdleTimeoutMs
53973
54343
  }), preferences, (options) => oauth.credentials(void 0, { purpose: "tool" }).then((credentials) => loadCodexCatalog(credentials, {
53974
54344
  fetchFn: proxyFetch,
53975
54345
  signal: options?.signal