@eddyskywalker/dsh-chatgpt-subscription 0.3.8 → 0.4.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 (59) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/lib/client.js +386 -99
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +853 -119
  5. package/lib/types/client/CodexSubscriptionSection.d.ts.map +1 -1
  6. package/lib/types/client/antigravity/AntigravitySection.d.ts.map +1 -1
  7. package/lib/types/client/antigravity/locales.d.ts +78 -0
  8. package/lib/types/client/antigravity/locales.d.ts.map +1 -1
  9. package/lib/types/client/antigravity/styles.d.ts.map +1 -1
  10. package/lib/types/client/command-code/CommandCodeSection.d.ts.map +1 -1
  11. package/lib/types/client/command-code/locales.d.ts +12 -6
  12. package/lib/types/client/command-code/locales.d.ts.map +1 -1
  13. package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
  14. package/lib/types/client/kimi-code/locales.d.ts +12 -6
  15. package/lib/types/client/kimi-code/locales.d.ts.map +1 -1
  16. package/lib/types/client/locales.d.ts +9 -3
  17. package/lib/types/client/locales.d.ts.map +1 -1
  18. package/lib/types/host/antigravity/account-pool.d.ts +50 -0
  19. package/lib/types/host/antigravity/account-pool.d.ts.map +1 -0
  20. package/lib/types/host/antigravity/adapter.d.ts +3 -1
  21. package/lib/types/host/antigravity/adapter.d.ts.map +1 -1
  22. package/lib/types/host/antigravity/mapper.d.ts +1 -0
  23. package/lib/types/host/antigravity/mapper.d.ts.map +1 -1
  24. package/lib/types/host/antigravity/oauth.d.ts +1 -1
  25. package/lib/types/host/antigravity/oauth.d.ts.map +1 -1
  26. package/lib/types/host/antigravity/routes.d.ts +3 -2
  27. package/lib/types/host/antigravity/routes.d.ts.map +1 -1
  28. package/lib/types/host/antigravity/token-store.d.ts +3 -0
  29. package/lib/types/host/antigravity/token-store.d.ts.map +1 -1
  30. package/lib/types/host/antigravity/types.d.ts +2 -1
  31. package/lib/types/host/antigravity/types.d.ts.map +1 -1
  32. package/lib/types/host/command-code/adapter.d.ts.map +1 -1
  33. package/lib/types/host/command-code/mapper.d.ts.map +1 -1
  34. package/lib/types/host/command-code/routes.d.ts +1 -1
  35. package/lib/types/host/command-code/routes.d.ts.map +1 -1
  36. package/lib/types/host/command-code/token-store.d.ts +3 -0
  37. package/lib/types/host/command-code/token-store.d.ts.map +1 -1
  38. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  39. package/lib/types/host/kimi-code/mapper.d.ts +9 -4
  40. package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
  41. package/lib/types/host/kimi-code/routes.d.ts +1 -1
  42. package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
  43. package/lib/types/host/kimi-code/token-store.d.ts +3 -0
  44. package/lib/types/host/kimi-code/token-store.d.ts.map +1 -1
  45. package/lib/types/host/model-catalog.d.ts.map +1 -1
  46. package/lib/types/host/preferences.d.ts.map +1 -1
  47. package/lib/types/host/token-store-windows.d.ts.map +1 -1
  48. package/lib/types/index.d.ts +1 -0
  49. package/lib/types/index.d.ts.map +1 -1
  50. package/lib/types/shared/antigravity-contracts.d.ts +18 -0
  51. package/lib/types/shared/antigravity-contracts.d.ts.map +1 -1
  52. package/lib/types/shared/command-code-contracts.d.ts +2 -0
  53. package/lib/types/shared/command-code-contracts.d.ts.map +1 -1
  54. package/lib/types/shared/contracts.d.ts +2 -0
  55. package/lib/types/shared/contracts.d.ts.map +1 -1
  56. package/lib/types/shared/kimi-code-contracts.d.ts +2 -0
  57. package/lib/types/shared/kimi-code-contracts.d.ts.map +1 -1
  58. package/lib/types/shared/preferences.d.ts.map +1 -1
  59. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -192,7 +192,9 @@ function resolveCodexFallbackModel(model) {
192
192
  const PROVIDER_ID$3 = CODEX_CHATGPT_PROVIDER_ID;
193
193
  const PROVIDER_NAME$3 = "Codex(ChatGPT 订阅)";
194
194
  function listCodexModels(preferences) {
195
- const visible = new Set(preferences?.status().visibleModelIds ?? CODEX_MODEL_CATALOG.map((entry) => entry.id));
195
+ const status = preferences?.status();
196
+ if (status?.enabled === false) return [];
197
+ const visible = new Set(status?.visibleModelIds ?? CODEX_MODEL_CATALOG.map((entry) => entry.id));
196
198
  return CODEX_MODEL_CATALOG.filter((entry) => visible.has(entry.id)).map((entry) => ({
197
199
  provider: PROVIDER_ID$3,
198
200
  id: entry.id,
@@ -1597,6 +1599,7 @@ var ProxyManager = class {
1597
1599
  //#region src/shared/preferences.ts
1598
1600
  const PREFERENCES_NAMESPACE = "dsh-chatgpt-subscription";
1599
1601
  const DEFAULT_PREFERENCES = {
1602
+ enabled: true,
1600
1603
  quickQuotaVisible: false,
1601
1604
  fastMode: false,
1602
1605
  outputVerbosity: null,
@@ -1630,6 +1633,7 @@ function isProxyMode(value) {
1630
1633
  function registerPreferenceStore(settings) {
1631
1634
  const ns = SettingsModule.settingsNamespace ? SettingsModule.settingsNamespace(PREFERENCES_NAMESPACE) : PREFERENCES_NAMESPACE;
1632
1635
  return new SettingsPreferenceStore(settings.register.call(settings, ns, z.object({
1636
+ enabled: z.boolean().default(DEFAULT_PREFERENCES.enabled ?? true),
1633
1637
  quickQuotaVisible: z.boolean().default(DEFAULT_PREFERENCES.quickQuotaVisible),
1634
1638
  fastMode: z.boolean().default(DEFAULT_PREFERENCES.fastMode),
1635
1639
  outputVerbosity: z.union([
@@ -1671,6 +1675,7 @@ var SettingsPreferenceStore = class {
1671
1675
  }
1672
1676
  async update(patch) {
1673
1677
  const normalized = {};
1678
+ if (patch.enabled !== void 0) normalized.enabled = patch.enabled;
1674
1679
  if (patch.quickQuotaVisible !== void 0) normalized.quickQuotaVisible = patch.quickQuotaVisible;
1675
1680
  if (patch.fastMode !== void 0) normalized.fastMode = patch.fastMode;
1676
1681
  if (patch.outputVerbosity !== void 0) {
@@ -1682,7 +1687,7 @@ var SettingsPreferenceStore = class {
1682
1687
  normalized.reasoningSummary = patch.reasoningSummary;
1683
1688
  }
1684
1689
  if (patch.visibleModelIds !== void 0) {
1685
- if (patch.visibleModelIds.length === 0 || !patch.visibleModelIds.every(isCodexModelId)) throw new PreferenceError("At least one supported Codex model must be visible.");
1690
+ if (!patch.visibleModelIds.every(isCodexModelId)) throw new PreferenceError("Unsupported Codex model.");
1686
1691
  normalized.visibleModelIds = [...new Set(patch.visibleModelIds)];
1687
1692
  }
1688
1693
  if (patch.searchProvider !== void 0) {
@@ -1899,7 +1904,7 @@ async function buildResponsesPayload(options, attachments, localRawImages = {},
1899
1904
  const instructionParts = [
1900
1905
  options.system?.trim(),
1901
1906
  latestSystemPrompt(options.messages),
1902
- progressExplanationInstruction(options.tools),
1907
+ progressExplanationInstruction$1(options.tools),
1903
1908
  sandboxToolInstruction(options.tools, sandboxRetryTools),
1904
1909
  commandToolInstruction(options.tools),
1905
1910
  runCodeInstruction(options.tools)
@@ -1985,7 +1990,7 @@ async function buildResponsesPayload(options, attachments, localRawImages = {},
1985
1990
  }
1986
1991
  return payload;
1987
1992
  }
1988
- function progressExplanationInstruction(tools) {
1993
+ function progressExplanationInstruction$1(tools) {
1989
1994
  if (!tools?.length) return void 0;
1990
1995
  return "Progress and tool execution rule: when executing multi-step tasks or invoking tools, output 1-2 concise sentences of progress, intent, or intermediate findings before each tool call. Keep progress text brief, professional, and factual. Only present the comprehensive final answer and summary in the final turn after all tool operations are completed.";
1991
1996
  }
@@ -3435,8 +3440,12 @@ function isRecord$6(value) {
3435
3440
  }
3436
3441
  function readPreferencesUpdate(value, current) {
3437
3442
  const patch = {};
3443
+ if ("enabled" in value) {
3444
+ if (typeof value.enabled !== "boolean") throw new PreferenceError("enabled must be a boolean.");
3445
+ patch.enabled = value.enabled;
3446
+ }
3438
3447
  if ("visibleModelIds" in value) {
3439
- if (!Array.isArray(value.visibleModelIds) || value.visibleModelIds.length === 0 || !value.visibleModelIds.every(isCodexModelId)) throw new PreferenceError("visibleModelIds must contain at least one supported Codex model.");
3448
+ if (!Array.isArray(value.visibleModelIds) || !value.visibleModelIds.every(isCodexModelId)) throw new PreferenceError("visibleModelIds must be an array of supported Codex models.");
3440
3449
  patch.visibleModelIds = [...new Set(value.visibleModelIds)];
3441
3450
  }
3442
3451
  if ("quickQuotaVisible" in value) {
@@ -3730,6 +3739,9 @@ function isMissing(error) {
3730
3739
  //#region src/host/token-store-windows.ts
3731
3740
  const PROTECT_SCRIPT = String.raw`
3732
3741
  $ErrorActionPreference = 'Stop'
3742
+ [Console]::InputEncoding = [Text.Encoding]::UTF8
3743
+ [Console]::OutputEncoding = [Text.Encoding]::UTF8
3744
+ $OutputEncoding = [Text.Encoding]::UTF8
3733
3745
  Add-Type -AssemblyName System.Security
3734
3746
  $path = $env:DSH_CODEX_TOKEN_PATH
3735
3747
  $plain = [Console]::In.ReadToEnd()
@@ -3751,6 +3763,9 @@ try {
3751
3763
  `;
3752
3764
  const UNPROTECT_SCRIPT = String.raw`
3753
3765
  $ErrorActionPreference = 'Stop'
3766
+ [Console]::InputEncoding = [Text.Encoding]::UTF8
3767
+ [Console]::OutputEncoding = [Text.Encoding]::UTF8
3768
+ $OutputEncoding = [Text.Encoding]::UTF8
3754
3769
  Add-Type -AssemblyName System.Security
3755
3770
  $path = $env:DSH_CODEX_TOKEN_PATH
3756
3771
  if (-not [IO.File]::Exists($path)) { exit 3 }
@@ -3965,7 +3980,8 @@ const SCOPES = [
3965
3980
  const DEFAULT_CLIENT_ID = Buffer.from("MTA3MTAwNjA2MDU5MS10bWhzc2luMmgyMWxjcmUyMzV2dG9sb2poNGc0MDNlcC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbQ==", "base64").toString("utf8");
3966
3981
  const DEFAULT_CLIENT_SECRET = Buffer.from("R09DU1BYLUs1OEZXUjQ4NkxkTEoxbUxCOHNYQzR6NnFEQWY=", "base64").toString("utf8");
3967
3982
  const ANTIGRAVITY_SYSTEM_INSTRUCTION = "You are Antigravity, a powerful agentic AI coding assistant designed by Google DeepMind. You are pair programming with a user to solve coding tasks. Be concise, practical, and tool-aware.";
3968
- const ANTIGRAVITY_NO_PREAMBLE_INSTRUCTION = "CRITICAL: NEVER output rule checks, formatting guidelines, constraint checklists, or thinking/personality preambles in the final response. Output only the final response.";
3983
+ const ANTIGRAVITY_NO_PREAMBLE_INSTRUCTION = "CRITICAL: NEVER output rule checks, formatting guidelines, constraint checklists, or thinking/personality preambles in the final response. Output only the final response. This forbids meta commentary only; it does not forbid the short progress lines the next rule requires before tool calls.";
3984
+ const ANTIGRAVITY_PROGRESS_INSTRUCTION = "Progress and tool execution rule: before EVERY tool call, emit 1-2 short sentences of ordinary, visible assistant text stating what you are about to do and why, written as normal response text the user can read. Never write those sentences only inside your thinking/thought summary: the visible text part must exist, otherwise the progress is not delivered. These progress lines are required and take precedence over the no-preamble rule. Keep them brief, professional, and factual; do not restate the whole plan. Only present the comprehensive final answer and summary in the final turn, after all tool operations are completed.";
3969
3985
  const GEMINI_ROLE = {
3970
3986
  user: "user",
3971
3987
  model: "model"
@@ -4357,6 +4373,7 @@ const ANTIGRAVITY_PREFERENCES_NAMESPACE = "dsh-antigravity";
4357
4373
  function registerAntigravityPreferenceStore(settings, fallbackStore = new FileModelSettingsStore$1()) {
4358
4374
  if (!settings) return {
4359
4375
  status: () => ({
4376
+ enabled: true,
4360
4377
  enabledModelIds: MODELS.map((m) => m.id),
4361
4378
  catalogModels: [],
4362
4379
  contextWindowOverrides: {},
@@ -4366,6 +4383,7 @@ function registerAntigravityPreferenceStore(settings, fallbackStore = new FileMo
4366
4383
  };
4367
4384
  const ns = SettingsModule.settingsNamespace ? SettingsModule.settingsNamespace(ANTIGRAVITY_PREFERENCES_NAMESPACE) : ANTIGRAVITY_PREFERENCES_NAMESPACE;
4368
4385
  const scope = settings.register.call(settings, ns, z.object({
4386
+ enabled: z.boolean().default(true),
4369
4387
  enabledModelIds: z.array(z.string()).default(MODELS.map((m) => m.id)),
4370
4388
  contextWindowOverrides: z.dict(z.number()).default({}),
4371
4389
  defaultReasoningEffort: z.union([
@@ -4379,6 +4397,7 @@ function registerAntigravityPreferenceStore(settings, fallbackStore = new FileMo
4379
4397
  status: () => {
4380
4398
  const val = scope.get();
4381
4399
  return {
4400
+ enabled: val.enabled !== false,
4382
4401
  enabledModelIds: val.enabledModelIds,
4383
4402
  catalogModels: [],
4384
4403
  contextWindowOverrides: val.contextWindowOverrides,
@@ -4388,6 +4407,7 @@ function registerAntigravityPreferenceStore(settings, fallbackStore = new FileMo
4388
4407
  update: async (patch) => {
4389
4408
  const current = scope.get();
4390
4409
  const normalized = {
4410
+ enabled: patch.enabled !== void 0 ? patch.enabled : current.enabled !== false,
4391
4411
  enabledModelIds: patch.enabledModelIds ?? current.enabledModelIds,
4392
4412
  contextWindowOverrides: patch.contextWindowOverrides ? {
4393
4413
  ...current.contextWindowOverrides,
@@ -4533,15 +4553,21 @@ var FileModelSettingsStore$1 = class {
4533
4553
  const parsed = JSON.parse(content);
4534
4554
  if (typeof parsed === "object" && parsed !== null) {
4535
4555
  const record = parsed;
4556
+ const enabledModelIds = Array.isArray(record.enabledModelIds) ? record.enabledModelIds.filter((id) => typeof id === "string") : MODELS.map((m) => m.id);
4557
+ const catalogModels = Array.isArray(record.catalogModels) ? record.catalogModels : [];
4558
+ const contextWindowOverrides = typeof record.contextWindowOverrides === "object" && record.contextWindowOverrides !== null ? record.contextWindowOverrides : {};
4559
+ const defaultReasoningEffort = record.defaultReasoningEffort === "low" || record.defaultReasoningEffort === "medium" || record.defaultReasoningEffort === "high" ? record.defaultReasoningEffort : null;
4536
4560
  return {
4537
- enabledModelIds: Array.isArray(record.enabledModelIds) ? record.enabledModelIds.filter((id) => typeof id === "string") : MODELS.map((m) => m.id),
4538
- catalogModels: Array.isArray(record.catalogModels) ? record.catalogModels : [],
4539
- contextWindowOverrides: typeof record.contextWindowOverrides === "object" && record.contextWindowOverrides !== null ? record.contextWindowOverrides : {},
4540
- defaultReasoningEffort: record.defaultReasoningEffort === "low" || record.defaultReasoningEffort === "medium" || record.defaultReasoningEffort === "high" ? record.defaultReasoningEffort : null
4561
+ enabled: record.enabled !== false,
4562
+ enabledModelIds,
4563
+ catalogModels,
4564
+ contextWindowOverrides,
4565
+ defaultReasoningEffort
4541
4566
  };
4542
4567
  }
4543
4568
  } catch {}
4544
4569
  return {
4570
+ enabled: true,
4545
4571
  enabledModelIds: MODELS.map((m) => m.id),
4546
4572
  catalogModels: [],
4547
4573
  contextWindowOverrides: {},
@@ -4558,6 +4584,7 @@ var FileModelSettingsStore$1 = class {
4558
4584
  const current = await this.read();
4559
4585
  const next = {
4560
4586
  ...current,
4587
+ ...patch.enabled !== void 0 ? { enabled: patch.enabled } : {},
4561
4588
  ...patch.enabledModelIds !== void 0 ? { enabledModelIds: patch.enabledModelIds } : {},
4562
4589
  ...patch.contextWindowOverrides !== void 0 ? { contextWindowOverrides: {
4563
4590
  ...current.contextWindowOverrides || {},
@@ -5064,7 +5091,7 @@ async function exchangeOAuthCode(code, verifier, callbackUrl, fetchFn = fetch, s
5064
5091
  email
5065
5092
  };
5066
5093
  }
5067
- async function beginWebLogin$1(store, fetchFn = fetch, signal) {
5094
+ async function beginWebLogin$1(store, fetchFn = fetch, signal, onSave) {
5068
5095
  if (webLoginFlow$2.status === "pending") return { ...webLoginFlow$2 };
5069
5096
  const { verifier, challenge } = generatePKCE();
5070
5097
  const state = base64Url(randomBytes(32));
@@ -5096,6 +5123,7 @@ async function beginWebLogin$1(store, fetchFn = fetch, signal) {
5096
5123
  webLoginFlow$2.progress = stage;
5097
5124
  });
5098
5125
  await store.write(credentials);
5126
+ if (onSave) await onSave(credentials).catch(() => void 0);
5099
5127
  webLoginFlow$2.status = "complete";
5100
5128
  webLoginFlow$2.email = credentials.email;
5101
5129
  webLoginFlow$2.completedAt = Date.now();
@@ -5316,9 +5344,13 @@ function attachmentLabel$2(block) {
5316
5344
  function collectImageRefs$2(content, refs) {
5317
5345
  if (!Array.isArray(content)) return;
5318
5346
  for (const block of content) {
5319
- if (!isRecord$4(block) || block.type !== "image") continue;
5320
- const attachment = attachmentOf$2(block);
5321
- if (attachment) refs.set(attachment.attachmentId, attachment);
5347
+ if (!isRecord$4(block)) continue;
5348
+ if (block.type === "image") {
5349
+ const attachment = attachmentOf$2(block);
5350
+ if (attachment) refs.set(attachment.attachmentId, attachment);
5351
+ continue;
5352
+ }
5353
+ if (block.type === "tool-result") collectImageRefs$2(block.content, refs);
5322
5354
  }
5323
5355
  }
5324
5356
  function isAbort$2(error, signal) {
@@ -5487,6 +5519,24 @@ function contentToUserParts(content, images) {
5487
5519
  }
5488
5520
  return parts;
5489
5521
  }
5522
+ /**
5523
+ * Image parts for one tool result, flattened the same way so a nested
5524
+ * `tool-result` cannot hide one. Gemini's `functionResponse` has nowhere to put
5525
+ * an image, so these become `inlineData` siblings on the same user content.
5526
+ */
5527
+ function toolResultImageParts(blocks, images) {
5528
+ if (!Array.isArray(blocks)) return [];
5529
+ const parts = [];
5530
+ for (const block of blocks) {
5531
+ if (!isRecord$4(block)) continue;
5532
+ if (block.type === "image") {
5533
+ parts.push(imageBlockToPart(block, images) ?? { text: unavailableImageText$2(block) });
5534
+ continue;
5535
+ }
5536
+ if (block.type === "tool-result") parts.push(...toolResultImageParts(block.content, images));
5537
+ }
5538
+ return parts;
5539
+ }
5490
5540
  function toolResultText$2(blocks) {
5491
5541
  if (!Array.isArray(blocks)) return "";
5492
5542
  return blocks.map((block) => {
@@ -5572,7 +5622,7 @@ function assistantParts(message, model, runtimeModel, toolCalls) {
5572
5622
  }
5573
5623
  return parts;
5574
5624
  }
5575
- function pushToolResult(contents, result, toolCalls, model, runtimeModel) {
5625
+ function pushToolResult(contents, result, toolCalls, model, runtimeModel, images = NO_RESOLVED_IMAGES$2) {
5576
5626
  const toolCallId = String(result.toolCallId || "");
5577
5627
  const call = toolCalls.get(toolCallId);
5578
5628
  const toolName = call?.name || "unknown";
@@ -5583,11 +5633,12 @@ function pushToolResult(contents, result, toolCalls, model, runtimeModel) {
5583
5633
  response: result.isError ? { error: responseText } : { output: responseText },
5584
5634
  ...wireId ? { id: wireId } : {}
5585
5635
  } };
5636
+ const extraParts = toolResultImageParts(result.content, images);
5586
5637
  const last = contents[contents.length - 1];
5587
- if (last?.role === GEMINI_ROLE.user && last.parts.some((entry) => "functionResponse" in entry)) last.parts.push(part);
5638
+ if (last?.role === GEMINI_ROLE.user && last.parts.some((entry) => "functionResponse" in entry)) last.parts.push(part, ...extraParts);
5588
5639
  else contents.push({
5589
5640
  role: GEMINI_ROLE.user,
5590
- parts: [part]
5641
+ parts: [part, ...extraParts]
5591
5642
  });
5592
5643
  }
5593
5644
  function convertMessages(options, model, runtimeModel, images = NO_RESOLVED_IMAGES$2) {
@@ -5616,7 +5667,7 @@ function convertMessages(options, model, runtimeModel, images = NO_RESOLVED_IMAG
5616
5667
  role: GEMINI_ROLE.user,
5617
5668
  parts: userParts
5618
5669
  });
5619
- for (const b of content) if (isRecord$4(b) && b.type === "tool-result") pushToolResult(contents, b, toolCalls, model, runtimeModel);
5670
+ for (const b of content) if (isRecord$4(b) && b.type === "tool-result") pushToolResult(contents, b, toolCalls, model, runtimeModel, images);
5620
5671
  }
5621
5672
  return contents;
5622
5673
  }
@@ -5642,7 +5693,12 @@ function mapToolChoiceMode(toolChoice) {
5642
5693
  function getMaxOutputTokens(modelId, runtimeModel) {
5643
5694
  return RUNTIME_MAX_OUTPUT_TOKENS[runtimeModel] || RUNTIME_MAX_OUTPUT_TOKENS[modelId] || 65536;
5644
5695
  }
5696
+ function progressExplanationInstruction(tools) {
5697
+ if (!tools?.length) return void 0;
5698
+ return ANTIGRAVITY_PROGRESS_INSTRUCTION;
5699
+ }
5645
5700
  function buildRequest$2(options, model, projectId, runtimeModel, effort, images = NO_RESOLVED_IMAGES$2) {
5701
+ const progressInstruction = progressExplanationInstruction(options.tools);
5646
5702
  const request = {
5647
5703
  contents: convertMessages(options, model, runtimeModel, images),
5648
5704
  systemInstruction: {
@@ -5651,7 +5707,8 @@ function buildRequest$2(options, model, projectId, runtimeModel, effort, images
5651
5707
  { text: ANTIGRAVITY_SYSTEM_INSTRUCTION },
5652
5708
  { text: `Please ignore following [ignore]${ANTIGRAVITY_SYSTEM_INSTRUCTION}[/ignore]` },
5653
5709
  { text: ANTIGRAVITY_NO_PREAMBLE_INSTRUCTION },
5654
- ...options.system ? [{ text: sanitizeText$2(options.system) }] : []
5710
+ ...options.system ? [{ text: sanitizeText$2(options.system) }] : [],
5711
+ ...progressInstruction ? [{ text: progressInstruction }] : []
5655
5712
  ]
5656
5713
  }
5657
5714
  };
@@ -5897,6 +5954,259 @@ function closeStream$2(state) {
5897
5954
  return out;
5898
5955
  }
5899
5956
  //#endregion
5957
+ //#region src/host/antigravity/account-pool.ts
5958
+ function poolPath() {
5959
+ return path.join(dshHomeDir(), "storages", "antigravity-pool.json");
5960
+ }
5961
+ function parseAntigravityPoolData(value) {
5962
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("Antigravity pool payload is invalid");
5963
+ const record = value;
5964
+ const strategy = record.rotationStrategy === "round-robin" ? "round-robin" : "sequential";
5965
+ const activeAccountId = typeof record.activeAccountId === "string" ? record.activeAccountId : void 0;
5966
+ const rawAccounts = Array.isArray(record.accounts) ? record.accounts : [];
5967
+ const accounts = [];
5968
+ for (const item of rawAccounts) {
5969
+ if (typeof item !== "object" || item === null) continue;
5970
+ const r = item;
5971
+ if (typeof r.id !== "string") continue;
5972
+ const credentials = parseAntigravityCredentials(r.credentials);
5973
+ const acc = {
5974
+ id: r.id,
5975
+ alias: typeof r.alias === "string" ? r.alias : credentials.email || "账号",
5976
+ credentials,
5977
+ addedAt: typeof r.addedAt === "number" ? r.addedAt : Date.now(),
5978
+ isPrimary: r.isPrimary === true
5979
+ };
5980
+ if (typeof r.email === "string") acc.email = r.email;
5981
+ else if (credentials.email) acc.email = credentials.email;
5982
+ if (typeof r.projectId === "string") acc.projectId = r.projectId;
5983
+ else if (credentials.projectId) acc.projectId = credentials.projectId;
5984
+ if (typeof r.planLabel === "string") acc.planLabel = r.planLabel;
5985
+ if (typeof r.lastUsedAt === "number") acc.lastUsedAt = r.lastUsedAt;
5986
+ if (typeof r.cooldownUntil === "number") acc.cooldownUntil = r.cooldownUntil;
5987
+ if (typeof r.cooldownReason === "string") acc.cooldownReason = r.cooldownReason;
5988
+ accounts.push(acc);
5989
+ }
5990
+ const res = {
5991
+ version: 1,
5992
+ rotationStrategy: strategy,
5993
+ accounts
5994
+ };
5995
+ if (activeAccountId) res.activeAccountId = activeAccountId;
5996
+ return res;
5997
+ }
5998
+ function poolCredentialAccount(filePath) {
5999
+ return createHash("sha256").update(path.resolve(filePath)).digest("hex");
6000
+ }
6001
+ function createPoolCredentialBackend(filePath) {
6002
+ if (process.platform === "win32") return new WindowsDpapiCredentialStore(`${filePath}.dpapi`, parseAntigravityPoolData);
6003
+ if (process.platform === "darwin") return new MacKeychainCredentialStore("dsh-antigravity-pool", poolCredentialAccount(filePath), parseAntigravityPoolData);
6004
+ if (process.platform === "linux") return new SecretServiceCredentialStore("dsh-antigravity-pool", poolCredentialAccount(filePath), parseAntigravityPoolData);
6005
+ throw new Error("Antigravity pool encrypted storage requires Windows, macOS, or Linux.");
6006
+ }
6007
+ const poolOperations = /* @__PURE__ */ new Map();
6008
+ var AccountPoolStore = class {
6009
+ filePath;
6010
+ backend;
6011
+ legacyStore;
6012
+ constructor(filePath = poolPath(), backend = createPoolCredentialBackend(filePath), legacyStore = new FileCredentialStore$1()) {
6013
+ this.filePath = filePath;
6014
+ this.backend = backend;
6015
+ this.legacyStore = legacyStore;
6016
+ }
6017
+ path() {
6018
+ if (process.platform === "win32") return `${this.filePath}.dpapi`;
6019
+ return `${process.platform === "darwin" ? "Keychain" : "Secret Service"}: dsh-antigravity-pool/${poolCredentialAccount(this.filePath)}`;
6020
+ }
6021
+ serialize(operation) {
6022
+ const key = path.resolve(this.filePath);
6023
+ const result = (poolOperations.get(key) || Promise.resolve()).then(operation);
6024
+ const settled = result.then(() => void 0, () => void 0);
6025
+ poolOperations.set(key, settled);
6026
+ settled.then(() => {
6027
+ if (poolOperations.get(key) === settled) poolOperations.delete(key);
6028
+ });
6029
+ return result;
6030
+ }
6031
+ async saveVerified(data) {
6032
+ const normalized = parseAntigravityPoolData(data);
6033
+ await this.backend.save(normalized);
6034
+ if (!isDeepStrictEqual(await this.backend.load(), normalized)) throw new Error("Antigravity pool encrypted verification failed");
6035
+ }
6036
+ read() {
6037
+ return this.serialize(async () => {
6038
+ let current = null;
6039
+ try {
6040
+ current = await this.backend.load();
6041
+ } catch {}
6042
+ if (current !== null && Array.isArray(current.accounts) && current.accounts.length > 0) return current;
6043
+ try {
6044
+ const legacy = await this.legacyStore.read();
6045
+ if (legacy && (legacy.access || legacy.access_token || legacy.refresh || legacy.refresh_token)) {
6046
+ const defaultAccount = {
6047
+ id: "acc_primary",
6048
+ alias: legacy.email || "主账号",
6049
+ email: legacy.email,
6050
+ projectId: legacy.projectId,
6051
+ credentials: legacy,
6052
+ addedAt: Date.now(),
6053
+ isPrimary: true
6054
+ };
6055
+ return {
6056
+ version: 1,
6057
+ activeAccountId: "acc_primary",
6058
+ rotationStrategy: current?.rotationStrategy || "sequential",
6059
+ accounts: [defaultAccount]
6060
+ };
6061
+ }
6062
+ } catch {}
6063
+ return current || {
6064
+ version: 1,
6065
+ rotationStrategy: "sequential",
6066
+ accounts: []
6067
+ };
6068
+ });
6069
+ }
6070
+ write(data) {
6071
+ return this.serialize(() => this.saveVerified(parseAntigravityPoolData(data)));
6072
+ }
6073
+ async listAccounts() {
6074
+ const data = await this.read();
6075
+ const now = Date.now();
6076
+ return data.accounts.map((acc) => {
6077
+ const expires = acc.credentials.expires || acc.credentials.expires_at;
6078
+ return {
6079
+ id: acc.id,
6080
+ alias: acc.alias,
6081
+ email: acc.email,
6082
+ projectId: acc.projectId,
6083
+ planLabel: acc.planLabel,
6084
+ isPrimary: acc.isPrimary === true,
6085
+ lastUsedAt: acc.lastUsedAt,
6086
+ cooldownUntil: acc.cooldownUntil && acc.cooldownUntil > now ? acc.cooldownUntil : void 0,
6087
+ cooldownReason: acc.cooldownUntil && acc.cooldownUntil > now ? acc.cooldownReason : void 0,
6088
+ expiresAt: expires
6089
+ };
6090
+ });
6091
+ }
6092
+ async addAccount(credentials, alias) {
6093
+ const data = await this.read();
6094
+ const email = credentials.email;
6095
+ const existingIndex = email ? data.accounts.findIndex((a) => a.email === email) : -1;
6096
+ const id = existingIndex >= 0 ? data.accounts[existingIndex].id : `acc_${randomBytes(6).toString("hex")}`;
6097
+ const isPrimary = data.accounts.length === 0 || existingIndex >= 0 && data.accounts[existingIndex].isPrimary;
6098
+ const account = {
6099
+ id,
6100
+ alias: alias?.trim() || email || `账号 ${data.accounts.length + 1}`,
6101
+ email,
6102
+ projectId: credentials.projectId,
6103
+ credentials,
6104
+ addedAt: Date.now(),
6105
+ isPrimary: !!isPrimary
6106
+ };
6107
+ if (existingIndex >= 0) data.accounts[existingIndex] = {
6108
+ ...data.accounts[existingIndex],
6109
+ ...account,
6110
+ isPrimary: data.accounts[existingIndex].isPrimary
6111
+ };
6112
+ else data.accounts.push(account);
6113
+ if (!data.activeAccountId || account.isPrimary) data.activeAccountId = account.id;
6114
+ await this.write(data);
6115
+ if (account.isPrimary) this.legacyStore.write(credentials).catch(() => void 0);
6116
+ return account;
6117
+ }
6118
+ async setPrimary(accountId) {
6119
+ const data = await this.read();
6120
+ for (const a of data.accounts) a.isPrimary = a.id === accountId;
6121
+ const primary = data.accounts.find((a) => a.isPrimary);
6122
+ if (primary) {
6123
+ data.activeAccountId = primary.id;
6124
+ this.legacyStore.write(primary.credentials).catch(() => void 0);
6125
+ }
6126
+ await this.write(data);
6127
+ }
6128
+ async setAlias(accountId, alias) {
6129
+ const data = await this.read();
6130
+ const target = data.accounts.find((a) => a.id === accountId);
6131
+ if (target && alias.trim()) {
6132
+ target.alias = alias.trim();
6133
+ await this.write(data);
6134
+ }
6135
+ }
6136
+ async deleteAccount(accountId) {
6137
+ const data = await this.read();
6138
+ const wasPrimary = data.accounts.find((a) => a.id === accountId)?.isPrimary;
6139
+ data.accounts = data.accounts.filter((a) => a.id !== accountId);
6140
+ if (wasPrimary && data.accounts.length > 0) {
6141
+ data.accounts[0].isPrimary = true;
6142
+ this.legacyStore.write(data.accounts[0].credentials).catch(() => void 0);
6143
+ } else if (data.accounts.length === 0) this.legacyStore.delete().catch(() => void 0);
6144
+ if (data.activeAccountId === accountId) data.activeAccountId = data.accounts.find((a) => a.isPrimary)?.id ?? data.accounts[0]?.id;
6145
+ await this.write(data);
6146
+ }
6147
+ async setStrategy(strategy) {
6148
+ const data = await this.read();
6149
+ data.rotationStrategy = strategy;
6150
+ await this.write(data);
6151
+ }
6152
+ async markCooldown(accountId, durationMs, reason) {
6153
+ const data = await this.read();
6154
+ const target = data.accounts.find((a) => a.id === accountId);
6155
+ if (target) {
6156
+ target.cooldownUntil = Date.now() + Math.max(1e4, durationMs);
6157
+ target.cooldownReason = reason;
6158
+ await this.write(data);
6159
+ }
6160
+ }
6161
+ async clearCooldown(accountId) {
6162
+ const data = await this.read();
6163
+ const target = data.accounts.find((a) => a.id === accountId);
6164
+ if (target) {
6165
+ target.cooldownUntil = void 0;
6166
+ target.cooldownReason = void 0;
6167
+ await this.write(data);
6168
+ }
6169
+ }
6170
+ async hasAnotherAvailableAccount(triedAccountIds) {
6171
+ const data = await this.read();
6172
+ const now = Date.now();
6173
+ return data.accounts.some((a) => !triedAccountIds.has(a.id) && (!a.cooldownUntil || a.cooldownUntil <= now));
6174
+ }
6175
+ async getEffectiveAccount(excludeIds, fetchFn = fetch) {
6176
+ const data = await this.read();
6177
+ if (data.accounts.length === 0) throw new Error("未登录 Antigravity 账号,请在「设置 → Antigravity」中添加并登录账号。");
6178
+ const now = Date.now();
6179
+ const eligible = data.accounts.filter((a) => (!excludeIds || !excludeIds.has(a.id)) && (!a.cooldownUntil || a.cooldownUntil <= now));
6180
+ if (eligible.length === 0) {
6181
+ let shortest = Infinity;
6182
+ for (const a of data.accounts) if (a.cooldownUntil && a.cooldownUntil > now) shortest = Math.min(shortest, a.cooldownUntil - now);
6183
+ const waitMins = Number.isFinite(shortest) ? Math.ceil(shortest / 6e4) : 15;
6184
+ throw new LlmError(`全部 ${data.accounts.length} 个 Antigravity 账号均处于配额限制或冷却中 (429)。最短预计在 ${waitMins} 分钟后解除冷却。`, "RATE_LIMIT", { status: 429 });
6185
+ }
6186
+ let selected;
6187
+ if (data.rotationStrategy === "round-robin") selected = [...eligible].sort((a, b) => (a.lastUsedAt || 0) - (b.lastUsedAt || 0))[0];
6188
+ else selected = eligible.find((a) => a.isPrimary) || eligible[0];
6189
+ const creds = selected.credentials;
6190
+ const expires = creds.expires || creds.expires_at || 0;
6191
+ if (!(creds.access || creds.access_token) || expires <= now + 6e4) {
6192
+ const refreshed = await refreshAntigravityToken(creds, fetchFn);
6193
+ selected.credentials = refreshed;
6194
+ selected.projectId = refreshed.projectId || selected.projectId;
6195
+ const idx = data.accounts.findIndex((a) => a.id === selected.id);
6196
+ if (idx >= 0) data.accounts[idx] = selected;
6197
+ if (selected.isPrimary) this.legacyStore.write(refreshed).catch(() => void 0);
6198
+ }
6199
+ selected.lastUsedAt = now;
6200
+ data.activeAccountId = selected.id;
6201
+ await this.write(data);
6202
+ return {
6203
+ account: selected,
6204
+ token: selected.credentials.access || selected.credentials.access_token,
6205
+ projectId: selected.projectId || selected.credentials.projectId
6206
+ };
6207
+ }
6208
+ };
6209
+ //#endregion
5900
6210
  //#region src/host/antigravity/adapter.ts
5901
6211
  function resolveDefaultReasoningEffort$2(efforts, configuredEffort) {
5902
6212
  if (configuredEffort && efforts.includes(configuredEffort)) return ReasoningEffortId(configuredEffort);
@@ -5909,12 +6219,14 @@ var AntigravityAdapter = class extends LlmAdapter {
5909
6219
  modelSettings;
5910
6220
  preferences;
5911
6221
  options;
5912
- constructor(store = new FileCredentialStore$1(), modelSettings = new FileModelSettingsStore$1(), preferences, options = {}) {
6222
+ accountPool;
6223
+ constructor(store = new FileCredentialStore$1(), modelSettings = new FileModelSettingsStore$1(), preferences, options = {}, accountPool) {
5913
6224
  super();
5914
6225
  this.store = store;
5915
6226
  this.modelSettings = modelSettings;
5916
6227
  this.preferences = preferences;
5917
6228
  this.options = options;
6229
+ this.accountPool = accountPool ?? new AccountPoolStore(void 0, void 0, store);
5918
6230
  }
5919
6231
  providerInfo(provider) {
5920
6232
  return {
@@ -5927,6 +6239,7 @@ var AntigravityAdapter = class extends LlmAdapter {
5927
6239
  async listModels(provider) {
5928
6240
  const prov = provider || "antigravity";
5929
6241
  const settings = this.preferences ? this.preferences.status() : await this.modelSettings.read();
6242
+ if (settings.enabled === false) return [];
5930
6243
  const enabledSet = new Set(settings.enabledModelIds);
5931
6244
  const available = MODELS.filter((m) => enabledSet.has(m.id));
5932
6245
  const overrides = settings.contextWindowOverrides || {};
@@ -5997,8 +6310,6 @@ var AntigravityAdapter = class extends LlmAdapter {
5997
6310
  }
5998
6311
  async *requestStream(options, model, signal) {
5999
6312
  const fetchFn = this.options.fetchFn ?? fetch;
6000
- const { token, projectId: defaultProj } = await ensureApiKey(this.store, fetchFn);
6001
- const projectId = defaultProj || "antigravity-default";
6002
6313
  const effort = String(options.reasoningEffort || "medium").toLowerCase();
6003
6314
  const routing = ROUTING[model.id];
6004
6315
  const initialRuntime = routing?.routing[effort] || routing?.defaultRequestId || model.id;
@@ -6010,26 +6321,54 @@ var AntigravityAdapter = class extends LlmAdapter {
6010
6321
  }
6011
6322
  const requestOptions = offloadOldestRequestImages$2(options);
6012
6323
  const images = await resolveRequestImages$2(requestOptions, this.options.attachments, signal);
6324
+ const triedAccountIds = /* @__PURE__ */ new Set();
6013
6325
  let response;
6014
- for (const runtimeModel of candidates) {
6015
- const body = JSON.stringify(buildRequest$2(requestOptions, model, projectId, runtimeModel, effort, images));
6016
- const headers = {
6017
- ...antigravityHeaders(token),
6018
- ...model.id.startsWith("claude-") ? { "anthropic-beta": "interleaved-thinking-2025-05-14" } : {}
6019
- };
6020
- for (const endpoint of endpointCandidates()) try {
6021
- response = await fetchFn(`${endpoint}/v1internal:streamGenerateContent?alt=sse`, {
6022
- method: "POST",
6023
- headers,
6024
- body,
6025
- signal
6026
- });
6027
- if (response.ok || response.status === 400) break;
6028
- if (response.status === 404) break;
6029
- } catch (err) {
6030
- if (signal.aborted) throw new LlmError("Antigravity request aborted", "ABORTED", { cause: err });
6326
+ while (true) {
6327
+ let eff;
6328
+ try {
6329
+ eff = await this.accountPool.getEffectiveAccount(triedAccountIds, fetchFn);
6330
+ } catch (poolErr) {
6331
+ const poolData = await this.accountPool.read().catch(() => null);
6332
+ if (!poolData || poolData.accounts.length === 0) {
6333
+ const { token, projectId: defaultProj } = await ensureApiKey(this.store, fetchFn);
6334
+ eff = {
6335
+ account: { id: "legacy" },
6336
+ token,
6337
+ projectId: defaultProj
6338
+ };
6339
+ } else throw poolErr;
6031
6340
  }
6032
- if (response && (response.ok || response.status === 400)) break;
6341
+ const { account, token, projectId: defaultProj } = eff;
6342
+ const projectId = defaultProj || "antigravity-default";
6343
+ triedAccountIds.add(account.id);
6344
+ for (const runtimeModel of candidates) {
6345
+ const body = JSON.stringify(buildRequest$2(requestOptions, model, projectId, runtimeModel, effort, images));
6346
+ const headers = {
6347
+ ...antigravityHeaders(token),
6348
+ ...model.id.startsWith("claude-") ? { "anthropic-beta": "interleaved-thinking-2025-05-14" } : {}
6349
+ };
6350
+ for (const endpoint of endpointCandidates()) try {
6351
+ response = await fetchFn(`${endpoint}/v1internal:streamGenerateContent?alt=sse`, {
6352
+ method: "POST",
6353
+ headers,
6354
+ body,
6355
+ signal
6356
+ });
6357
+ if (response.ok || response.status === 400) break;
6358
+ if (response.status === 404) break;
6359
+ } catch (err) {
6360
+ if (signal.aborted) throw new LlmError("Antigravity request aborted", "ABORTED", { cause: err });
6361
+ }
6362
+ if (response && (response.ok || response.status === 400)) break;
6363
+ }
6364
+ if (response && response.status === 429) {
6365
+ const retryAfterHeader = response.headers.get("retry-after");
6366
+ const retryAfterSec = retryAfterHeader ? Number(retryAfterHeader) : NaN;
6367
+ const cooldownMs = Number.isFinite(retryAfterSec) && retryAfterSec > 0 ? retryAfterSec * 1e3 : 900 * 1e3;
6368
+ await this.accountPool.markCooldown(account.id, cooldownMs, "429 Rate Limit");
6369
+ if (await this.accountPool.hasAnotherAvailableAccount(triedAccountIds)) continue;
6370
+ }
6371
+ break;
6033
6372
  }
6034
6373
  if (!response || !response.ok) {
6035
6374
  const status = response?.status ?? 500;
@@ -6097,7 +6436,7 @@ async function readRequestJson$2(request) {
6097
6436
  request.on("error", reject);
6098
6437
  });
6099
6438
  }
6100
- async function getAntigravityWebStatus(store, modelSettings, preferences) {
6439
+ async function getAntigravityWebStatus(store, modelSettings, preferences, accountPool = new AccountPoolStore(void 0, void 0, store)) {
6101
6440
  const credentials = await store.read();
6102
6441
  const settings = preferences ? preferences.status() : await modelSettings.read();
6103
6442
  const quota = getCachedQuota();
@@ -6111,20 +6450,27 @@ async function getAntigravityWebStatus(store, modelSettings, preferences) {
6111
6450
  contextWindow: overrides[m.id] || m.contextWindow,
6112
6451
  reasoningEfforts: m.reasoningEfforts
6113
6452
  }));
6453
+ const accounts = await accountPool.listAccounts().catch(() => []);
6454
+ const poolData = await accountPool.read().catch(() => null);
6455
+ const activeAccount = accounts.find((a) => a.id === poolData?.activeAccountId) || accounts[0];
6114
6456
  return {
6115
- authenticated: !!(credentials?.access || credentials?.access_token),
6116
- email: credentials?.email,
6117
- projectId: credentials?.projectId,
6118
- hasCredentials: !!credentials,
6457
+ enabled: settings.enabled !== false,
6458
+ authenticated: accounts.length > 0 || !!(credentials?.access || credentials?.access_token),
6459
+ email: activeAccount?.email || credentials?.email,
6460
+ projectId: activeAccount?.projectId || credentials?.projectId,
6461
+ hasCredentials: accounts.length > 0 || !!credentials,
6119
6462
  storagePath: store.path(),
6120
6463
  lastFetchedAt: quota?.fetchedAt,
6121
6464
  quota,
6122
6465
  models,
6123
6466
  contextWindowOverrides: overrides,
6124
- defaultReasoningEffort: settings.defaultReasoningEffort || null
6467
+ defaultReasoningEffort: settings.defaultReasoningEffort || null,
6468
+ accounts,
6469
+ activeAccountId: poolData?.activeAccountId || activeAccount?.id,
6470
+ rotationStrategy: poolData?.rotationStrategy || "sequential"
6125
6471
  };
6126
6472
  }
6127
- function registerAntigravityRoutes(ctx, store, modelSettings, preferences, fetchFn = fetch) {
6473
+ function registerAntigravityRoutes(ctx, store, modelSettings, preferences, fetchFn = fetch, accountPool = new AccountPoolStore(void 0, void 0, store)) {
6128
6474
  return ctx.webServer.register({
6129
6475
  kind: "prefix",
6130
6476
  path: "/antigravity/api",
@@ -6139,14 +6485,16 @@ function registerAntigravityRoutes(ctx, store, modelSettings, preferences, fetch
6139
6485
  if (authenticated && (!cached || Date.now() - (cached.fetchedAt || 0) > 12e4)) await fetchAccountQuota(store, modelSettings, fetchFn).catch(() => void 0);
6140
6486
  return sendJson$3(response, 200, {
6141
6487
  ok: true,
6142
- value: await getAntigravityWebStatus(store, modelSettings, preferences)
6488
+ value: await getAntigravityWebStatus(store, modelSettings, preferences, accountPool)
6143
6489
  });
6144
6490
  }
6145
- if (path === "login") {
6491
+ if (path === "login" || path === "accounts/login") {
6146
6492
  if (request.method !== "POST") return sendMethodNotAllowed$2(response);
6147
6493
  return sendJson$3(response, 200, {
6148
6494
  ok: true,
6149
- value: await beginWebLogin$1(store, fetchFn)
6495
+ value: await beginWebLogin$1(store, fetchFn, void 0, async (creds) => {
6496
+ await accountPool.addAccount(creds);
6497
+ })
6150
6498
  });
6151
6499
  }
6152
6500
  if (path === "login/status") {
@@ -6156,13 +6504,33 @@ function registerAntigravityRoutes(ctx, store, modelSettings, preferences, fetch
6156
6504
  value: getWebLoginStatus$2()
6157
6505
  });
6158
6506
  }
6507
+ if (path === "accounts") {
6508
+ if (request.method === "GET") return sendJson$3(response, 200, {
6509
+ ok: true,
6510
+ value: await accountPool.listAccounts()
6511
+ });
6512
+ if (request.method === "POST") {
6513
+ const body = await readRequestJson$2(request);
6514
+ const action = String(body.action || "");
6515
+ if (action === "set-primary" && typeof body.accountId === "string") await accountPool.setPrimary(body.accountId);
6516
+ else if (action === "set-alias" && typeof body.accountId === "string" && typeof body.alias === "string") await accountPool.setAlias(body.accountId, body.alias);
6517
+ else if (action === "delete" && typeof body.accountId === "string") await accountPool.deleteAccount(body.accountId);
6518
+ else if (action === "strategy" && (body.strategy === "sequential" || body.strategy === "round-robin")) await accountPool.setStrategy(body.strategy);
6519
+ else if (action === "clear-cooldown" && typeof body.accountId === "string") await accountPool.clearCooldown(body.accountId);
6520
+ return sendJson$3(response, 200, {
6521
+ ok: true,
6522
+ value: await getAntigravityWebStatus(store, modelSettings, preferences, accountPool)
6523
+ });
6524
+ }
6525
+ return sendMethodNotAllowed$2(response);
6526
+ }
6159
6527
  if (path === "quota") {
6160
6528
  if (request.method !== "GET" && request.method !== "POST") return sendMethodNotAllowed$2(response);
6161
6529
  const quota = await fetchAccountQuota(store, modelSettings, fetchFn, true);
6162
6530
  return sendJson$3(response, 200, {
6163
6531
  ok: true,
6164
6532
  value: {
6165
- ...await getAntigravityWebStatus(store, modelSettings, preferences),
6533
+ ...await getAntigravityWebStatus(store, modelSettings, preferences, accountPool),
6166
6534
  quota
6167
6535
  }
6168
6536
  });
@@ -6174,32 +6542,39 @@ function registerAntigravityRoutes(ctx, store, modelSettings, preferences, fetch
6174
6542
  else await modelSettings.updateSettings(body);
6175
6543
  return sendJson$3(response, 200, {
6176
6544
  ok: true,
6177
- value: await getAntigravityWebStatus(store, modelSettings, preferences)
6545
+ value: await getAntigravityWebStatus(store, modelSettings, preferences, accountPool)
6178
6546
  });
6179
6547
  }
6180
6548
  if (path === "models") {
6181
6549
  if (request.method === "GET") return sendJson$3(response, 200, {
6182
6550
  ok: true,
6183
- value: (await getAntigravityWebStatus(store, modelSettings, preferences)).models
6551
+ value: (await getAntigravityWebStatus(store, modelSettings, preferences, accountPool)).models
6184
6552
  });
6185
6553
  if (request.method === "POST") {
6186
6554
  const body = await readRequestJson$2(request);
6187
- if (Array.isArray(body.enabledModelIds) || body.contextWindowOverrides || body.defaultReasoningEffort !== void 0) if (preferences) await preferences.update(body);
6555
+ if (Array.isArray(body.enabledModelIds) || body.enabled !== void 0 || body.contextWindowOverrides || body.defaultReasoningEffort !== void 0) if (preferences) await preferences.update(body);
6188
6556
  else await modelSettings.updateSettings(body);
6189
6557
  return sendJson$3(response, 200, {
6190
6558
  ok: true,
6191
- value: await getAntigravityWebStatus(store, modelSettings, preferences)
6559
+ value: await getAntigravityWebStatus(store, modelSettings, preferences, accountPool)
6192
6560
  });
6193
6561
  }
6194
6562
  return sendMethodNotAllowed$2(response);
6195
6563
  }
6196
6564
  if (path === "logout") {
6197
6565
  if (request.method !== "POST") return sendMethodNotAllowed$2(response);
6198
- await store.delete();
6566
+ const body = await readRequestJson$2(request).catch(() => ({}));
6567
+ const targetId = typeof body.accountId === "string" ? body.accountId : void 0;
6568
+ if (targetId) await accountPool.deleteAccount(targetId);
6569
+ else {
6570
+ const poolData = await accountPool.read().catch(() => null);
6571
+ if (poolData?.activeAccountId) await accountPool.deleteAccount(poolData.activeAccountId);
6572
+ else await store.delete();
6573
+ }
6199
6574
  clearCachedQuota();
6200
6575
  return sendJson$3(response, 200, {
6201
6576
  ok: true,
6202
- value: await getAntigravityWebStatus(store, modelSettings)
6577
+ value: await getAntigravityWebStatus(store, modelSettings, preferences, accountPool)
6203
6578
  });
6204
6579
  }
6205
6580
  return sendJson$3(response, 404, {
@@ -7223,6 +7598,7 @@ const DEFAULT_ENABLED_MODEL_IDS$1 = FALLBACK_MODELS$1.map((model) => model.id);
7223
7598
  function registerCommandCodePreferenceStore(settings, fallbackStore = new FileModelSettingsStore()) {
7224
7599
  if (!settings) return {
7225
7600
  status: () => ({
7601
+ enabled: true,
7226
7602
  enabledModelIds: [...DEFAULT_ENABLED_MODEL_IDS$1],
7227
7603
  catalogModels: [],
7228
7604
  contextWindowOverrides: {},
@@ -7232,6 +7608,7 @@ function registerCommandCodePreferenceStore(settings, fallbackStore = new FileMo
7232
7608
  };
7233
7609
  const ns = SettingsModule.settingsNamespace ? SettingsModule.settingsNamespace(COMMAND_CODE_PREFERENCES_NAMESPACE) : COMMAND_CODE_PREFERENCES_NAMESPACE;
7234
7610
  const scope = settings.register.call(settings, ns, z.object({
7611
+ enabled: z.boolean().default(true),
7235
7612
  enabledModelIds: z.array(z.string()).default([...DEFAULT_ENABLED_MODEL_IDS$1]),
7236
7613
  contextWindowOverrides: z.dict(z.number()).default({}),
7237
7614
  defaultReasoningEffort: z.union([...COMMAND_CODE_REASONING_EFFORTS.map((effort) => z.const(effort)), z.const(null)]).default(null)
@@ -7240,6 +7617,7 @@ function registerCommandCodePreferenceStore(settings, fallbackStore = new FileMo
7240
7617
  status: () => {
7241
7618
  const value = scope.get();
7242
7619
  return {
7620
+ enabled: value.enabled !== false,
7243
7621
  enabledModelIds: value.enabledModelIds,
7244
7622
  catalogModels: [],
7245
7623
  contextWindowOverrides: value.contextWindowOverrides,
@@ -7249,6 +7627,7 @@ function registerCommandCodePreferenceStore(settings, fallbackStore = new FileMo
7249
7627
  update: async (patch) => {
7250
7628
  const current = scope.get();
7251
7629
  const normalized = {
7630
+ enabled: patch.enabled !== void 0 ? patch.enabled : current.enabled !== false,
7252
7631
  enabledModelIds: patch.enabledModelIds ?? current.enabledModelIds,
7253
7632
  contextWindowOverrides: patch.contextWindowOverrides ? {
7254
7633
  ...current.contextWindowOverrides,
@@ -7404,15 +7783,21 @@ var FileModelSettingsStore = class {
7404
7783
  const parsed = JSON.parse(content);
7405
7784
  if (typeof parsed === "object" && parsed !== null) {
7406
7785
  const record = parsed;
7786
+ const enabledModelIds = Array.isArray(record.enabledModelIds) ? record.enabledModelIds.filter((id) => typeof id === "string") : [...DEFAULT_ENABLED_MODEL_IDS$1];
7787
+ const catalogModels = Array.isArray(record.catalogModels) ? record.catalogModels : [];
7788
+ const contextWindowOverrides = typeof record.contextWindowOverrides === "object" && record.contextWindowOverrides !== null ? record.contextWindowOverrides : {};
7789
+ const defaultReasoningEffort = isReasoningEffort$1(record.defaultReasoningEffort) ? record.defaultReasoningEffort : null;
7407
7790
  return {
7408
- enabledModelIds: Array.isArray(record.enabledModelIds) ? record.enabledModelIds.filter((id) => typeof id === "string") : [...DEFAULT_ENABLED_MODEL_IDS$1],
7409
- catalogModels: Array.isArray(record.catalogModels) ? record.catalogModels : [],
7410
- contextWindowOverrides: typeof record.contextWindowOverrides === "object" && record.contextWindowOverrides !== null ? record.contextWindowOverrides : {},
7411
- defaultReasoningEffort: isReasoningEffort$1(record.defaultReasoningEffort) ? record.defaultReasoningEffort : null
7791
+ enabled: record.enabled !== false,
7792
+ enabledModelIds,
7793
+ catalogModels,
7794
+ contextWindowOverrides,
7795
+ defaultReasoningEffort
7412
7796
  };
7413
7797
  }
7414
7798
  } catch {}
7415
7799
  return {
7800
+ enabled: true,
7416
7801
  enabledModelIds: [...DEFAULT_ENABLED_MODEL_IDS$1],
7417
7802
  catalogModels: [],
7418
7803
  contextWindowOverrides: {},
@@ -7429,6 +7814,7 @@ var FileModelSettingsStore = class {
7429
7814
  const current = await this.read();
7430
7815
  const next = {
7431
7816
  ...current,
7817
+ ...patch.enabled !== void 0 ? { enabled: patch.enabled } : {},
7432
7818
  ...patch.enabledModelIds !== void 0 ? { enabledModelIds: patch.enabledModelIds } : {},
7433
7819
  ...patch.contextWindowOverrides !== void 0 ? { contextWindowOverrides: {
7434
7820
  ...current.contextWindowOverrides,
@@ -8335,9 +8721,13 @@ function attachmentLabel$1(block) {
8335
8721
  function collectImageRefs$1(content, refs) {
8336
8722
  if (!Array.isArray(content)) return;
8337
8723
  for (const block of content) {
8338
- if (!isRecord$2(block) || block.type !== "image") continue;
8339
- const attachment = attachmentOf$1(block);
8340
- if (attachment) refs.set(attachment.attachmentId, attachment);
8724
+ if (!isRecord$2(block)) continue;
8725
+ if (block.type === "image") {
8726
+ const attachment = attachmentOf$1(block);
8727
+ if (attachment) refs.set(attachment.attachmentId, attachment);
8728
+ continue;
8729
+ }
8730
+ if (block.type === "tool-result") collectImageRefs$1(block.content, refs);
8341
8731
  }
8342
8732
  }
8343
8733
  function base64Length$1(bytes) {
@@ -8475,6 +8865,83 @@ function toolResultText$1(blocks) {
8475
8865
  return "";
8476
8866
  }).join("");
8477
8867
  }
8868
+ /**
8869
+ * Anthropic `tool_result` content for one tool result, or `undefined` when the
8870
+ * result carries no image. Returning `undefined` is what keeps a plain tool
8871
+ * result a byte-identical string on the wire: the image-less path never changes
8872
+ * shape, so only results that actually hold pixels take the block-array form.
8873
+ */
8874
+ function toolResultBlocks$1(blocks, images) {
8875
+ if (!Array.isArray(blocks)) return void 0;
8876
+ const out = [];
8877
+ let hasImage = false;
8878
+ for (const block of blocks) {
8879
+ if (!isRecord$2(block)) continue;
8880
+ if (block.type === "text" && typeof block.text === "string") {
8881
+ out.push({
8882
+ type: "text",
8883
+ text: sanitizeText$1(block.text)
8884
+ });
8885
+ continue;
8886
+ }
8887
+ if (block.type === "image") {
8888
+ hasImage = true;
8889
+ const inline = imageBlockToInline$1(block, images);
8890
+ if (inline && SUPPORTED_IMAGE_MEDIA_TYPES$1.has(inline.mediaType)) out.push({
8891
+ type: "image",
8892
+ source: {
8893
+ type: "base64",
8894
+ media_type: inline.mediaType,
8895
+ data: inline.data
8896
+ }
8897
+ });
8898
+ else out.push({
8899
+ type: "text",
8900
+ text: unavailableImageText$1(block)
8901
+ });
8902
+ continue;
8903
+ }
8904
+ if (block.type === "tool-result") {
8905
+ const nested = toolResultBlocks$1(block.content, images);
8906
+ if (nested) {
8907
+ hasImage = true;
8908
+ out.push(...nested);
8909
+ }
8910
+ }
8911
+ }
8912
+ if (!hasImage) return void 0;
8913
+ if (out[0]?.type !== "text") out.unshift({
8914
+ type: "text",
8915
+ text: ""
8916
+ });
8917
+ return out;
8918
+ }
8919
+ /**
8920
+ * OpenAI `image_url` blocks for one tool result. A `role: "tool"` message can
8921
+ * only carry text, so these ride on a `user` message appended after the run of
8922
+ * tool messages rather than inside it.
8923
+ */
8924
+ function toolResultImageBlocks$1(blocks, images) {
8925
+ if (!Array.isArray(blocks)) return [];
8926
+ const out = [];
8927
+ for (const block of blocks) {
8928
+ if (!isRecord$2(block)) continue;
8929
+ if (block.type === "image") {
8930
+ const inline = imageBlockToInline$1(block, images);
8931
+ if (inline && SUPPORTED_IMAGE_MEDIA_TYPES$1.has(inline.mediaType)) out.push({
8932
+ type: "image_url",
8933
+ image_url: { url: `data:${inline.mediaType};base64,${inline.data}` }
8934
+ });
8935
+ else out.push({
8936
+ type: "text",
8937
+ text: unavailableImageText$1(block)
8938
+ });
8939
+ continue;
8940
+ }
8941
+ if (block.type === "tool-result") out.push(...toolResultImageBlocks$1(block.content, images));
8942
+ }
8943
+ return out;
8944
+ }
8478
8945
  function toolCallArguments$1(raw) {
8479
8946
  if (typeof raw === "string") return raw;
8480
8947
  if (raw === void 0 || raw === null) return "{}";
@@ -8571,14 +9038,27 @@ function buildOpenAIRequest$1(options, images = NO_RESOLVED_IMAGES$1) {
8571
9038
  role: "system",
8572
9039
  content: system
8573
9040
  });
8574
- for (const message of nonSystemMessages$1(options)) {
9041
+ const conversation = nonSystemMessages$1(options);
9042
+ for (let index = 0; index < conversation.length; index++) {
9043
+ const message = conversation[index];
8575
9044
  if (isToolResultMessage$1(message)) {
8576
- const block = message.content[0];
8577
- const callId = isRecord$2(block) && typeof block.toolCallId === "string" ? block.toolCallId : "";
8578
- messages.push({
8579
- role: "tool",
8580
- tool_call_id: callId,
8581
- content: toolResultText$1(message.content)
9045
+ const imageBlocks = [];
9046
+ while (index < conversation.length && isToolResultMessage$1(conversation[index])) {
9047
+ const current = conversation[index];
9048
+ const block = current.content[0];
9049
+ const callId = isRecord$2(block) && typeof block.toolCallId === "string" ? block.toolCallId : "";
9050
+ messages.push({
9051
+ role: "tool",
9052
+ tool_call_id: callId,
9053
+ content: toolResultText$1(current.content)
9054
+ });
9055
+ imageBlocks.push(...toolResultImageBlocks$1(current.content, images));
9056
+ index += 1;
9057
+ }
9058
+ index -= 1;
9059
+ if (imageBlocks.length > 0) messages.push({
9060
+ role: "user",
9061
+ content: imageBlocks
8582
9062
  });
8583
9063
  continue;
8584
9064
  }
@@ -8650,10 +9130,11 @@ function anthropicUserContent$1(message, images) {
8650
9130
  });
8651
9131
  } else if (block.type === "tool-result") {
8652
9132
  const callId = typeof block.toolCallId === "string" ? block.toolCallId : "";
9133
+ const resultBlocks = toolResultBlocks$1(block.content, images);
8653
9134
  blocks.push({
8654
9135
  type: "tool_result",
8655
9136
  tool_use_id: callId,
8656
- content: toolResultText$1(block.content),
9137
+ content: resultBlocks ?? toolResultText$1(block.content),
8657
9138
  ...block.isError === true ? { is_error: true } : {}
8658
9139
  });
8659
9140
  }
@@ -9231,9 +9712,10 @@ var CommandCodeAdapter = class extends LlmAdapter {
9231
9712
  async listModels(provider) {
9232
9713
  const prov = provider || "command-code";
9233
9714
  const settings = await this.settings();
9715
+ if (settings.enabled === false) return [];
9234
9716
  const catalog = await this.catalog();
9235
9717
  const enabled = new Set(settings.enabledModelIds);
9236
- return (enabled.size === 0 ? catalog : catalog.filter((model) => enabled.has(model.id))).map((model) => ({
9718
+ return catalog.filter((model) => enabled.has(model.id)).map((model) => ({
9237
9719
  provider: prov,
9238
9720
  id: model.id,
9239
9721
  name: model.name ?? model.id,
@@ -9858,14 +10340,13 @@ function fallbackCatalog$1() {
9858
10340
  * "everything currently offered" keeps a first run from hiding the whole
9859
10341
  * catalog behind an unedited default. Any explicit edit is honoured exactly.
9860
10342
  */
9861
- function resolveEnabledModelIds$1(stored, catalog) {
10343
+ function resolveEnabledModelIds$1(stored, catalog, enabled = true) {
10344
+ if (!enabled) return [];
9862
10345
  const catalogIds = catalog.map((model) => model.id);
9863
10346
  const shippedDefaults = new Set(FALLBACK_MODELS$1.map((model) => model.id));
9864
- const isUntouchedDefault = stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id));
9865
- if (stored.length === 0 || isUntouchedDefault) return catalogIds;
10347
+ if (stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id))) return catalogIds;
9866
10348
  const known = new Set(catalogIds);
9867
- const kept = stored.filter((id) => known.has(id));
9868
- return kept.length === 0 ? catalogIds : kept;
10349
+ return stored.filter((id) => known.has(id));
9869
10350
  }
9870
10351
  function readOption$1(value, fallback) {
9871
10352
  return typeof value === "function" ? value() : value ?? fallback;
@@ -9880,9 +10361,11 @@ async function getCommandCodeWebStatus(store, modelSettings, preferences, option
9880
10361
  apiEnv
9881
10362
  });
9882
10363
  const catalog = live.length > 0 ? live : fallbackCatalog$1();
9883
- const models = buildModelOptions$1(catalog, resolveEnabledModelIds$1(settings.enabledModelIds, catalog), settings.contextWindowOverrides);
10364
+ const enabled = settings.enabled !== false;
10365
+ const models = buildModelOptions$1(catalog, resolveEnabledModelIds$1(settings.enabledModelIds, catalog, enabled), settings.contextWindowOverrides);
9884
10366
  const quota = getCachedQuota$1();
9885
10367
  return {
10368
+ enabled,
9886
10369
  authenticated: credentials !== null,
9887
10370
  hasCredentials: credentials !== null,
9888
10371
  storagePath: store.path(),
@@ -10014,6 +10497,7 @@ function registerCommandCodeRoutes(ctx, store, modelSettings, preferences, optio
10014
10497
  });
10015
10498
  const body = await readRequestJson$1(request);
10016
10499
  const patch = {};
10500
+ if (typeof body.enabled === "boolean") patch.enabled = body.enabled;
10017
10501
  if (Array.isArray(body.enabledModelIds)) patch.enabledModelIds = body.enabledModelIds.filter((id) => typeof id === "string");
10018
10502
  if (typeof body.contextWindowOverrides === "object" && body.contextWindowOverrides !== null) {
10019
10503
  const overrides = {};
@@ -10360,6 +10844,7 @@ const DEFAULT_ENABLED_MODEL_IDS = FALLBACK_MODELS.map((model) => model.id);
10360
10844
  function registerKimiCodePreferenceStore(settings, fallbackStore = new FileModelSettingsStore$2()) {
10361
10845
  if (!settings) return {
10362
10846
  status: () => ({
10847
+ enabled: true,
10363
10848
  enabledModelIds: [...DEFAULT_ENABLED_MODEL_IDS],
10364
10849
  catalogModels: [],
10365
10850
  contextWindowOverrides: {},
@@ -10369,6 +10854,7 @@ function registerKimiCodePreferenceStore(settings, fallbackStore = new FileModel
10369
10854
  };
10370
10855
  const ns = SettingsModule.settingsNamespace ? SettingsModule.settingsNamespace(KIMI_CODE_PREFERENCES_NAMESPACE) : KIMI_CODE_PREFERENCES_NAMESPACE;
10371
10856
  const scope = settings.register.call(settings, ns, z.object({
10857
+ enabled: z.boolean().default(true),
10372
10858
  enabledModelIds: z.array(z.string()).default([...DEFAULT_ENABLED_MODEL_IDS]),
10373
10859
  contextWindowOverrides: z.dict(z.number()).default({}),
10374
10860
  defaultReasoningEffort: z.union([...KIMI_CODE_REASONING_EFFORTS.map((effort) => z.const(effort)), z.const(null)]).default(null)
@@ -10377,6 +10863,7 @@ function registerKimiCodePreferenceStore(settings, fallbackStore = new FileModel
10377
10863
  status: () => {
10378
10864
  const value = scope.get();
10379
10865
  return {
10866
+ enabled: value.enabled !== false,
10380
10867
  enabledModelIds: value.enabledModelIds,
10381
10868
  catalogModels: [],
10382
10869
  contextWindowOverrides: value.contextWindowOverrides,
@@ -10386,6 +10873,7 @@ function registerKimiCodePreferenceStore(settings, fallbackStore = new FileModel
10386
10873
  update: async (patch) => {
10387
10874
  const current = scope.get();
10388
10875
  const normalized = {
10876
+ enabled: patch.enabled !== void 0 ? patch.enabled : current.enabled !== false,
10389
10877
  enabledModelIds: patch.enabledModelIds ?? current.enabledModelIds,
10390
10878
  contextWindowOverrides: patch.contextWindowOverrides ? {
10391
10879
  ...current.contextWindowOverrides,
@@ -10576,15 +11064,21 @@ var FileModelSettingsStore$2 = class {
10576
11064
  const parsed = JSON.parse(content);
10577
11065
  if (typeof parsed === "object" && parsed !== null) {
10578
11066
  const record = parsed;
11067
+ const enabledModelIds = Array.isArray(record.enabledModelIds) ? record.enabledModelIds.filter((id) => typeof id === "string") : [...DEFAULT_ENABLED_MODEL_IDS];
11068
+ const catalogModels = Array.isArray(record.catalogModels) ? record.catalogModels : [];
11069
+ const contextWindowOverrides = typeof record.contextWindowOverrides === "object" && record.contextWindowOverrides !== null ? record.contextWindowOverrides : {};
11070
+ const defaultReasoningEffort = isReasoningEffort(record.defaultReasoningEffort) ? record.defaultReasoningEffort : null;
10579
11071
  return {
10580
- enabledModelIds: Array.isArray(record.enabledModelIds) ? record.enabledModelIds.filter((id) => typeof id === "string") : [...DEFAULT_ENABLED_MODEL_IDS],
10581
- catalogModels: Array.isArray(record.catalogModels) ? record.catalogModels : [],
10582
- contextWindowOverrides: typeof record.contextWindowOverrides === "object" && record.contextWindowOverrides !== null ? record.contextWindowOverrides : {},
10583
- defaultReasoningEffort: isReasoningEffort(record.defaultReasoningEffort) ? record.defaultReasoningEffort : null
11072
+ enabled: record.enabled !== false,
11073
+ enabledModelIds,
11074
+ catalogModels,
11075
+ contextWindowOverrides,
11076
+ defaultReasoningEffort
10584
11077
  };
10585
11078
  }
10586
11079
  } catch {}
10587
11080
  return {
11081
+ enabled: true,
10588
11082
  enabledModelIds: [...DEFAULT_ENABLED_MODEL_IDS],
10589
11083
  catalogModels: [],
10590
11084
  contextWindowOverrides: {},
@@ -10601,6 +11095,7 @@ var FileModelSettingsStore$2 = class {
10601
11095
  const current = await this.read();
10602
11096
  const next = {
10603
11097
  ...current,
11098
+ ...patch.enabled !== void 0 ? { enabled: patch.enabled } : {},
10604
11099
  ...patch.enabledModelIds !== void 0 ? { enabledModelIds: patch.enabledModelIds } : {},
10605
11100
  ...patch.contextWindowOverrides !== void 0 ? { contextWindowOverrides: {
10606
11101
  ...current.contextWindowOverrides,
@@ -12131,9 +12626,13 @@ function attachmentLabel(block) {
12131
12626
  function collectImageRefs(content, refs) {
12132
12627
  if (!Array.isArray(content)) return;
12133
12628
  for (const block of content) {
12134
- if (!isRecord(block) || block.type !== "image") continue;
12135
- const attachment = attachmentOf(block);
12136
- if (attachment) refs.set(attachment.attachmentId, attachment);
12629
+ if (!isRecord(block)) continue;
12630
+ if (block.type === "image") {
12631
+ const attachment = attachmentOf(block);
12632
+ if (attachment) refs.set(attachment.attachmentId, attachment);
12633
+ continue;
12634
+ }
12635
+ if (block.type === "tool-result") collectImageRefs(block.content, refs);
12137
12636
  }
12138
12637
  }
12139
12638
  function base64Length(bytes) {
@@ -12410,6 +12909,83 @@ function toolResultText(blocks) {
12410
12909
  return "";
12411
12910
  }).join("");
12412
12911
  }
12912
+ /**
12913
+ * Anthropic `tool_result` content for one tool result, or `undefined` when the
12914
+ * result carries no image. Returning `undefined` is what keeps a plain tool
12915
+ * result a byte-identical string on the wire: the image-less path never changes
12916
+ * shape, so only results that actually hold pixels take the block-array form.
12917
+ */
12918
+ function toolResultBlocks(blocks, images) {
12919
+ if (!Array.isArray(blocks)) return void 0;
12920
+ const out = [];
12921
+ let hasImage = false;
12922
+ for (const block of blocks) {
12923
+ if (!isRecord(block)) continue;
12924
+ if (block.type === "text" && typeof block.text === "string") {
12925
+ out.push({
12926
+ type: "text",
12927
+ text: sanitizeText(block.text)
12928
+ });
12929
+ continue;
12930
+ }
12931
+ if (block.type === "image") {
12932
+ hasImage = true;
12933
+ const inline = imageBlockToInline(block, images);
12934
+ if (inline && SUPPORTED_IMAGE_MEDIA_TYPES.has(inline.mediaType)) out.push({
12935
+ type: "image",
12936
+ source: {
12937
+ type: "base64",
12938
+ media_type: inline.mediaType,
12939
+ data: inline.data
12940
+ }
12941
+ });
12942
+ else out.push({
12943
+ type: "text",
12944
+ text: unavailableImageText(block)
12945
+ });
12946
+ continue;
12947
+ }
12948
+ if (block.type === "tool-result") {
12949
+ const nested = toolResultBlocks(block.content, images);
12950
+ if (nested) {
12951
+ hasImage = true;
12952
+ out.push(...nested);
12953
+ }
12954
+ }
12955
+ }
12956
+ if (!hasImage) return void 0;
12957
+ if (out[0]?.type !== "text") out.unshift({
12958
+ type: "text",
12959
+ text: ""
12960
+ });
12961
+ return out;
12962
+ }
12963
+ /**
12964
+ * OpenAI `image_url` blocks for one tool result. A `role: "tool"` message can
12965
+ * only carry text, so these ride on a `user` message appended after the run of
12966
+ * tool messages rather than inside it.
12967
+ */
12968
+ function toolResultImageBlocks(blocks, images) {
12969
+ if (!Array.isArray(blocks)) return [];
12970
+ const out = [];
12971
+ for (const block of blocks) {
12972
+ if (!isRecord(block)) continue;
12973
+ if (block.type === "image") {
12974
+ const inline = imageBlockToInline(block, images);
12975
+ if (inline && SUPPORTED_IMAGE_MEDIA_TYPES.has(inline.mediaType)) out.push({
12976
+ type: "image_url",
12977
+ image_url: { url: `data:${inline.mediaType};base64,${inline.data}` }
12978
+ });
12979
+ else out.push({
12980
+ type: "text",
12981
+ text: unavailableImageText(block)
12982
+ });
12983
+ continue;
12984
+ }
12985
+ if (block.type === "tool-result") out.push(...toolResultImageBlocks(block.content, images));
12986
+ }
12987
+ return out;
12988
+ }
12413
12989
  function toolCallArguments(raw) {
12414
12990
  if (typeof raw === "string") return raw;
12415
12991
  if (raw === void 0 || raw === null) return "{}";
@@ -12444,15 +13020,134 @@ function leadingSystemText(options) {
12444
13020
  function nonSystemMessages(options) {
12445
13021
  return options.messages.filter((message) => message.role !== "system");
12446
13022
  }
12447
- /** Drop the JSON-Schema keywords provider gateways reject or ignore. */
12448
- function stripMetaSchema(schema) {
13023
+ function cloneJsonValue(value) {
13024
+ if (Array.isArray(value)) return value.map(cloneJsonValue);
13025
+ if (isRecord(value)) {
13026
+ const res = {};
13027
+ for (const [k, v] of Object.entries(value)) res[k] = cloneJsonValue(v);
13028
+ return res;
13029
+ }
13030
+ return value;
13031
+ }
13032
+ function resolveLocalJsonPointer(root, ref) {
13033
+ if (ref === "#") return {
13034
+ found: true,
13035
+ value: root
13036
+ };
13037
+ let current = root;
13038
+ for (const rawPart of ref.slice(2).split("/")) {
13039
+ const part = rawPart.replaceAll("~1", "/").replaceAll("~0", "~");
13040
+ if (isRecord(current)) {
13041
+ if (!Object.prototype.hasOwnProperty.call(current, part)) return { found: false };
13042
+ current = current[part];
13043
+ } else if (Array.isArray(current)) {
13044
+ const idx = Number(part);
13045
+ if (!/^(0|[1-9]\d*)$/.test(part) || idx >= current.length) return { found: false };
13046
+ current = current[idx];
13047
+ } else return { found: false };
13048
+ }
13049
+ return {
13050
+ found: true,
13051
+ value: current
13052
+ };
13053
+ }
13054
+ function derefNode(node, root, visited) {
13055
+ if (Array.isArray(node)) return node.map((item) => derefNode(item, root, visited));
13056
+ if (isRecord(node)) {
13057
+ if (typeof node["$ref"] === "string" && (node["$ref"] === "#" || node["$ref"].startsWith("#/"))) {
13058
+ const ref = node["$ref"];
13059
+ if (visited.has(ref)) return node;
13060
+ const resolved = resolveLocalJsonPointer(root, ref);
13061
+ if (resolved.found) {
13062
+ visited.add(ref);
13063
+ const inlined = derefNode(resolved.value, root, visited);
13064
+ visited.delete(ref);
13065
+ if (isRecord(inlined)) {
13066
+ const merged = { ...inlined };
13067
+ for (const [k, v] of Object.entries(node)) {
13068
+ if (k === "$ref") continue;
13069
+ merged[k] = derefNode(v, root, visited);
13070
+ }
13071
+ return merged;
13072
+ }
13073
+ return inlined;
13074
+ }
13075
+ return node;
13076
+ }
13077
+ const res = {};
13078
+ for (const [k, v] of Object.entries(node)) res[k] = derefNode(v, root, visited);
13079
+ return res;
13080
+ }
13081
+ return node;
13082
+ }
13083
+ function hasUnresolvedDefinitionRef(node, bucketKey) {
13084
+ if (Array.isArray(node)) return node.some((child) => hasUnresolvedDefinitionRef(child, bucketKey));
13085
+ if (isRecord(node)) {
13086
+ const ref = node["$ref"];
13087
+ if (typeof ref === "string" && ref.startsWith(`#/${bucketKey}/`)) return true;
13088
+ for (const [k, v] of Object.entries(node)) {
13089
+ if (k === bucketKey) continue;
13090
+ if (hasUnresolvedDefinitionRef(v, bucketKey)) return true;
13091
+ }
13092
+ }
13093
+ return false;
13094
+ }
13095
+ function inferValueType(val) {
13096
+ if (val === null) return "null";
13097
+ if (Array.isArray(val)) return "array";
13098
+ switch (typeof val) {
13099
+ case "string": return "string";
13100
+ case "number": return Number.isInteger(val) ? "integer" : "number";
13101
+ case "boolean": return "boolean";
13102
+ case "object": return "object";
13103
+ default: return;
13104
+ }
13105
+ }
13106
+ function inferTypeFromValues(values) {
13107
+ const types = /* @__PURE__ */ new Set();
13108
+ for (const v of values) {
13109
+ const t = inferValueType(v);
13110
+ if (t) types.add(t);
13111
+ }
13112
+ if (types.has("number") && types.has("integer")) types.delete("integer");
13113
+ if (types.size === 1) return types.values().next().value;
13114
+ }
13115
+ function normalizeSchemaProperties(node) {
13116
+ if (!isRecord(node)) return;
13117
+ if (isRecord(node.properties)) {
13118
+ for (const propSchema of Object.values(node.properties)) if (isRecord(propSchema)) {
13119
+ if (!propSchema.type && !propSchema.$ref) {
13120
+ if (Array.isArray(propSchema.enum) && propSchema.enum.length > 0) propSchema.type = inferTypeFromValues(propSchema.enum) ?? "string";
13121
+ else if (propSchema.const !== void 0) propSchema.type = inferValueType(propSchema.const) ?? "string";
13122
+ else if (isRecord(propSchema.properties)) propSchema.type = "object";
13123
+ else if (propSchema.items) propSchema.type = "array";
13124
+ }
13125
+ normalizeSchemaProperties(propSchema);
13126
+ }
13127
+ }
13128
+ if (isRecord(node.items)) normalizeSchemaProperties(node.items);
13129
+ else if (Array.isArray(node.items)) for (const item of node.items) normalizeSchemaProperties(item);
13130
+ }
13131
+ /**
13132
+ * Normalizes tool parameter schemas for Kimi by stripping meta keywords ($schema),
13133
+ * inlining definitions ($defs/definitions/$ref), and ensuring property types for enums/consts.
13134
+ */
13135
+ function normalizeKimiToolSchema(schema) {
12449
13136
  if (!isRecord(schema)) return {
12450
13137
  type: "object",
12451
13138
  properties: {}
12452
13139
  };
12453
- const copy = { ...schema };
12454
- delete copy.$schema;
12455
- return copy;
13140
+ const cloned = cloneJsonValue(schema);
13141
+ delete cloned.$schema;
13142
+ const dereffed = derefNode(cloned, cloned, /* @__PURE__ */ new Set());
13143
+ if (!hasUnresolvedDefinitionRef(dereffed, "$defs")) delete dereffed.$defs;
13144
+ if (!hasUnresolvedDefinitionRef(dereffed, "definitions")) delete dereffed.definitions;
13145
+ normalizeSchemaProperties(dereffed);
13146
+ return dereffed;
13147
+ }
13148
+ /** Drop the JSON-Schema keywords provider gateways reject or ignore, and normalize properties. */
13149
+ function stripMetaSchema(schema) {
13150
+ return normalizeKimiToolSchema(schema);
12456
13151
  }
12457
13152
  /** Concatenated reasoning text one assistant message carries, when it has any. */
12458
13153
  function reasoningText(message) {
@@ -12663,26 +13358,41 @@ function buildOpenAIRequest(options, images = NO_RESOLVED_IMAGES, preserveThinki
12663
13358
  }
12664
13359
  };
12665
13360
  flushSlots(0);
12666
- for (const message of nonSystemMessages(options)) {
13361
+ const conversation = nonSystemMessages(options);
13362
+ for (let index = 0; index < conversation.length; index++) {
13363
+ const message = conversation[index];
12667
13364
  flushSlots(nonSystemIndex);
12668
13365
  nonSystemIndex += 1;
12669
13366
  if (isToolResultMessage(message)) {
12670
- const block = message.content[0];
12671
- const callId = isRecord(block) && typeof block.toolCallId === "string" ? block.toolCallId : "";
12672
- messages.push({
12673
- role: "tool",
12674
- tool_call_id: clampToolCallId(callId),
12675
- content: toolResultText(message.content)
13367
+ const imageBlocks = [];
13368
+ while (index < conversation.length && isToolResultMessage(conversation[index])) {
13369
+ const current = conversation[index];
13370
+ if (index > 0) {
13371
+ flushSlots(nonSystemIndex);
13372
+ nonSystemIndex += 1;
13373
+ }
13374
+ const block = current.content[0];
13375
+ const callId = isRecord(block) && typeof block.toolCallId === "string" ? block.toolCallId : "";
13376
+ messages.push({
13377
+ role: "tool",
13378
+ tool_call_id: clampToolCallId(callId),
13379
+ content: toolResultText(current.content)
13380
+ });
13381
+ imageBlocks.push(...toolResultImageBlocks(current.content, images));
13382
+ index += 1;
13383
+ }
13384
+ index -= 1;
13385
+ if (imageBlocks.length > 0) messages.push({
13386
+ role: "user",
13387
+ content: imageBlocks
12676
13388
  });
12677
13389
  continue;
12678
13390
  }
12679
13391
  if (message.role === "assistant") {
12680
13392
  const { content, toolCalls, reasoning } = openAIAssistantContent(message);
12681
- if (content === "" && toolCalls.length === 0) continue;
12682
- const entry = {
12683
- role: "assistant",
12684
- content
12685
- };
13393
+ if (content === "" && toolCalls.length === 0 && reasoning === "") continue;
13394
+ const entry = { role: "assistant" };
13395
+ if (content !== "" || toolCalls.length === 0) entry.content = content;
12686
13396
  if (toolCalls.length > 0) entry.tool_calls = toolCalls;
12687
13397
  if (thinkingOn) entry.reasoning_content = reasoning;
12688
13398
  messages.push(entry);
@@ -12732,11 +13442,12 @@ function buildOpenAIRequest(options, images = NO_RESOLVED_IMAGES, preserveThinki
12732
13442
  /**
12733
13443
  * Stable identifier for the conversation this request belongs to.
12734
13444
  *
12735
- * Derived from the first user turn rather than a fresh value per request, so it
12736
- * stays identical across the steps of one session and changes when a new
12737
- * conversation starts.
13445
+ * Prioritizes the session identifier (GenerateOptions.sessionId) if present,
13446
+ * ensuring the cache key stays strictly constant across turns, context compactions,
13447
+ * and multimodal message changes. Falls back to hashing the first user message text.
12738
13448
  */
12739
13449
  function promptCacheKey(options) {
13450
+ if (typeof options.sessionId === "string" && options.sessionId.trim() !== "") return `dsh-${options.sessionId.trim()}`;
12740
13451
  for (const message of options.messages) {
12741
13452
  if (message.role !== "user") continue;
12742
13453
  const text = textOf(message.content);
@@ -12778,10 +13489,11 @@ function anthropicUserContent(message, images) {
12778
13489
  });
12779
13490
  } else if (block.type === "tool-result") {
12780
13491
  const callId = typeof block.toolCallId === "string" ? block.toolCallId : "";
13492
+ const resultBlocks = toolResultBlocks(block.content, images);
12781
13493
  blocks.push({
12782
13494
  type: "tool_result",
12783
13495
  tool_use_id: clampToolCallId(callId),
12784
- content: toolResultText(block.content),
13496
+ content: resultBlocks ?? toolResultText(block.content),
12785
13497
  ...block.isError === true ? { is_error: true } : {}
12786
13498
  });
12787
13499
  }
@@ -13540,9 +14252,10 @@ var KimiCodeAdapter = class extends LlmAdapter {
13540
14252
  async listModels(provider) {
13541
14253
  const prov = provider || "kimi-code";
13542
14254
  const settings = await this.settings();
14255
+ if (settings.enabled === false) return [];
13543
14256
  const catalog = await this.catalog();
13544
14257
  const enabled = new Set(settings.enabledModelIds);
13545
- return (enabled.size === 0 ? catalog : catalog.filter((model) => enabled.has(model.id))).map((model) => ({
14258
+ return catalog.filter((model) => enabled.has(model.id)).map((model) => ({
13546
14259
  provider: prov,
13547
14260
  id: model.id,
13548
14261
  name: model.name ?? model.id,
@@ -13742,14 +14455,13 @@ function fallbackCatalog() {
13742
14455
  * "everything currently offered" keeps a first run from hiding the whole
13743
14456
  * catalog behind an unedited default. Any explicit edit is honoured exactly.
13744
14457
  */
13745
- function resolveEnabledModelIds(stored, catalog) {
14458
+ function resolveEnabledModelIds(stored, catalog, enabled = true) {
14459
+ if (!enabled) return [];
13746
14460
  const catalogIds = catalog.map((model) => model.id);
13747
14461
  const shippedDefaults = new Set(FALLBACK_MODELS.map((model) => model.id));
13748
- const isUntouchedDefault = stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id));
13749
- if (stored.length === 0 || isUntouchedDefault) return catalogIds;
14462
+ if (stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id))) return catalogIds;
13750
14463
  const known = new Set(catalogIds);
13751
- const kept = stored.filter((id) => known.has(id));
13752
- return kept.length === 0 ? catalogIds : kept;
14464
+ return stored.filter((id) => known.has(id));
13753
14465
  }
13754
14466
  function readOption(value, fallback) {
13755
14467
  return typeof value === "function" ? value() : value ?? fallback;
@@ -13766,10 +14478,12 @@ async function getKimiCodeWebStatus(store, modelSettings, preferences, options =
13766
14478
  accessToken: credentials?.accessToken
13767
14479
  }).catch(() => []);
13768
14480
  const catalog = live.length > 0 ? live : fallbackCatalog();
13769
- const models = buildModelOptions(catalog, resolveEnabledModelIds(settings.enabledModelIds, catalog), settings.contextWindowOverrides);
14481
+ const enabled = settings.enabled !== false;
14482
+ const models = buildModelOptions(catalog, resolveEnabledModelIds(settings.enabledModelIds, catalog, enabled), settings.contextWindowOverrides);
13770
14483
  const quota = getCachedQuota$2();
13771
14484
  const account = quota?.account ?? (credentials === null ? null : accountFromCredentials(credentials));
13772
14485
  return {
14486
+ enabled,
13773
14487
  authenticated: credentials !== null,
13774
14488
  hasCredentials: credentials !== null,
13775
14489
  storagePath: store.path(),
@@ -13922,6 +14636,7 @@ function registerKimiCodeRoutes(ctx, store, modelSettings, preferences, options
13922
14636
  });
13923
14637
  const body = await readRequestJson(request);
13924
14638
  const patch = {};
14639
+ if (typeof body.enabled === "boolean") patch.enabled = body.enabled;
13925
14640
  if (Array.isArray(body.enabledModelIds)) patch.enabledModelIds = body.enabledModelIds.filter((id) => typeof id === "string");
13926
14641
  if (typeof body.contextWindowOverrides === "object" && body.contextWindowOverrides !== null) {
13927
14642
  const overrides = {};
@@ -15727,6 +16442,7 @@ function apply(ctx, pluginConfig = {}) {
15727
16442
  const store = createPlatformTokenStore();
15728
16443
  const preferences = registerPreferenceStore(ctx.settings);
15729
16444
  const antigravityStore = new FileCredentialStore$1();
16445
+ const antigravityAccountPool = new AccountPoolStore(void 0, void 0, antigravityStore);
15730
16446
  const antigravityModelSettings = new FileModelSettingsStore$1();
15731
16447
  const antigravityPreferences = registerAntigravityPreferenceStore(ctx.settings, antigravityModelSettings);
15732
16448
  const commandCodeStore = new FileCredentialStore();
@@ -15769,9 +16485,25 @@ function apply(ctx, pluginConfig = {}) {
15769
16485
  const antigravityAdapter = new AntigravityAdapter(antigravityStore, antigravityModelSettings, antigravityPreferences, {
15770
16486
  fetchFn: proxyFetch,
15771
16487
  attachments: ctx.attachments
15772
- });
15773
- const disposeAntigravityAdapter = ctx.llm.registerAdapter([PROVIDER_ID$2], antigravityAdapter);
15774
- const disposeAntigravityRoutes = registerAntigravityRoutes(ctx, antigravityStore, antigravityModelSettings, antigravityPreferences, proxyFetch);
16488
+ }, antigravityAccountPool);
16489
+ let antigravityRegistration;
16490
+ let antigravityConflict = null;
16491
+ const claimAntigravityRoute = () => {
16492
+ if (antigravityRegistration !== void 0) return;
16493
+ try {
16494
+ antigravityRegistration = ctx.llm.registerAdapter([PROVIDER_ID$2], antigravityAdapter);
16495
+ if (antigravityConflict !== null) ctx.logger.info(`[dsh-chatgpt-subscription] Antigravity route "${PROVIDER_ID$2}" is now served by this plugin`);
16496
+ antigravityConflict = null;
16497
+ } catch (error) {
16498
+ antigravityConflict = error instanceof Error ? error.message : String(error);
16499
+ ctx.logger.warn(`[dsh-chatgpt-subscription] provider route "${PROVIDER_ID$2}" is already owned by another adapter; Antigravity models keep being served by that one until its configuration is removed (${antigravityConflict})`);
16500
+ }
16501
+ };
16502
+ claimAntigravityRoute();
16503
+ const antigravityRouteWatch = typeof ctx.on === "function" ? ctx.on("llm/adapters-updated", () => {
16504
+ claimAntigravityRoute();
16505
+ }) : void 0;
16506
+ const disposeAntigravityRoutes = registerAntigravityRoutes(ctx, antigravityStore, antigravityModelSettings, antigravityPreferences, proxyFetch, antigravityAccountPool);
15775
16507
  const disposeCommandCodeRoutes = registerCommandCodeRoutes(ctx, commandCodeStore, commandCodeModelSettings, commandCodePreferences, {
15776
16508
  fetchFn: proxyFetch,
15777
16509
  serving: () => commandCodeRegistration !== void 0,
@@ -15894,7 +16626,9 @@ function apply(ctx, pluginConfig = {}) {
15894
16626
  disposeAdapter();
15895
16627
  disposeRoutes();
15896
16628
  disposeAntigravityRoutes();
15897
- disposeAntigravityAdapter();
16629
+ releaseHandle(antigravityRouteWatch);
16630
+ antigravityRegistration?.();
16631
+ antigravityRegistration = void 0;
15898
16632
  disposeCommandCodeRoutes();
15899
16633
  releaseHandle(commandCodeRouteWatch);
15900
16634
  commandCodeRegistration?.();
@@ -15920,4 +16654,4 @@ function localWebServerBaseUrl(host, port) {
15920
16654
  return `http://${host === "0.0.0.0" ? "127.0.0.1" : host}:${port}`;
15921
16655
  }
15922
16656
  //#endregion
15923
- export { AntigravityAdapter, CodexChatGptAdapter, CommandCodeAdapter, FileCredentialStore as CommandCodeCredentialStore, FileModelSettingsStore as CommandCodeModelSettingsStore, Config, DEFAULT_SUBAGENT_INHERIT_TOOLS, FileCredentialStore$1 as FileCredentialStore, FileModelSettingsStore$1 as FileModelSettingsStore, KIMI_CODE_MODELS, KIMI_CODE_RETRY_POLICY_CONFIG, KimiCodeAdapter, FileCredentialStore$2 as KimiCodeCredentialStore, FileModelSettingsStore$2 as KimiCodeModelSettingsStore, LinuxFileTokenStore, MacKeychainTokenStore, OAuthService, ProxyManager, RELAY_PROBE_ENV, RELAY_PROBE_FILE_ENV, RELAY_PROBE_FILE_NAME, RELAY_PROBE_MAX_BYTES, RELAY_SOURCE_KINDS, RelayProbe, ResponsesClient, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, SearchProviderSwitcher, UsageService, WindowsDpapiTokenStore, apply, auditChildRoutes, auditedRoutesOf, authorizedRoutesFor, beginWebLogin as beginKimiCodeLogin, beginWebLogin$1 as beginWebLogin, childRoutesOf, classifyKimiFailure, clearCachedQuota, clearCachedQuota$1 as clearCommandCodeQuota, clearCachedQuota$2 as clearKimiCodeQuota, credentialPath as commandCodeCredentialPath, modelSettingsPath as commandCodeModelSettingsPath, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createFileRelayProbeSink, createPlatformTokenStore, createSubagentAuthorization, credentialPath$1 as credentialPath, delegationDenialReason, delegationModeOf, detectSystemProxy, effectiveRouteOf, ensureAccessToken as ensureKimiCodeAccessToken, fetchAccountQuota, fetchAccountQuota$1 as fetchCommandCodeQuota, fetchAccountQuota$2 as fetchKimiCodeQuota, fetchUserInfo as fetchKimiCodeUserInfo, getCachedQuota, getWebLoginStatus as getCommandCodeLoginStatus, getCachedQuota$1 as getCommandCodeQuota, getCommandCodeWebStatus, getWebLoginStatus$1 as getKimiCodeLoginStatus, getCachedQuota$2 as getKimiCodeQuota, getKimiCodeWebStatus, inheritOverrideReason, inheritRouteDenialReason, inheritedRouteOf, inject, installRelayProbe, installSubagentModelAuthorization, credentialPath$2 as kimiCodeCredentialPath, kimiCodeModelDef, modelSettingsPath$1 as kimiCodeModelSettingsPath, loadProviderModels as loadCommandCodeModels, loadProviderModels$1 as loadKimiCodeModels, loginAndSave, mapCodexUsage, modelSettingsPath$2 as modelSettingsPath, normalizeDelegationToolNames, normalizeInheritToolNames, parseAllowedRoutes, parseCodexUsage, parseResponsesStream, policyRoutesOf, readChildDescriptor, refreshAntigravityToken, refreshAccessToken as refreshKimiCodeToken, registerCommandCodePreferenceStore, registerCommandCodeRoutes, registerKimiCodePreferenceStore, registerKimiCodeRoutes, relayProbeEnabled, relayProbeEnvFile, relayProbeEnvValue, relayProbeLogPath, requestDeviceAuthorization as requestKimiCodeDeviceAuthorization, resolveRegion as resolveKimiCodeRegion, saveApiKey as saveCommandCodeApiKey, beginWebLogin$2 as startCommandCodeLogin, subagentModelSelectionPreference, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames, validateInheritToolNames, violationText };
16657
+ export { AccountPoolStore, AntigravityAdapter, CodexChatGptAdapter, CommandCodeAdapter, FileCredentialStore as CommandCodeCredentialStore, FileModelSettingsStore as CommandCodeModelSettingsStore, Config, DEFAULT_SUBAGENT_INHERIT_TOOLS, FileCredentialStore$1 as FileCredentialStore, FileModelSettingsStore$1 as FileModelSettingsStore, KIMI_CODE_MODELS, KIMI_CODE_RETRY_POLICY_CONFIG, KimiCodeAdapter, FileCredentialStore$2 as KimiCodeCredentialStore, FileModelSettingsStore$2 as KimiCodeModelSettingsStore, LinuxFileTokenStore, MacKeychainTokenStore, OAuthService, ProxyManager, RELAY_PROBE_ENV, RELAY_PROBE_FILE_ENV, RELAY_PROBE_FILE_NAME, RELAY_PROBE_MAX_BYTES, RELAY_SOURCE_KINDS, RelayProbe, ResponsesClient, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, SearchProviderSwitcher, UsageService, WindowsDpapiTokenStore, apply, auditChildRoutes, auditedRoutesOf, authorizedRoutesFor, beginWebLogin as beginKimiCodeLogin, beginWebLogin$1 as beginWebLogin, childRoutesOf, classifyKimiFailure, clearCachedQuota, clearCachedQuota$1 as clearCommandCodeQuota, clearCachedQuota$2 as clearKimiCodeQuota, credentialPath as commandCodeCredentialPath, modelSettingsPath as commandCodeModelSettingsPath, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createFileRelayProbeSink, createPlatformTokenStore, createSubagentAuthorization, credentialPath$1 as credentialPath, delegationDenialReason, delegationModeOf, detectSystemProxy, effectiveRouteOf, ensureAccessToken as ensureKimiCodeAccessToken, fetchAccountQuota, fetchAccountQuota$1 as fetchCommandCodeQuota, fetchAccountQuota$2 as fetchKimiCodeQuota, fetchUserInfo as fetchKimiCodeUserInfo, getCachedQuota, getWebLoginStatus as getCommandCodeLoginStatus, getCachedQuota$1 as getCommandCodeQuota, getCommandCodeWebStatus, getWebLoginStatus$1 as getKimiCodeLoginStatus, getCachedQuota$2 as getKimiCodeQuota, getKimiCodeWebStatus, inheritOverrideReason, inheritRouteDenialReason, inheritedRouteOf, inject, installRelayProbe, installSubagentModelAuthorization, credentialPath$2 as kimiCodeCredentialPath, kimiCodeModelDef, modelSettingsPath$1 as kimiCodeModelSettingsPath, loadProviderModels as loadCommandCodeModels, loadProviderModels$1 as loadKimiCodeModels, loginAndSave, mapCodexUsage, modelSettingsPath$2 as modelSettingsPath, normalizeDelegationToolNames, normalizeInheritToolNames, parseAllowedRoutes, parseCodexUsage, parseResponsesStream, policyRoutesOf, readChildDescriptor, refreshAntigravityToken, refreshAccessToken as refreshKimiCodeToken, registerCommandCodePreferenceStore, registerCommandCodeRoutes, registerKimiCodePreferenceStore, registerKimiCodeRoutes, relayProbeEnabled, relayProbeEnvFile, relayProbeEnvValue, relayProbeLogPath, requestDeviceAuthorization as requestKimiCodeDeviceAuthorization, resolveRegion as resolveKimiCodeRegion, saveApiKey as saveCommandCodeApiKey, beginWebLogin$2 as startCommandCodeLogin, subagentModelSelectionPreference, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames, validateInheritToolNames, violationText };