@astralyn/pi 0.84.13 → 0.84.15

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 (202) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/core/agent-session.d.ts.map +1 -1
  3. package/dist/core/agent-session.js +12 -6
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/extensions/types.d.ts +4 -1
  6. package/dist/core/extensions/types.d.ts.map +1 -1
  7. package/dist/core/extensions/types.js.map +1 -1
  8. package/dist/core/tools/bash.d.ts +1 -0
  9. package/dist/core/tools/bash.d.ts.map +1 -1
  10. package/dist/core/tools/bash.js +4 -1
  11. package/dist/core/tools/bash.js.map +1 -1
  12. package/dist/core/tools/find.d.ts +2 -0
  13. package/dist/core/tools/find.d.ts.map +1 -1
  14. package/dist/core/tools/find.js +18 -15
  15. package/dist/core/tools/find.js.map +1 -1
  16. package/dist/extensions/background/actions.d.ts.map +1 -1
  17. package/dist/extensions/background/actions.js +3 -2
  18. package/dist/extensions/background/actions.js.map +1 -1
  19. package/dist/extensions/background/manager.d.ts.map +1 -1
  20. package/dist/extensions/background/manager.js +8 -9
  21. package/dist/extensions/background/manager.js.map +1 -1
  22. package/dist/extensions/background/registry.d.ts +4 -1
  23. package/dist/extensions/background/registry.d.ts.map +1 -1
  24. package/dist/extensions/background/registry.js +30 -17
  25. package/dist/extensions/background/registry.js.map +1 -1
  26. package/dist/extensions/background/task-view.d.ts +6 -0
  27. package/dist/extensions/background/task-view.d.ts.map +1 -1
  28. package/dist/extensions/background/task-view.js +11 -6
  29. package/dist/extensions/background/task-view.js.map +1 -1
  30. package/dist/extensions/deepwiki/client.d.ts.map +1 -1
  31. package/dist/extensions/deepwiki/client.js +3 -0
  32. package/dist/extensions/deepwiki/client.js.map +1 -1
  33. package/dist/extensions/deepwiki/execute.d.ts +2 -1
  34. package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
  35. package/dist/extensions/deepwiki/execute.js +17 -2
  36. package/dist/extensions/deepwiki/execute.js.map +1 -1
  37. package/dist/extensions/deepwiki/http.d.ts +1 -0
  38. package/dist/extensions/deepwiki/http.d.ts.map +1 -1
  39. package/dist/extensions/deepwiki/http.js +16 -2
  40. package/dist/extensions/deepwiki/http.js.map +1 -1
  41. package/dist/extensions/deepwiki/schema.d.ts +1 -1
  42. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  43. package/dist/extensions/deepwiki/schema.js +8 -2
  44. package/dist/extensions/deepwiki/schema.js.map +1 -1
  45. package/dist/extensions/question/dialog.d.ts.map +1 -1
  46. package/dist/extensions/question/dialog.js +80 -9
  47. package/dist/extensions/question/dialog.js.map +1 -1
  48. package/dist/extensions/question/index.d.ts.map +1 -1
  49. package/dist/extensions/question/index.js +8 -0
  50. package/dist/extensions/question/index.js.map +1 -1
  51. package/dist/extensions/question/schema.d.ts +2 -2
  52. package/dist/extensions/question/schema.d.ts.map +1 -1
  53. package/dist/extensions/question/schema.js +41 -11
  54. package/dist/extensions/question/schema.js.map +1 -1
  55. package/dist/extensions/question/types.d.ts +1 -1
  56. package/dist/extensions/question/types.d.ts.map +1 -1
  57. package/dist/extensions/question/types.js.map +1 -1
  58. package/dist/extensions/router/probe.d.ts.map +1 -1
  59. package/dist/extensions/router/probe.js +10 -29
  60. package/dist/extensions/router/probe.js.map +1 -1
  61. package/dist/extensions/router/register.d.ts.map +1 -1
  62. package/dist/extensions/router/register.js +16 -6
  63. package/dist/extensions/router/register.js.map +1 -1
  64. package/dist/extensions/router/store.d.ts.map +1 -1
  65. package/dist/extensions/router/store.js +108 -51
  66. package/dist/extensions/router/store.js.map +1 -1
  67. package/dist/extensions/router/ui.d.ts +6 -0
  68. package/dist/extensions/router/ui.d.ts.map +1 -1
  69. package/dist/extensions/router/ui.js +14 -6
  70. package/dist/extensions/router/ui.js.map +1 -1
  71. package/dist/extensions/statusline/index.d.ts.map +1 -1
  72. package/dist/extensions/statusline/index.js +40 -43
  73. package/dist/extensions/statusline/index.js.map +1 -1
  74. package/dist/extensions/subagent/activity.d.ts +7 -1
  75. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  76. package/dist/extensions/subagent/activity.js +69 -6
  77. package/dist/extensions/subagent/activity.js.map +1 -1
  78. package/dist/extensions/subagent/agents-command.js +1 -1
  79. package/dist/extensions/subagent/agents-command.js.map +1 -1
  80. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  81. package/dist/extensions/subagent/agents.js +0 -3
  82. package/dist/extensions/subagent/agents.js.map +1 -1
  83. package/dist/extensions/subagent/budget.d.ts.map +1 -1
  84. package/dist/extensions/subagent/budget.js +29 -2
  85. package/dist/extensions/subagent/budget.js.map +1 -1
  86. package/dist/extensions/subagent/cancellation.d.ts +4 -4
  87. package/dist/extensions/subagent/cancellation.d.ts.map +1 -1
  88. package/dist/extensions/subagent/cancellation.js +31 -13
  89. package/dist/extensions/subagent/cancellation.js.map +1 -1
  90. package/dist/extensions/subagent/constants.d.ts +1 -0
  91. package/dist/extensions/subagent/constants.d.ts.map +1 -1
  92. package/dist/extensions/subagent/constants.js +1 -0
  93. package/dist/extensions/subagent/constants.js.map +1 -1
  94. package/dist/extensions/subagent/index.d.ts.map +1 -1
  95. package/dist/extensions/subagent/index.js +1 -0
  96. package/dist/extensions/subagent/index.js.map +1 -1
  97. package/dist/extensions/subagent/render.d.ts +8 -1
  98. package/dist/extensions/subagent/render.d.ts.map +1 -1
  99. package/dist/extensions/subagent/render.js +148 -178
  100. package/dist/extensions/subagent/render.js.map +1 -1
  101. package/dist/extensions/subagent/runner.d.ts +1 -0
  102. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  103. package/dist/extensions/subagent/runner.js +53 -44
  104. package/dist/extensions/subagent/runner.js.map +1 -1
  105. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  106. package/dist/extensions/subagent/sdk-runner.js +0 -3
  107. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  108. package/dist/extensions/subagent/settings.d.ts +1 -1
  109. package/dist/extensions/subagent/settings.d.ts.map +1 -1
  110. package/dist/extensions/subagent/settings.js +74 -25
  111. package/dist/extensions/subagent/settings.js.map +1 -1
  112. package/dist/extensions/subagent/state.d.ts +1 -0
  113. package/dist/extensions/subagent/state.d.ts.map +1 -1
  114. package/dist/extensions/subagent/state.js +46 -16
  115. package/dist/extensions/subagent/state.js.map +1 -1
  116. package/dist/extensions/subagent/types.d.ts +0 -7
  117. package/dist/extensions/subagent/types.d.ts.map +1 -1
  118. package/dist/extensions/subagent/types.js.map +1 -1
  119. package/dist/extensions/subagent/ui/agents-dialog.js +1 -1
  120. package/dist/extensions/subagent/ui/agents-dialog.js.map +1 -1
  121. package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
  122. package/dist/extensions/subagent/ui/model-list.js +3 -4
  123. package/dist/extensions/subagent/ui/model-list.js.map +1 -1
  124. package/dist/extensions/subagent/ui/model-picker.d.ts.map +1 -1
  125. package/dist/extensions/subagent/ui/model-picker.js +2 -1
  126. package/dist/extensions/subagent/ui/model-picker.js.map +1 -1
  127. package/dist/extensions/web-search/constants.d.ts +2 -2
  128. package/dist/extensions/web-search/constants.d.ts.map +1 -1
  129. package/dist/extensions/web-search/constants.js +4 -5
  130. package/dist/extensions/web-search/constants.js.map +1 -1
  131. package/dist/extensions/web-search/execute.d.ts +13 -0
  132. package/dist/extensions/web-search/execute.d.ts.map +1 -0
  133. package/dist/extensions/web-search/execute.js +101 -0
  134. package/dist/extensions/web-search/execute.js.map +1 -0
  135. package/dist/extensions/web-search/format.d.ts +12 -0
  136. package/dist/extensions/web-search/format.d.ts.map +1 -0
  137. package/dist/extensions/web-search/format.js +109 -0
  138. package/dist/extensions/web-search/format.js.map +1 -0
  139. package/dist/extensions/web-search/index.d.ts.map +1 -1
  140. package/dist/extensions/web-search/index.js +12 -9
  141. package/dist/extensions/web-search/index.js.map +1 -1
  142. package/dist/extensions/web-search/providers/deepseek.d.ts +0 -2
  143. package/dist/extensions/web-search/providers/deepseek.d.ts.map +1 -1
  144. package/dist/extensions/web-search/providers/deepseek.js +82 -34
  145. package/dist/extensions/web-search/providers/deepseek.js.map +1 -1
  146. package/dist/extensions/web-search/providers/http.d.ts +2 -7
  147. package/dist/extensions/web-search/providers/http.d.ts.map +1 -1
  148. package/dist/extensions/web-search/providers/http.js +30 -13
  149. package/dist/extensions/web-search/providers/http.js.map +1 -1
  150. package/dist/extensions/web-search/providers/minimax.d.ts +0 -2
  151. package/dist/extensions/web-search/providers/minimax.d.ts.map +1 -1
  152. package/dist/extensions/web-search/providers/minimax.js +43 -50
  153. package/dist/extensions/web-search/providers/minimax.js.map +1 -1
  154. package/dist/extensions/web-search/render.d.ts +1 -2
  155. package/dist/extensions/web-search/render.d.ts.map +1 -1
  156. package/dist/extensions/web-search/render.js +22 -17
  157. package/dist/extensions/web-search/render.js.map +1 -1
  158. package/dist/extensions/web-search/results.d.ts +35 -0
  159. package/dist/extensions/web-search/results.d.ts.map +1 -0
  160. package/dist/extensions/web-search/results.js +172 -0
  161. package/dist/extensions/web-search/results.js.map +1 -0
  162. package/dist/extensions/web-search/schema.d.ts +0 -2
  163. package/dist/extensions/web-search/schema.d.ts.map +1 -1
  164. package/dist/extensions/web-search/schema.js +4 -25
  165. package/dist/extensions/web-search/schema.js.map +1 -1
  166. package/dist/extensions/web-search/types.d.ts +0 -62
  167. package/dist/extensions/web-search/types.d.ts.map +1 -1
  168. package/dist/extensions/web-search/types.js.map +1 -1
  169. package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  170. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  171. package/dist/modes/interactive/components/tool-execution.js +7 -0
  172. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  173. package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/tool-group.js +10 -0
  175. package/dist/modes/interactive/components/tool-group.js.map +1 -1
  176. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  177. package/dist/modes/interactive/interactive-mode.js +3 -40
  178. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  179. package/dist/modes/interactive/theme/theme.d.ts +0 -4
  180. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  181. package/dist/modes/interactive/theme/theme.js +16 -23
  182. package/dist/modes/interactive/theme/theme.js.map +1 -1
  183. package/dist/utils/http-response.d.ts +10 -0
  184. package/dist/utils/http-response.d.ts.map +1 -0
  185. package/dist/utils/http-response.js +68 -0
  186. package/dist/utils/http-response.js.map +1 -0
  187. package/docs/bundled/extensions/background.md +2 -1
  188. package/docs/bundled/extensions/deepwiki.md +7 -5
  189. package/docs/bundled/extensions/question.md +6 -4
  190. package/docs/bundled/extensions/router.md +1 -1
  191. package/docs/bundled/extensions/statusline.md +1 -0
  192. package/docs/bundled/extensions/subagent.md +29 -39
  193. package/docs/bundled/extensions/web-search.md +8 -12
  194. package/docs/development.md +7 -2
  195. package/docs/docs.json +4 -0
  196. package/docs/extensions.md +2 -2
  197. package/npm-shrinkwrap.json +2 -2
  198. package/package.json +1 -1
  199. package/dist/extensions/web-search/fusion.d.ts +0 -36
  200. package/dist/extensions/web-search/fusion.d.ts.map +0 -1
  201. package/dist/extensions/web-search/fusion.js +0 -272
  202. package/dist/extensions/web-search/fusion.js.map +0 -1
@@ -307,11 +307,11 @@ async function editRelayFlow(ctx, pi, dialogs, initial) {
307
307
  continue;
308
308
  }
309
309
  if (choice === "apiKey") {
310
- const next = await promptText(ctx, dialogs, `Relay · ${relay.id} · API key`, relay.apiKey, (value) => value.trim() ? undefined : "API key is required.");
310
+ const next = await promptText(ctx, dialogs, `Relay · ${relay.id} · API key`, "Enter a new key · blank keeps the current value");
311
311
  if (next === undefined)
312
312
  continue;
313
313
  const trimmed = next.trim();
314
- if (trimmed === relay.apiKey)
314
+ if (!trimmed || trimmed === relay.apiKey)
315
315
  continue;
316
316
  relay.apiKey = trimmed;
317
317
  await persistRelay(ctx, pi, relay);
@@ -564,12 +564,17 @@ async function fetchAndSelectModels(ctx, pi, dialogs, relay) {
564
564
  return;
565
565
  if (result.truncated)
566
566
  ctx.ui.notify("Catalog truncated to 2,000 models.", "warning");
567
- const catalog = mergeCatalogWithConfigured(relay.models, result.models);
568
- const initiallySelected = new Set(relay.models.map((model) => model.id));
569
567
  const activeModelId = ctx.model?.provider === relay.id ? ctx.model.id : undefined;
570
- const currentModelId = activeModelId && initiallySelected.has(activeModelId) ? activeModelId : undefined;
568
+ const catalog = mergeCatalogWithConfigured(relay.models, result.models, activeModelId);
569
+ const initiallySelected = new Set(relay.models.map((model) => model.id));
570
+ if (activeModelId)
571
+ initiallySelected.add(activeModelId);
572
+ const currentModelId = activeModelId;
571
573
  const protectedIds = currentModelId ? new Set([currentModelId]) : undefined;
572
574
  const preserved = new Map(relay.models.map((model) => [model.id, structuredClone(model)]));
575
+ if (activeModelId && !preserved.has(activeModelId)) {
576
+ preserved.set(activeModelId, createDefaultModelConfig(activeModelId));
577
+ }
573
578
  const saver = new RelayAutoSaver(ctx, pi, relay);
574
579
  const applySelection = (selectedIds) => {
575
580
  if (currentModelId && !selectedIds.includes(currentModelId)) {
@@ -642,7 +647,7 @@ function mergeAddedModels(previous, additions) {
642
647
  }
643
648
  return result;
644
649
  }
645
- function mergeCatalogWithConfigured(configured, catalog) {
650
+ export function mergeCatalogWithConfigured(configured, catalog, activeModelId) {
646
651
  const items = new Map();
647
652
  const configuredById = new Map(configured.map((model) => [model.id, model]));
648
653
  for (const model of catalog) {
@@ -661,6 +666,9 @@ function mergeCatalogWithConfigured(configured, catalog) {
661
666
  });
662
667
  }
663
668
  }
669
+ if (activeModelId && !items.has(activeModelId)) {
670
+ items.set(activeModelId, { id: activeModelId, name: activeModelId, unavailable: true });
671
+ }
664
672
  return [...items.values()].sort((left, right) => left.id.localeCompare(right.id));
665
673
  }
666
674
  function applySelectionIfChanged(relay, selectedIds, apply) {
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/extensions/router/ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * /router interactive flows: list, add, edit, fetch, thinking map.\n *\n * Relay edits are live: confirmed inputs and every toggle persist immediately.\n * Searchable pickers follow Pi's native /model interaction pattern.\n */\n\nimport type { TUI } from \"@earendil-works/pi-tui\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { BorderedLoader } from \"../../modes/interactive/components/bordered-loader.ts\";\nimport { getModelSelectorSearchText } from \"../../modes/interactive/model-search.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { formatError, isValidRelayId, NO_UI_WARNING, ROUTER_THINKING_LEVELS, truncate } from \"./constants.ts\";\nimport {\n\tcreateModelChecklist,\n\tcreateSearchableSelector,\n\tcreateThinkingMapEditor,\n\ttype ModelChecklistItem,\n} from \"./dialog.ts\";\nimport {\n\tcreateNativeRouterDialogs,\n\ttype RouterDialogs,\n\tRouterTuiSession,\n\tRouterTuiSessionClosedError,\n} from \"./dialog-host.ts\";\nimport {\n\tcreateDefaultModelConfig,\n\tdisplayModelLabel,\n\tresolveModelConfig,\n\tresolveRouterThinkingMap,\n\tsummarizeThinkingMap,\n} from \"./presets.ts\";\nimport { probeRelayModels } from \"./probe.ts\";\nimport { applyRouterFile, registerOneRelay, unregisterOneRelay } from \"./register.ts\";\nimport { loadRouterFile, removeRelay, upsertRelay } from \"./store.ts\";\nimport type { RelayConfig, RelayModelConfig } from \"./types.ts\";\n\n/**\n * Serialize live relay mutations without forcing a model-registry refresh for\n * every checkbox press. Provider registration follows each snapshot; the\n * registry is refreshed once when the editor closes.\n */\nclass RelayAutoSaver {\n\tprivate chain: Promise<void> = Promise.resolve();\n\tprivate error: unknown;\n\tprivate needsRefresh = false;\n\tprivate readonly ctx: ExtensionCommandContext;\n\tprivate readonly pi: ExtensionAPI;\n\tprivate readonly relay: RelayConfig;\n\n\tconstructor(ctx: ExtensionCommandContext, pi: ExtensionAPI, relay: RelayConfig) {\n\t\tthis.ctx = ctx;\n\t\tthis.pi = pi;\n\t\tthis.relay = relay;\n\t}\n\n\tsave(): void {\n\t\tconst snapshot = structuredClone(this.relay);\n\t\tthis.needsRefresh = true;\n\t\tthis.chain = this.chain\n\t\t\t.catch(() => {})\n\t\t\t.then(async () => {\n\t\t\t\tawait upsertRelay(snapshot);\n\t\t\t\tregisterOneRelay(this.pi, snapshot);\n\t\t\t\tthis.error = undefined;\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tthis.error = error;\n\t\t\t});\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tawait this.chain;\n\t\tif (this.error !== undefined) {\n\t\t\tconst error = this.error;\n\t\t\tthis.error = undefined;\n\t\t\tthrow error;\n\t\t}\n\t\tif (this.needsRefresh) {\n\t\t\tthis.needsRefresh = false;\n\t\t\tawait this.ctx.modelRegistry.refresh();\n\t\t}\n\t}\n}\n\n/** Abort the catalog request if its internal page or the whole Router session is disposed. */\nclass RouterProbeLoader extends BorderedLoader {\n\treadonly probeSignal: AbortSignal;\n\tprivate readonly disposeController = new AbortController();\n\n\tconstructor(tui: TUI, theme: Theme, message: string) {\n\t\tsuper(tui, theme, message, { cancellable: true });\n\t\tthis.probeSignal = AbortSignal.any([this.signal, this.disposeController.signal]);\n\t}\n\n\toverride dispose(): void {\n\t\tthis.disposeController.abort();\n\t\tsuper.dispose();\n\t}\n}\n\nexport function isCurrentRouterModel(\n\tcurrent: { provider: string; id: string } | undefined,\n\trelayId: string,\n\tmodelId: string,\n): boolean {\n\treturn current?.provider === relayId && current.id === modelId;\n}\n\nexport async function runRouterCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(NO_UI_WARNING, \"warning\");\n\t\treturn;\n\t}\n\tconst trimmed = args.trim().toLowerCase();\n\tif (trimmed === \"reload\") {\n\t\tconst file = await loadRouterFile();\n\t\tapplyRouterFile(pi, file);\n\t\tawait ctx.modelRegistry.refresh();\n\t\tctx.ui.notify(`Reloaded ${file.relays.length} relay(s).`, \"info\");\n\t\treturn;\n\t}\n\tif (ctx.mode === \"tui\") {\n\t\tawait runRouterTuiCommand(args, ctx, pi);\n\t\treturn;\n\t}\n\tawait runRouterDialogCommand(args, ctx, pi, createNativeRouterDialogs(ctx));\n}\n\nasync function runRouterTuiCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {\n\tlet failure: { error: unknown } | undefined;\n\tlet closedDuringTransition = false;\n\tawait ctx.ui.custom<void>((tui, theme, keybindings, done) => {\n\t\tconst session = new RouterTuiSession(tui, theme, keybindings, () => {\n\t\t\tclosedDuringTransition = true;\n\t\t\tdone();\n\t\t});\n\t\tvoid runRouterDialogCommand(args, ctx, pi, session).then(\n\t\t\t() => {\n\t\t\t\tif (!closedDuringTransition) done();\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (closedDuringTransition) {\n\t\t\t\t\tif (!(error instanceof RouterTuiSessionClosedError)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tctx.ui.notify(formatError(error), \"error\");\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// The command context may have gone stale after the modal closed.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfailure = { error };\n\t\t\t\tdone();\n\t\t\t},\n\t\t);\n\t\treturn session;\n\t});\n\tif (failure) throw failure.error;\n}\n\nasync function runRouterDialogCommand(\n\targs: string,\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n): Promise<void> {\n\tconst trimmed = args.trim().toLowerCase();\n\tif (!trimmed || trimmed === \"list\") {\n\t\tawait openMainMenu(ctx, pi, dialogs);\n\t\treturn;\n\t}\n\tif (trimmed === \"add\") {\n\t\tawait addRelayFlow(ctx, pi, dialogs);\n\t\treturn;\n\t}\n\t// Treat as relay id open.\n\tconst file = await loadRouterFile();\n\tconst exact = file.relays.find((relay) => relay.id.toLowerCase() === trimmed);\n\tif (exact) {\n\t\tawait editRelayFlow(ctx, pi, dialogs, exact);\n\t\treturn;\n\t}\n\tawait openMainMenu(ctx, pi, dialogs, args.trim());\n}\n\nasync function openMainMenu(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\tinitialQuery?: string,\n): Promise<void> {\n\tlet cursor: string | undefined;\n\tlet query = initialQuery;\n\twhile (true) {\n\t\tconst file = await loadRouterFile();\n\t\t// Relays first (primary content), actions at the bottom.\n\t\tconst items = [\n\t\t\t...file.relays.map((relay) => ({\n\t\t\t\tvalue: `relay:${relay.id}`,\n\t\t\t\tlabel: relay.id,\n\t\t\t\tdescription: `${relay.models.length} model${relay.models.length === 1 ? \"\" : \"s\"} · ${truncate(relay.baseUrl, 40)}`,\n\t\t\t\tsearchText: `${relay.id} ${relay.baseUrl}`,\n\t\t\t})),\n\t\t\t{\n\t\t\t\tvalue: \"action:add\",\n\t\t\t\tlabel: \"+ Add relay\",\n\t\t\t\tdescription: \"Name · base URL · API key · fetch models\",\n\t\t\t\tsearchText: \"add create new relay gateway\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tvalue: \"action:reload\",\n\t\t\t\tlabel: \"Reload from disk\",\n\t\t\t\tdescription: \"Re-register providers from router.json\",\n\t\t\t\tsearchText: \"reload refresh\",\n\t\t\t},\n\t\t];\n\n\t\tconst selected =\n\t\t\tdialogs.kind === \"tui\"\n\t\t\t\t? await dialogs.show(\n\t\t\t\t\t\tcreateSearchableSelector({\n\t\t\t\t\t\t\ttitle: \"API relays\",\n\t\t\t\t\t\t\tsubtitle:\n\t\t\t\t\t\t\t\tfile.relays.length === 0\n\t\t\t\t\t\t\t\t\t? \"No relays yet — add a base URL + API key.\"\n\t\t\t\t\t\t\t\t\t: `${file.relays.length} relay${file.relays.length === 1 ? \"\" : \"s\"} · Enter opens · Esc closes`,\n\t\t\t\t\t\t\titems,\n\t\t\t\t\t\t\tinitialValue: cursor,\n\t\t\t\t\t\t\tinitialQuery: query,\n\t\t\t\t\t\t\tmaxVisible: 10,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t: await selectRouterItem(\n\t\t\t\t\t\tdialogs,\n\t\t\t\t\t\t\"API relays\",\n\t\t\t\t\t\titems.map((item) => ({ value: item.value, label: item.label, description: item.description })),\n\t\t\t\t\t);\n\n\t\tquery = undefined;\n\t\tif (selected === undefined) return;\n\t\tcursor = selected;\n\n\t\tif (selected === \"action:add\") {\n\t\t\tconst id = await addRelayFlow(ctx, pi, dialogs);\n\t\t\tif (id) cursor = `relay:${id}`;\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected === \"action:reload\") {\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tapplyRouterFile(pi, latest);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Reloaded ${latest.relays.length} relay(s).`, \"info\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected.startsWith(\"relay:\")) {\n\t\t\tconst id = selected.slice(\"relay:\".length);\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tconst relay = latest.relays.find((entry) => entry.id === id);\n\t\t\tif (!relay) {\n\t\t\t\tctx.ui.notify(`Relay \"${id}\" not found.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait editRelayFlow(ctx, pi, dialogs, relay);\n\t\t}\n\t}\n}\n\nasync function addRelayFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n): Promise<string | undefined> {\n\tconst file = await loadRouterFile();\n\tconst existing = new Set(file.relays.map((relay) => relay.id));\n\n\tconst id = await promptText(ctx, dialogs, \"New relay · name (provider id)\", \"my-relay\", (value) => {\n\t\tconst trimmed = value.trim();\n\t\tif (!trimmed) return \"Name is required.\";\n\t\tif (!isValidRelayId(trimmed)) return \"Name cannot be empty or contain '/'.\";\n\t\tif (existing.has(trimmed)) return `Relay \"${trimmed}\" already exists.`;\n\t\treturn undefined;\n\t});\n\tif (id === undefined) return undefined;\n\n\tconst baseUrl = await promptText(\n\t\tctx,\n\t\tdialogs,\n\t\t`New relay · ${id.trim()} · base URL`,\n\t\t\"https://relay.example/v1\",\n\t\t(value) => {\n\t\t\tconst trimmed = value.trim();\n\t\t\tif (!trimmed) return \"Base URL is required.\";\n\t\t\ttry {\n\t\t\t\tconst url = new URL(trimmed);\n\t\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t\t} catch {\n\t\t\t\treturn \"Invalid URL.\";\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t);\n\tif (baseUrl === undefined) return undefined;\n\n\tconst apiKey = await promptText(\n\t\tctx,\n\t\tdialogs,\n\t\t`New relay · ${id.trim()} · API key`,\n\t\t\"sk-… or $RELAY_KEY\",\n\t\t(value) => {\n\t\t\tif (!value.trim()) return \"API key is required.\";\n\t\t\treturn undefined;\n\t\t},\n\t);\n\tif (apiKey === undefined) return undefined;\n\n\tconst relay: RelayConfig = {\n\t\tid: id.trim(),\n\t\tbaseUrl: baseUrl.trim().replace(/\\/+$/, \"\"),\n\t\tapiKey: apiKey.trim(),\n\t\tmodels: [],\n\t};\n\n\t// Connection fields are committed before the network step so cancelling or\n\t// failing catalog discovery never loses the relay the user just entered.\n\tawait persistRelay(ctx, pi, relay);\n\tawait fetchAndSelectModels(ctx, pi, dialogs, relay);\n\tif (relay.models.length === 0) {\n\t\tctx.ui.notify(`Relay \"${relay.id}\" has no models yet.`, \"warning\");\n\t}\n\treturn relay.id;\n}\n\n/**\n * Relay editor — flat menu. Every mutation writes router.json immediately.\n * Hierarchy: list → relay → (models list | connection field | fetch | remove).\n */\nasync function editRelayFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\tinitial: RelayConfig,\n): Promise<void> {\n\tconst relay = structuredClone(initial);\n\twhile (true) {\n\t\tconst modelSummary =\n\t\t\trelay.models.length === 0\n\t\t\t\t? \"none yet — fetch catalog\"\n\t\t\t\t: relay.models.length <= 3\n\t\t\t\t\t? relay.models.map((m) => displayModelLabel(m)).join(\", \")\n\t\t\t\t\t: `${relay.models.length} models · ${relay.models\n\t\t\t\t\t\t\t.slice(0, 2)\n\t\t\t\t\t\t\t.map((m) => displayModelLabel(m))\n\t\t\t\t\t\t\t.join(\", \")}…`;\n\n\t\tconst choice = await selectRouterItem(dialogs, `Relay · ${relay.id}`, [\n\t\t\t{\n\t\t\t\tvalue: \"models\",\n\t\t\t\tlabel: \"Models\",\n\t\t\t\tdescription: modelSummary,\n\t\t\t},\n\t\t\t{ value: \"baseUrl\", label: \"Base URL\", description: relay.baseUrl },\n\t\t\t{ value: \"apiKey\", label: \"API key\", description: maskKey(relay.apiKey) },\n\t\t\t{ value: \"remove\", label: \"Remove relay\", description: \"Delete from router.json\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relays\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"back\") return;\n\n\t\tif (choice === \"baseUrl\") {\n\t\t\tconst next = await promptText(ctx, dialogs, `Relay · ${relay.id} · base URL`, relay.baseUrl, (value) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst url = new URL(value.trim());\n\t\t\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t\t\t} catch {\n\t\t\t\t\treturn \"Invalid URL.\";\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t\tif (next === undefined) continue;\n\t\t\tconst normalized = next.trim().replace(/\\/+$/, \"\");\n\t\t\tif (normalized === relay.baseUrl) continue;\n\t\t\trelay.baseUrl = normalized;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"apiKey\") {\n\t\t\tconst next = await promptText(ctx, dialogs, `Relay · ${relay.id} · API key`, relay.apiKey, (value) =>\n\t\t\t\tvalue.trim() ? undefined : \"API key is required.\",\n\t\t\t);\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tif (trimmed === relay.apiKey) continue;\n\t\t\trelay.apiKey = trimmed;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"models\") {\n\t\t\t// Always open the models screen (fetch lives only here). Empty list still\n\t\t\t// shows Fetch so the path is Relay → Models → Fetch, not a top-level shortcut.\n\t\t\tawait manageModelsFlow(ctx, pi, dialogs, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"remove\") {\n\t\t\tif (ctx.model?.provider === relay.id) {\n\t\t\t\tctx.ui.notify(`Switch away from relay \"${relay.id}\" before removing it.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ok = await dialogs.confirm(`Remove relay \"${relay.id}\"?`, \"Models will disappear from /model.\");\n\t\t\tif (!ok) continue;\n\t\t\tawait removeRelay(relay.id);\n\t\t\tunregisterOneRelay(pi, relay.id);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Removed relay \"${relay.id}\".`, \"info\");\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * Models screen: searchable configured models plus fetch/manual-add actions.\n * Selecting a model opens its editor (name / thinking / remove).\n */\nasync function manageModelsFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tlet cursor: string | undefined;\n\twhile (true) {\n\t\tconst items: Array<{ value: string; label: string; description?: string; searchText?: string }> = [\n\t\t\t...relay.models.map((model) => {\n\t\t\t\tconst resolved = resolveModelConfig(model);\n\t\t\t\tconst label = displayModelLabel(resolved);\n\t\t\t\tconst thinking = summarizeThinkingMap(resolved.thinkingLevelMap);\n\t\t\t\tconst current = ctx.model?.provider === relay.id && ctx.model.id === model.id ? \" ✓\" : \"\";\n\t\t\t\treturn {\n\t\t\t\t\tvalue: `model:${model.id}`,\n\t\t\t\t\tlabel: `${model.id}${current}`,\n\t\t\t\t\tdescription: label !== model.id ? `${label} · ${thinking}` : thinking,\n\t\t\t\t\tsearchText: `${getModelSelectorSearchText({ id: model.id, provider: relay.id, name: resolved.name })} ${thinking}`,\n\t\t\t\t};\n\t\t\t}),\n\t\t\t{\n\t\t\t\tvalue: \"action:fetch\",\n\t\t\t\tlabel: \"Fetch catalog\",\n\t\t\t\tdescription:\n\t\t\t\t\trelay.models.length === 0\n\t\t\t\t\t\t? \"GET /models · select models\"\n\t\t\t\t\t\t: \"Refresh from server · keeps selected customizations\",\n\t\t\t\tsearchText: \"fetch catalog refresh models server\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tvalue: \"action:manual\",\n\t\t\t\tlabel: \"Add models manually\",\n\t\t\t\tdescription: \"Comma- or newline-separated model ids\",\n\t\t\t\tsearchText: \"add manual custom model ids\",\n\t\t\t},\n\t\t\t{ value: \"action:back\", label: \"Back\", description: \"Return to relay\", searchText: \"back return\" },\n\t\t];\n\n\t\tconst currentValue = `model:${ctx.model?.id}`;\n\t\tconst initialValue = cursor ?? (ctx.model?.provider === relay.id ? currentValue : undefined);\n\t\tconst choice = await selectRouterItem(dialogs, `Relay · ${relay.id} · models`, items, { initialValue });\n\t\tif (choice === undefined || choice === \"action:back\") return;\n\t\tcursor = choice;\n\n\t\tif (choice === \"action:fetch\") {\n\t\t\tawait fetchAndSelectModels(ctx, pi, dialogs, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"action:manual\") {\n\t\t\tconst additions = await manualModelEntry(ctx, dialogs);\n\t\t\tif (!additions) continue;\n\t\t\trelay.models = mergeAddedModels(relay.models, additions);\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice.startsWith(\"model:\")) {\n\t\t\tconst modelId = choice.slice(\"model:\".length);\n\t\t\tconst model = relay.models.find((entry) => entry.id === modelId);\n\t\t\tif (!model) continue;\n\t\t\tawait editModelFlow(ctx, pi, dialogs, relay, model);\n\t\t}\n\t}\n}\n\n/** Single-model editor: display name + thinking. Every confirmed change is live. */\nasync function editModelFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n\tmodel: RelayModelConfig,\n): Promise<void> {\n\twhile (true) {\n\t\tconst resolved = resolveModelConfig(model);\n\t\tconst nameDesc = resolved.name ? resolved.name : \"(empty · /model shows id)\";\n\t\tconst action = await selectRouterItem(dialogs, `Relay · ${relay.id} · ${model.id}`, [\n\t\t\t{ value: \"name\", label: \"Display name\", description: nameDesc },\n\t\t\t{\n\t\t\t\tvalue: \"thinking\",\n\t\t\t\tlabel: \"Thinking levels\",\n\t\t\t\tdescription: summarizeThinkingMap(resolved.thinkingLevelMap),\n\t\t\t},\n\t\t\t{ value: \"remove\", label: \"Remove model\", description: \"Delete this model from the relay\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to models\" },\n\t\t]);\n\t\tif (action === undefined || action === \"back\") return;\n\n\t\tif (action === \"name\") {\n\t\t\tconst next = await promptText(\n\t\t\t\tctx,\n\t\t\t\tdialogs,\n\t\t\t\t`Display name · ${model.id} (empty = show id)`,\n\t\t\t\tresolved.name ?? \"\",\n\t\t\t);\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tconst nextName = !trimmed || trimmed === model.id ? undefined : trimmed;\n\t\t\tconst prevName = model.name?.trim() && model.name.trim() !== model.id ? model.name.trim() : undefined;\n\t\t\tif (nextName === prevName) continue;\n\t\t\tif (nextName) model.name = nextName;\n\t\t\telse delete model.name;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"thinking\") {\n\t\t\tconst saver = new RelayAutoSaver(ctx, pi, relay);\n\t\t\tif (dialogs.kind === \"tui\") {\n\t\t\t\tawait dialogs.show(\n\t\t\t\t\tcreateThinkingMapEditor({\n\t\t\t\t\t\ttitle: `Thinking · ${relay.id} / ${model.id}`,\n\t\t\t\t\t\tmap: resolved.thinkingLevelMap,\n\t\t\t\t\t\tlevels: ROUTER_THINKING_LEVELS,\n\t\t\t\t\t\tonChange: (nextMap) => {\n\t\t\t\t\t\t\tmodel.thinkingLevelMap = nextMap;\n\t\t\t\t\t\t\tmodel.reasoning = true;\n\t\t\t\t\t\t\tsaver.save();\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait editThinkingMapNative(dialogs, resolved.thinkingLevelMap, (nextMap) => {\n\t\t\t\t\tmodel.thinkingLevelMap = nextMap;\n\t\t\t\t\tmodel.reasoning = true;\n\t\t\t\t\tsaver.save();\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait saver.flush();\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"remove\") {\n\t\t\tif (isCurrentRouterModel(ctx.model, relay.id, model.id)) {\n\t\t\t\tctx.ui.notify(`Switch away from model \"${model.id}\" before removing it.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ok = await dialogs.confirm(\n\t\t\t\t`Remove model \"${model.id}\"?`,\n\t\t\t\t\"Its display name and thinking settings will be removed.\",\n\t\t\t);\n\t\t\tif (!ok) continue;\n\t\t\trelay.models = relay.models.filter((entry) => entry.id !== model.id);\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tctx.ui.notify(`Removed model \"${model.id}\".`, \"info\");\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nasync function editThinkingMapNative(\n\tdialogs: RouterDialogs,\n\tmap: RelayModelConfig[\"thinkingLevelMap\"],\n\tonChange: (map: RelayModelConfig[\"thinkingLevelMap\"]) => void,\n): Promise<void> {\n\tlet working = resolveRouterThinkingMap(map);\n\twhile (true) {\n\t\tconst choice = await selectRouterItem(dialogs, \"Toggle thinking level\", [\n\t\t\t...ROUTER_THINKING_LEVELS.map((level) => ({\n\t\t\t\tvalue: level,\n\t\t\t\tlabel: level,\n\t\t\t\tdescription:\n\t\t\t\t\tworking[level] === null ? \"hidden\" : working[level] === undefined ? \"default\" : String(working[level]),\n\t\t\t})),\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Changes are live\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"back\") return;\n\t\tif (!ROUTER_THINKING_LEVELS.includes(choice as (typeof ROUTER_THINKING_LEVELS)[number])) continue;\n\t\tconst level = choice as (typeof ROUTER_THINKING_LEVELS)[number];\n\t\tworking = {\n\t\t\t...working,\n\t\t\t[level]: working[level] === null ? level : null,\n\t\t\toff: null,\n\t\t\tminimal: null,\n\t\t};\n\t\tonChange({ ...working });\n\t}\n}\n\nasync function fetchAndSelectModels(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tconst key = resolveProbeApiKey(relay.apiKey);\n\tif (key.error) {\n\t\tctx.ui.notify(key.error, \"warning\");\n\t\tawait recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\treturn;\n\t}\n\n\tlet result: Awaited<ReturnType<typeof probeRelayModels>> | undefined;\n\twhile (true) {\n\t\tconst probeOptions = { baseUrl: relay.baseUrl, apiKey: key.value };\n\t\tif (dialogs.kind === \"tui\") {\n\t\t\tresult = await dialogs.show<Awaited<ReturnType<typeof probeRelayModels>> | undefined>(\n\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\tconst loader = new RouterProbeLoader(tui, theme, `Fetching models · ${relay.id}`);\n\t\t\t\t\tlet settled = false;\n\t\t\t\t\tconst finish = (value: Awaited<ReturnType<typeof probeRelayModels>> | undefined) => {\n\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tloader.dispose();\n\t\t\t\t\t\tdone(value);\n\t\t\t\t\t};\n\t\t\t\t\tloader.onAbort = () => finish(undefined);\n\t\t\t\t\tvoid probeRelayModels({ ...probeOptions, signal: loader.probeSignal })\n\t\t\t\t\t\t.then(finish)\n\t\t\t\t\t\t.catch((error) => finish({ ok: false, error: formatError(error) }));\n\t\t\t\t\treturn loader;\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tctx.ui.notify(`Fetching models from ${relay.baseUrl}…`, \"info\");\n\t\t\tresult = await probeRelayModels(probeOptions);\n\t\t}\n\n\t\tif (result === undefined) return;\n\t\tif (result.ok && result.models.length === 0) {\n\t\t\tctx.ui.notify(\"Server returned an empty model list.\", \"warning\");\n\t\t\tconst recovery = await selectRouterItem(dialogs, `Catalog empty · ${relay.id}`, [\n\t\t\t\t{ value: \"retry\", label: \"Retry\", description: \"Fetch /models again\" },\n\t\t\t\t{ value: \"manual\", label: \"Add models manually\", description: \"Enter model ids without a catalog\" },\n\t\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relay settings\" },\n\t\t\t]);\n\t\t\tif (recovery === \"retry\") continue;\n\t\t\tif (recovery === \"manual\") await recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\t\treturn;\n\t\t}\n\t\tif (result.ok) break;\n\n\t\tctx.ui.notify(`Fetch failed: ${result.error}`, \"error\");\n\t\tconst recovery = await selectRouterItem(dialogs, `Catalog unavailable · ${relay.id}`, [\n\t\t\t{ value: \"retry\", label: \"Retry\", description: \"Fetch /models again\" },\n\t\t\t{ value: \"manual\", label: \"Add models manually\", description: \"Enter model ids without a catalog\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relay settings\" },\n\t\t]);\n\t\tif (recovery === \"retry\") continue;\n\t\tif (recovery === \"manual\") await recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\treturn;\n\t}\n\n\tif (!result || !result.ok) return;\n\tif (result.truncated) ctx.ui.notify(\"Catalog truncated to 2,000 models.\", \"warning\");\n\n\tconst catalog = mergeCatalogWithConfigured(relay.models, result.models);\n\tconst initiallySelected = new Set(relay.models.map((model) => model.id));\n\tconst activeModelId = ctx.model?.provider === relay.id ? ctx.model.id : undefined;\n\tconst currentModelId = activeModelId && initiallySelected.has(activeModelId) ? activeModelId : undefined;\n\tconst protectedIds = currentModelId ? new Set([currentModelId]) : undefined;\n\tconst preserved = new Map(relay.models.map((model) => [model.id, structuredClone(model)]));\n\tconst saver = new RelayAutoSaver(ctx, pi, relay);\n\tconst applySelection = (selectedIds: string[]) => {\n\t\tif (currentModelId && !selectedIds.includes(currentModelId)) {\n\t\t\tctx.ui.notify(`Switch away from model \"${currentModelId}\" before disabling it.`, \"warning\");\n\t\t\treturn;\n\t\t}\n\t\trelay.models = selectedIds.map((id) => {\n\t\t\tconst previous = preserved.get(id);\n\t\t\tif (previous) return structuredClone(previous);\n\t\t\tconst next = createDefaultModelConfig(id);\n\t\t\tpreserved.set(id, next);\n\t\t\treturn structuredClone(next);\n\t\t});\n\t\tsaver.save();\n\t};\n\n\tif (dialogs.kind === \"tui\") {\n\t\tconst choice = await dialogs.show(\n\t\t\tcreateModelChecklist({\n\t\t\t\ttitle: `Select models · ${relay.id}`,\n\t\t\t\tsubtitle: \"Space toggles immediately · Enter/Esc returns\",\n\t\t\t\tmodels: catalog,\n\t\t\t\tinitiallySelected,\n\t\t\t\tprotectedIds,\n\t\t\t\tonChange: applySelection,\n\t\t\t\tonProtectedToggle: (id) => ctx.ui.notify(`Switch away from model \"${id}\" before disabling it.`, \"warning\"),\n\t\t\t}),\n\t\t);\n\t\tif (choice.kind === \"close\") applySelectionIfChanged(relay, choice.selectedIds, applySelection);\n\t} else {\n\t\tconst ok = await dialogs.confirm(\n\t\t\t`Import ${result.models.length} models?`,\n\t\t\t\"Non-TUI mode imports the full catalog.\",\n\t\t);\n\t\tif (ok) applySelection([...new Set([...initiallySelected, ...result.models.map((model) => model.id)])]);\n\t}\n\tawait saver.flush();\n\tif (relay.models.length === 0) ctx.ui.notify(`No models enabled for \"${relay.id}\".`, \"warning\");\n}\n\nasync function manualModelEntry(\n\tctx: ExtensionCommandContext,\n\tdialogs: RouterDialogs,\n): Promise<RelayModelConfig[] | undefined> {\n\tconst value = await dialogs.input(\"Model IDs (comma-separated)\", \"gpt-5.6-sol, gpt-5.6-luna\");\n\tif (value === undefined) return undefined;\n\tconst ids = [\n\t\t...new Set(\n\t\t\tvalue\n\t\t\t\t.split(/[,\\r\\n]+/)\n\t\t\t\t.map((id) => id.trim())\n\t\t\t\t.filter(Boolean),\n\t\t),\n\t];\n\tif (ids.length === 0) {\n\t\tctx.ui.notify(\"Enter at least one model id.\", \"warning\");\n\t\treturn undefined;\n\t}\n\treturn ids.map((id) => createDefaultModelConfig(id));\n}\n\nasync function recoverWithManualModels(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tconst additions = await manualModelEntry(ctx, dialogs);\n\tif (!additions) return;\n\trelay.models = mergeAddedModels(relay.models, additions);\n\tawait persistRelay(ctx, pi, relay);\n}\n\nfunction mergeAddedModels(previous: RelayModelConfig[], additions: RelayModelConfig[]): RelayModelConfig[] {\n\tconst result = previous.map((model) => structuredClone(model));\n\tconst ids = new Set(result.map((model) => model.id));\n\tfor (const model of additions) {\n\t\tif (ids.has(model.id)) continue;\n\t\tids.add(model.id);\n\t\tresult.push(model);\n\t}\n\treturn result;\n}\n\nfunction mergeCatalogWithConfigured(\n\tconfigured: ReadonlyArray<RelayModelConfig>,\n\tcatalog: ReadonlyArray<{ id: string; name?: string }>,\n): ModelChecklistItem[] {\n\tconst items = new Map<string, ModelChecklistItem>();\n\tconst configuredById = new Map(configured.map((model) => [model.id, model]));\n\tfor (const model of catalog) {\n\t\tconst previous = configuredById.get(model.id);\n\t\titems.set(model.id, {\n\t\t\tid: model.id,\n\t\t\tname: previous?.name ?? model.name,\n\t\t});\n\t}\n\tfor (const model of configured) {\n\t\tif (!items.has(model.id)) {\n\t\t\titems.set(model.id, {\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name ?? model.id,\n\t\t\t\tunavailable: true,\n\t\t\t});\n\t\t}\n\t}\n\treturn [...items.values()].sort((left, right) => left.id.localeCompare(right.id));\n}\n\nfunction applySelectionIfChanged(\n\trelay: RelayConfig,\n\tselectedIds: ReadonlyArray<string>,\n\tapply: (ids: string[]) => void,\n): void {\n\tconst current = new Set(relay.models.map((model) => model.id));\n\tif (current.size === selectedIds.length && selectedIds.every((id) => current.has(id))) return;\n\tapply([...selectedIds]);\n}\n\nasync function persistRelay(ctx: ExtensionCommandContext, pi: ExtensionAPI, relay: RelayConfig): Promise<void> {\n\tawait upsertRelay(relay);\n\tregisterOneRelay(pi, relay);\n\tawait ctx.modelRegistry.refresh();\n}\n\nasync function promptText(\n\tctx: ExtensionCommandContext,\n\tdialogs: RouterDialogs,\n\ttitle: string,\n\tplaceholder: string,\n\tvalidate?: (value: string) => string | undefined,\n): Promise<string | undefined> {\n\twhile (true) {\n\t\tconst value = await dialogs.input(title, placeholder);\n\t\tif (value === undefined) return undefined;\n\t\tconst error = validate?.(value);\n\t\tif (error) {\n\t\t\tctx.ui.notify(error, \"warning\");\n\t\t\tcontinue;\n\t\t}\n\t\treturn value;\n\t}\n}\n\nasync function selectRouterItem<T extends string>(\n\tdialogs: RouterDialogs,\n\ttitle: string,\n\titems: ReadonlyArray<{ value: T; label: string; description?: string; searchText?: string }>,\n\topts?: { initialValue?: T; initialQuery?: string; maxVisible?: number },\n): Promise<T | undefined> {\n\tif (dialogs.kind === \"tui\") {\n\t\treturn dialogs.show(\n\t\t\tcreateSearchableSelector({\n\t\t\t\ttitle,\n\t\t\t\titems,\n\t\t\t\tinitialValue: opts?.initialValue,\n\t\t\t\tinitialQuery: opts?.initialQuery,\n\t\t\t\tmaxVisible: opts?.maxVisible ?? Math.min(10, Math.max(1, items.length)),\n\t\t\t}),\n\t\t);\n\t}\n\tconst labels = items.map((item) => (item.description ? `${item.label} — ${item.description}` : item.label));\n\tconst selected = await dialogs.select(title, labels);\n\tif (selected === undefined) return undefined;\n\treturn items[labels.indexOf(selected)]?.value;\n}\n\nfunction maskKey(key: string): string {\n\tif (key.startsWith(\"$\") || key.startsWith(\"!\")) return key;\n\tif (key.length <= 8) return \"••••\";\n\treturn `${key.slice(0, 4)}…${key.slice(-4)}`;\n}\n\n/** Resolve only keys that can be safely used by the catalog probe. */\nexport function resolveProbeApiKey(apiKey: string): { value?: string; error?: string } {\n\tconst trimmed = apiKey.trim();\n\tif (!trimmed) return {};\n\tif (trimmed.startsWith(\"!\")) {\n\t\treturn { error: \"This API key uses a !command and cannot be resolved for catalog probing.\" };\n\t}\n\tconst envOnly = trimmed.match(/^\\$([A-Za-z_][A-Za-z0-9_]*)$/);\n\tconst braced = trimmed.match(/^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/);\n\tconst envName = envOnly?.[1] ?? braced?.[1];\n\tif (envName) {\n\t\tconst value = process.env[envName]?.trim();\n\t\treturn value ? { value } : { error: `Environment variable $${envName} is not set.` };\n\t}\n\tif (trimmed.includes(\"$\")) {\n\t\treturn { error: \"This API key contains interpolation and cannot be resolved for catalog probing.\" };\n\t}\n\treturn { value: trimmed };\n}\n"]}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/extensions/router/ui.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,uDAAuD,CAAC;AACvF,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AAErF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC9G,OAAO,EACN,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GAEvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,yBAAyB,EAEzB,gBAAgB,EAChB,2BAA2B,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGtE;;;;GAIG;AACH,MAAM,cAAc;IAQnB,YAAY,GAA4B,EAAE,EAAgB,EAAE,KAAkB;QAPtE,UAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;QAEzC,iBAAY,GAAG,KAAK,CAAC;QAM5B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,IAAI;QACH,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;aACrB,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;aACf,IAAI,CAAC,KAAK,IAAI,EAAE;YAChB,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC5B,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACV,MAAM,IAAI,CAAC,KAAK,CAAC;QACjB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,MAAM,KAAK,CAAC;QACb,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;YAC1B,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QACxC,CAAC;IACF,CAAC;CACD;AAED,8FAA8F;AAC9F,MAAM,iBAAkB,SAAQ,cAAc;IAI7C,YAAY,GAAQ,EAAE,KAAY,EAAE,OAAe;QAClD,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAHlC,sBAAiB,GAAG,IAAI,eAAe,EAAE,CAAC;QAI1D,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IAClF,CAAC;IAEQ,OAAO;QACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,KAAK,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACD;AAED,MAAM,UAAU,oBAAoB,CACnC,OAAqD,EACrD,OAAe,EACf,OAAe;IAEf,OAAO,OAAO,EAAE,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC;AAChE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY,EAAE,GAA4B,EAAE,EAAgB;IAClG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAChB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACxC,OAAO;IACR,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;QACpC,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC1B,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAClC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,MAAM,YAAY,EAAE,MAAM,CAAC,CAAC;QAClE,OAAO;IACR,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACxB,MAAM,mBAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACzC,OAAO;IACR,CAAC;IACD,MAAM,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,yBAAyB,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAAY,EAAE,GAA4B,EAAE,EAAgB;IAC9F,IAAI,OAAuC,CAAC;IAC5C,IAAI,sBAAsB,GAAG,KAAK,CAAC;IACnC,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAO,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;QAC3D,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE;YAClE,sBAAsB,GAAG,IAAI,CAAC;YAC9B,IAAI,EAAE,CAAC;QACR,CAAC,CAAC,CAAC;QACH,KAAK,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CACvD,GAAG,EAAE;YACJ,IAAI,CAAC,sBAAsB;gBAAE,IAAI,EAAE,CAAC;QACrC,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YAClB,IAAI,sBAAsB,EAAE,CAAC;gBAC5B,IAAI,CAAC,CAAC,KAAK,YAAY,2BAA2B,CAAC,EAAE,CAAC;oBACrD,IAAI,CAAC;wBACJ,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;oBAC5C,CAAC;oBAAC,MAAM,CAAC;wBACR,kEAAkE;oBACnE,CAAC;gBACF,CAAC;gBACD,OAAO;YACR,CAAC;YACD,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;YACpB,IAAI,EAAE,CAAC;QACR,CAAC,CACD,CAAC;QACF,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,IAAI,OAAO;QAAE,MAAM,OAAO,CAAC,KAAK,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,sBAAsB,CACpC,IAAY,EACZ,GAA4B,EAC5B,EAAgB,EAChB,OAAsB;IAEtB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACpC,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QACrC,OAAO;IACR,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACvB,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QACrC,OAAO;IACR,CAAC;IACD,0BAA0B;IAC1B,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,CAAC;IAC9E,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO;IACR,CAAC;IACD,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,YAAY,CAC1B,GAA4B,EAC5B,EAAgB,EAChB,OAAsB,EACtB,YAAqB;IAErB,IAAI,MAA0B,CAAC;IAC/B,IAAI,KAAK,GAAG,YAAY,CAAC;IACzB,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;QACpC,yDAAyD;QACzD,MAAM,KAAK,GAAG;YACb,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC9B,KAAK,EAAE,SAAS,KAAK,CAAC,EAAE,EAAE;gBAC1B,KAAK,EAAE,KAAK,CAAC,EAAE;gBACf,WAAW,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,SAAS,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE;gBACnH,UAAU,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE;aAC1C,CAAC,CAAC;YACH;gBACC,KAAK,EAAE,YAAY;gBACnB,KAAK,EAAE,aAAa;gBACpB,WAAW,EAAE,0CAA0C;gBACvD,UAAU,EAAE,8BAA8B;aAC1C;YACD;gBACC,KAAK,EAAE,eAAe;gBACtB,KAAK,EAAE,kBAAkB;gBACzB,WAAW,EAAE,wCAAwC;gBACrD,UAAU,EAAE,gBAAgB;aAC5B;SACD,CAAC;QAEF,MAAM,QAAQ,GACb,OAAO,CAAC,IAAI,KAAK,KAAK;YACrB,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAClB,wBAAwB,CAAC;gBACxB,KAAK,EAAE,YAAY;gBACnB,QAAQ,EACP,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;oBACvB,CAAC,CAAC,2CAA2C;oBAC7C,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,6BAA6B;gBAClG,KAAK;gBACL,YAAY,EAAE,MAAM;gBACpB,YAAY,EAAE,KAAK;gBACnB,UAAU,EAAE,EAAE;aACd,CAAC,CACF;YACF,CAAC,CAAC,MAAM,gBAAgB,CACtB,OAAO,EACP,YAAY,EACZ,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAC9F,CAAC;QAEL,KAAK,GAAG,SAAS,CAAC;QAClB,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO;QACnC,MAAM,GAAG,QAAQ,CAAC;QAElB,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAChD,IAAI,EAAE;gBAAE,MAAM,GAAG,SAAS,EAAE,EAAE,CAAC;YAC/B,SAAS;QACV,CAAC;QACD,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;YACtC,eAAe,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC5B,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;YAClC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,MAAM,CAAC,MAAM,CAAC,MAAM,YAAY,EAAE,MAAM,CAAC,CAAC;YACpE,SAAS;QACV,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;gBACrD,SAAS;YACV,CAAC;YACD,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,YAAY,CAC1B,GAA4B,EAC5B,EAAgB,EAChB,OAAsB;IAEtB,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAE/D,MAAM,EAAE,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,gCAAgC,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;QACjG,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO,mBAAmB,CAAC;QACzC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;YAAE,OAAO,sCAAsC,CAAC;QAC5E,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,UAAU,OAAO,mBAAmB,CAAC;QACvE,OAAO,SAAS,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAEvC,MAAM,OAAO,GAAG,MAAM,UAAU,CAC/B,GAAG,EACH,OAAO,EACP,eAAe,EAAE,CAAC,IAAI,EAAE,aAAa,EACrC,0BAA0B,EAC1B,CAAC,KAAK,EAAE,EAAE;QACT,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO,uBAAuB,CAAC;QAC7C,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;YAC7B,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;gBAAE,OAAO,oBAAoB,CAAC;QACxF,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,cAAc,CAAC;QACvB,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC,CACD,CAAC;IACF,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAE5C,MAAM,MAAM,GAAG,MAAM,UAAU,CAC9B,GAAG,EACH,OAAO,EACP,eAAe,EAAE,CAAC,IAAI,EAAE,YAAY,EACpC,oBAAoB,EACpB,CAAC,KAAK,EAAE,EAAE;QACT,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,OAAO,sBAAsB,CAAC;QACjD,OAAO,SAAS,CAAC;IAClB,CAAC,CACD,CAAC;IACF,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAE3C,MAAM,KAAK,GAAgB;QAC1B,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE;QACb,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3C,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;QACrB,MAAM,EAAE,EAAE;KACV,CAAC;IAEF,2EAA2E;IAC3E,yEAAyE;IACzE,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IACnC,MAAM,oBAAoB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACpD,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,KAAK,CAAC,EAAE,sBAAsB,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,aAAa,CAC3B,GAA4B,EAC5B,EAAgB,EAChB,OAAsB,EACtB,OAAoB;IAEpB,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,YAAY,GACjB,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YACxB,CAAC,CAAC,0BAA0B;YAC5B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC;gBACzB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC1D,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,aAAa,KAAK,CAAC,MAAM;qBAC9C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;qBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;qBAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAEpB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,WAAW,KAAK,CAAC,EAAE,EAAE,EAAE;YACrE;gBACC,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,YAAY;aACzB;YACD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,EAAE;YACnE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;YACzE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,yBAAyB,EAAE;YAClF,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE;SACjE,CAAC,CAAC;QACH,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO;QAEtD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,KAAK,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACtG,IAAI,CAAC;oBACJ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;oBAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;wBAAE,OAAO,oBAAoB,CAAC;gBACxF,CAAC;gBAAC,MAAM,CAAC;oBACR,OAAO,cAAc,CAAC;gBACvB,CAAC;gBACD,OAAO,SAAS,CAAC;YAClB,CAAC,CAAC,CAAC;YACH,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,UAAU,KAAK,KAAK,CAAC,OAAO;gBAAE,SAAS;YAC3C,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC;YAC3B,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACnC,SAAS;QACV,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,UAAU,CAC5B,GAAG,EACH,OAAO,EACP,WAAW,KAAK,CAAC,EAAE,YAAY,EAC/B,iDAAiD,CACjD,CAAC;YACF,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,KAAK,CAAC,MAAM;gBAAE,SAAS;YACnD,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC;YACvB,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACnC,SAAS;QACV,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzB,0EAA0E;YAC1E,+EAA+E;YAC/E,MAAM,gBAAgB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAChD,SAAS;QACV,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzB,IAAI,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;gBACtC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,2BAA2B,KAAK,CAAC,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;gBACrF,SAAS;YACV,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,iBAAiB,KAAK,CAAC,EAAE,IAAI,EAAE,oCAAoC,CAAC,CAAC;YACtG,IAAI,CAAC,EAAE;gBAAE,SAAS;YAClB,MAAM,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC5B,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;YACjC,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;YAClC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,kBAAkB,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACtD,OAAO;QACR,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,gBAAgB,CAC9B,GAA4B,EAC5B,EAAgB,EAChB,OAAsB,EACtB,KAAkB;IAElB,IAAI,MAA0B,CAAC;IAC/B,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,KAAK,GAAuF;YACjG,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC7B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC3C,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;gBAC1C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;gBACjE,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,KAAK,CAAC,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1F,OAAO;oBACN,KAAK,EAAE,SAAS,KAAK,CAAC,EAAE,EAAE;oBAC1B,KAAK,EAAE,GAAG,KAAK,CAAC,EAAE,GAAG,OAAO,EAAE;oBAC9B,WAAW,EAAE,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ;oBACrE,UAAU,EAAE,GAAG,0BAA0B,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,QAAQ,EAAE;iBAClH,CAAC;YACH,CAAC,CAAC;YACF;gBACC,KAAK,EAAE,cAAc;gBACrB,KAAK,EAAE,eAAe;gBACtB,WAAW,EACV,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;oBACxB,CAAC,CAAC,6BAA6B;oBAC/B,CAAC,CAAC,qDAAqD;gBACzD,UAAU,EAAE,qCAAqC;aACjD;YACD;gBACC,KAAK,EAAE,eAAe;gBACtB,KAAK,EAAE,qBAAqB;gBAC5B,WAAW,EAAE,uCAAuC;gBACpD,UAAU,EAAE,6BAA6B;aACzC;YACD,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,aAAa,EAAE;SAClG,CAAC;QAEF,MAAM,YAAY,GAAG,SAAS,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC;QAC9C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7F,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,WAAW,KAAK,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;QACxG,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,aAAa;YAAE,OAAO;QAC7D,MAAM,GAAG,MAAM,CAAC;QAEhB,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;YAC/B,MAAM,oBAAoB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YACpD,SAAS;QACV,CAAC;QAED,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;YAChC,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACvD,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACzD,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACnC,SAAS;QACV,CAAC;QAED,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;YACjE,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;AACF,CAAC;AAED,oFAAoF;AACpF,KAAK,UAAU,aAAa,CAC3B,GAA4B,EAC5B,EAAgB,EAChB,OAAsB,EACtB,KAAkB,EAClB,KAAuB;IAEvB,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,2BAA2B,CAAC;QAC7E,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,WAAW,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,EAAE,EAAE,EAAE;YACnF,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE;YAC/D;gBACC,KAAK,EAAE,UAAU;gBACjB,KAAK,EAAE,iBAAiB;gBACxB,WAAW,EAAE,oBAAoB,CAAC,QAAQ,CAAC,gBAAgB,CAAC;aAC5D;YACD,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,kCAAkC,EAAE;YAC3F,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE;SACjE,CAAC,CAAC;QACH,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO;QAEtD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,MAAM,UAAU,CAC5B,GAAG,EACH,OAAO,EACP,kBAAkB,KAAK,CAAC,EAAE,oBAAoB,EAC9C,QAAQ,CAAC,IAAI,IAAI,EAAE,CACnB,CAAC;YACF,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,CAAC,OAAO,IAAI,OAAO,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YACxE,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACtG,IAAI,QAAQ,KAAK,QAAQ;gBAAE,SAAS;YACpC,IAAI,QAAQ;gBAAE,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC;;gBAC/B,OAAO,KAAK,CAAC,IAAI,CAAC;YACvB,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACnC,SAAS;QACV,CAAC;QAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACjD,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC5B,MAAM,OAAO,CAAC,IAAI,CACjB,uBAAuB,CAAC;oBACvB,KAAK,EAAE,cAAc,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,EAAE,EAAE;oBAC7C,GAAG,EAAE,QAAQ,CAAC,gBAAgB;oBAC9B,MAAM,EAAE,sBAAsB;oBAC9B,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;wBACrB,KAAK,CAAC,gBAAgB,GAAG,OAAO,CAAC;wBACjC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;wBACvB,KAAK,CAAC,IAAI,EAAE,CAAC;oBACd,CAAC;iBACD,CAAC,CACF,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,MAAM,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,EAAE;oBAC3E,KAAK,CAAC,gBAAgB,GAAG,OAAO,CAAC;oBACjC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;oBACvB,KAAK,CAAC,IAAI,EAAE,CAAC;gBACd,CAAC,CAAC,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;YACpB,SAAS;QACV,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzB,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBACzD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,2BAA2B,KAAK,CAAC,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;gBACrF,SAAS;YACV,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,CAC/B,iBAAiB,KAAK,CAAC,EAAE,IAAI,EAC7B,yDAAyD,CACzD,CAAC;YACF,IAAI,CAAC,EAAE;gBAAE,SAAS;YAClB,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;YACrE,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACnC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,kBAAkB,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACtD,OAAO;QACR,CAAC;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,qBAAqB,CACnC,OAAsB,EACtB,GAAyC,EACzC,QAA6D;IAE7D,IAAI,OAAO,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,EAAE;YACvE,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACzC,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,KAAK;gBACZ,WAAW,EACV,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;aACvG,CAAC,CAAC;YACH,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE;SACjE,CAAC,CAAC;QACH,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO;QACtD,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,MAAiD,CAAC;YAAE,SAAS;QAClG,MAAM,KAAK,GAAG,MAAiD,CAAC;QAChE,OAAO,GAAG;YACT,GAAG,OAAO;YACV,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;YAC/C,GAAG,EAAE,IAAI;YACT,OAAO,EAAE,IAAI;SACb,CAAC;QACF,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC;AAED,KAAK,UAAU,oBAAoB,CAClC,GAA4B,EAC5B,EAAgB,EAChB,OAAsB,EACtB,KAAkB;IAElB,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,uBAAuB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACvD,OAAO;IACR,CAAC;IAED,IAAI,MAAgE,CAAC;IACrE,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;QACnE,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC5B,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAC1B,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;gBACzB,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,qBAAqB,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;gBAClF,IAAI,OAAO,GAAG,KAAK,CAAC;gBACpB,MAAM,MAAM,GAAG,CAAC,KAA+D,EAAE,EAAE;oBAClF,IAAI,OAAO;wBAAE,OAAO;oBACpB,OAAO,GAAG,IAAI,CAAC;oBACf,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjB,IAAI,CAAC,KAAK,CAAC,CAAC;gBACb,CAAC,CAAC;gBACF,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACzC,KAAK,gBAAgB,CAAC,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;qBACpE,IAAI,CAAC,MAAM,CAAC;qBACZ,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrE,OAAO,MAAM,CAAC;YACf,CAAC,CACD,CAAC;QACH,CAAC;aAAM,CAAC;YACP,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,wBAAwB,KAAK,CAAC,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;YAChE,MAAM,GAAG,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO;QACjC,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,sCAAsC,EAAE,SAAS,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,KAAK,CAAC,EAAE,EAAE,EAAE;gBAC/E,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE;gBACtE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,mCAAmC,EAAE;gBACnG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,0BAA0B,EAAE;aACzE,CAAC,CAAC;YACH,IAAI,QAAQ,KAAK,OAAO;gBAAE,SAAS;YACnC,IAAI,QAAQ,KAAK,QAAQ;gBAAE,MAAM,uBAAuB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAClF,OAAO;QACR,CAAC;QACD,IAAI,MAAM,CAAC,EAAE;YAAE,MAAM;QAErB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,iBAAiB,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,yBAAyB,KAAK,CAAC,EAAE,EAAE,EAAE;YACrF,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE;YACtE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,mCAAmC,EAAE;YACnG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,0BAA0B,EAAE;SACzE,CAAC,CAAC;QACH,IAAI,QAAQ,KAAK,OAAO;YAAE,SAAS;QACnC,IAAI,QAAQ,KAAK,QAAQ;YAAE,MAAM,uBAAuB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAClF,OAAO;IACR,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO;IAClC,IAAI,MAAM,CAAC,SAAS;QAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,oCAAoC,EAAE,SAAS,CAAC,CAAC;IAErF,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,MAAM,OAAO,GAAG,0BAA0B,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACzE,IAAI,aAAa;QAAE,iBAAiB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,aAAa,CAAC;IACrC,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3F,IAAI,aAAa,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QACpD,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IACjD,MAAM,cAAc,GAAG,CAAC,WAAqB,EAAE,EAAE;QAChD,IAAI,cAAc,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,2BAA2B,cAAc,wBAAwB,EAAE,SAAS,CAAC,CAAC;YAC5F,OAAO;QACR,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;YACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,QAAQ;gBAAE,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,wBAAwB,CAAC,EAAE,CAAC,CAAC;YAC1C,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACxB,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,EAAE,CAAC;IACd,CAAC,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAChC,oBAAoB,CAAC;YACpB,KAAK,EAAE,mBAAmB,KAAK,CAAC,EAAE,EAAE;YACpC,QAAQ,EAAE,+CAA+C;YACzD,MAAM,EAAE,OAAO;YACf,iBAAiB;YACjB,YAAY;YACZ,QAAQ,EAAE,cAAc;YACxB,iBAAiB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,2BAA2B,EAAE,wBAAwB,EAAE,SAAS,CAAC;SAC1G,CAAC,CACF,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;YAAE,uBAAuB,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACjG,CAAC;SAAM,CAAC;QACP,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,CAC/B,UAAU,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,EACxC,wCAAwC,CACxC,CAAC;QACF,IAAI,EAAE;YAAE,cAAc,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,iBAAiB,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;IACpB,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,0BAA0B,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AACjG,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC9B,GAA4B,EAC5B,OAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,2BAA2B,CAAC,CAAC;IAC9F,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,GAAG,GAAG;QACX,GAAG,IAAI,GAAG,CACT,KAAK;aACH,KAAK,CAAC,UAAU,CAAC;aACjB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;aACtB,MAAM,CAAC,OAAO,CAAC,CACjB;KACD,CAAC;IACF,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,8BAA8B,EAAE,SAAS,CAAC,CAAC;QACzD,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,KAAK,UAAU,uBAAuB,CACrC,GAA4B,EAC5B,EAAgB,EAChB,OAAsB,EACtB,KAAkB;IAElB,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzD,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,gBAAgB,CAAC,QAA4B,EAAE,SAA6B;IACpF,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC/B,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,SAAS;QAChC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,0BAA0B,CACzC,UAA2C,EAC3C,OAAqD,EACrD,aAAsB;IAEtB,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAC;IACpD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9C,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE;YACnB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,KAAK,CAAC,IAAI;SAClC,CAAC,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE;gBACnB,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE;gBAC5B,WAAW,EAAE,IAAI;aACjB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IACD,IAAI,aAAa,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,uBAAuB,CAC/B,KAAkB,EAClB,WAAkC,EAClC,KAA8B;IAE9B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO;IAC9F,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;AACzB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,GAA4B,EAAE,EAAgB,EAAE,KAAkB;IAC7F,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;IACzB,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,UAAU,CACxB,GAA4B,EAC5B,OAAsB,EACtB,KAAa,EACb,WAAmB,EACnB,QAAgD;IAEhD,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QACtD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC1C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAChC,SAAS;QACV,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC9B,OAAsB,EACtB,KAAa,EACb,KAA4F,EAC5F,IAAuE;IAEvE,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,OAAO,CAAC,IAAI,CAClB,wBAAwB,CAAC;YACxB,KAAK;YACL,KAAK;YACL,YAAY,EAAE,IAAI,EAAE,YAAY;YAChC,YAAY,EAAE,IAAI,EAAE,YAAY;YAChC,UAAU,EAAE,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;SACvE,CAAC,CACF,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5G,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;AAC/C,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC3B,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC3D,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IACnC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAChD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,KAAK,EAAE,0EAA0E,EAAE,CAAC;IAC9F,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,yBAAyB,OAAO,cAAc,EAAE,CAAC;IACtF,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,KAAK,EAAE,iFAAiF,EAAE,CAAC;IACrG,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["/**\n * /router interactive flows: list, add, edit, fetch, thinking map.\n *\n * Relay edits are live: confirmed inputs and every toggle persist immediately.\n * Searchable pickers follow Pi's native /model interaction pattern.\n */\n\nimport type { TUI } from \"@earendil-works/pi-tui\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { BorderedLoader } from \"../../modes/interactive/components/bordered-loader.ts\";\nimport { getModelSelectorSearchText } from \"../../modes/interactive/model-search.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { formatError, isValidRelayId, NO_UI_WARNING, ROUTER_THINKING_LEVELS, truncate } from \"./constants.ts\";\nimport {\n\tcreateModelChecklist,\n\tcreateSearchableSelector,\n\tcreateThinkingMapEditor,\n\ttype ModelChecklistItem,\n} from \"./dialog.ts\";\nimport {\n\tcreateNativeRouterDialogs,\n\ttype RouterDialogs,\n\tRouterTuiSession,\n\tRouterTuiSessionClosedError,\n} from \"./dialog-host.ts\";\nimport {\n\tcreateDefaultModelConfig,\n\tdisplayModelLabel,\n\tresolveModelConfig,\n\tresolveRouterThinkingMap,\n\tsummarizeThinkingMap,\n} from \"./presets.ts\";\nimport { probeRelayModels } from \"./probe.ts\";\nimport { applyRouterFile, registerOneRelay, unregisterOneRelay } from \"./register.ts\";\nimport { loadRouterFile, removeRelay, upsertRelay } from \"./store.ts\";\nimport type { RelayConfig, RelayModelConfig } from \"./types.ts\";\n\n/**\n * Serialize live relay mutations without forcing a model-registry refresh for\n * every checkbox press. Provider registration follows each snapshot; the\n * registry is refreshed once when the editor closes.\n */\nclass RelayAutoSaver {\n\tprivate chain: Promise<void> = Promise.resolve();\n\tprivate error: unknown;\n\tprivate needsRefresh = false;\n\tprivate readonly ctx: ExtensionCommandContext;\n\tprivate readonly pi: ExtensionAPI;\n\tprivate readonly relay: RelayConfig;\n\n\tconstructor(ctx: ExtensionCommandContext, pi: ExtensionAPI, relay: RelayConfig) {\n\t\tthis.ctx = ctx;\n\t\tthis.pi = pi;\n\t\tthis.relay = relay;\n\t}\n\n\tsave(): void {\n\t\tconst snapshot = structuredClone(this.relay);\n\t\tthis.needsRefresh = true;\n\t\tthis.chain = this.chain\n\t\t\t.catch(() => {})\n\t\t\t.then(async () => {\n\t\t\t\tawait upsertRelay(snapshot);\n\t\t\t\tregisterOneRelay(this.pi, snapshot);\n\t\t\t\tthis.error = undefined;\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tthis.error = error;\n\t\t\t});\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tawait this.chain;\n\t\tif (this.error !== undefined) {\n\t\t\tconst error = this.error;\n\t\t\tthis.error = undefined;\n\t\t\tthrow error;\n\t\t}\n\t\tif (this.needsRefresh) {\n\t\t\tthis.needsRefresh = false;\n\t\t\tawait this.ctx.modelRegistry.refresh();\n\t\t}\n\t}\n}\n\n/** Abort the catalog request if its internal page or the whole Router session is disposed. */\nclass RouterProbeLoader extends BorderedLoader {\n\treadonly probeSignal: AbortSignal;\n\tprivate readonly disposeController = new AbortController();\n\n\tconstructor(tui: TUI, theme: Theme, message: string) {\n\t\tsuper(tui, theme, message, { cancellable: true });\n\t\tthis.probeSignal = AbortSignal.any([this.signal, this.disposeController.signal]);\n\t}\n\n\toverride dispose(): void {\n\t\tthis.disposeController.abort();\n\t\tsuper.dispose();\n\t}\n}\n\nexport function isCurrentRouterModel(\n\tcurrent: { provider: string; id: string } | undefined,\n\trelayId: string,\n\tmodelId: string,\n): boolean {\n\treturn current?.provider === relayId && current.id === modelId;\n}\n\nexport async function runRouterCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(NO_UI_WARNING, \"warning\");\n\t\treturn;\n\t}\n\tconst trimmed = args.trim().toLowerCase();\n\tif (trimmed === \"reload\") {\n\t\tconst file = await loadRouterFile();\n\t\tapplyRouterFile(pi, file);\n\t\tawait ctx.modelRegistry.refresh();\n\t\tctx.ui.notify(`Reloaded ${file.relays.length} relay(s).`, \"info\");\n\t\treturn;\n\t}\n\tif (ctx.mode === \"tui\") {\n\t\tawait runRouterTuiCommand(args, ctx, pi);\n\t\treturn;\n\t}\n\tawait runRouterDialogCommand(args, ctx, pi, createNativeRouterDialogs(ctx));\n}\n\nasync function runRouterTuiCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {\n\tlet failure: { error: unknown } | undefined;\n\tlet closedDuringTransition = false;\n\tawait ctx.ui.custom<void>((tui, theme, keybindings, done) => {\n\t\tconst session = new RouterTuiSession(tui, theme, keybindings, () => {\n\t\t\tclosedDuringTransition = true;\n\t\t\tdone();\n\t\t});\n\t\tvoid runRouterDialogCommand(args, ctx, pi, session).then(\n\t\t\t() => {\n\t\t\t\tif (!closedDuringTransition) done();\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (closedDuringTransition) {\n\t\t\t\t\tif (!(error instanceof RouterTuiSessionClosedError)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tctx.ui.notify(formatError(error), \"error\");\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// The command context may have gone stale after the modal closed.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfailure = { error };\n\t\t\t\tdone();\n\t\t\t},\n\t\t);\n\t\treturn session;\n\t});\n\tif (failure) throw failure.error;\n}\n\nasync function runRouterDialogCommand(\n\targs: string,\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n): Promise<void> {\n\tconst trimmed = args.trim().toLowerCase();\n\tif (!trimmed || trimmed === \"list\") {\n\t\tawait openMainMenu(ctx, pi, dialogs);\n\t\treturn;\n\t}\n\tif (trimmed === \"add\") {\n\t\tawait addRelayFlow(ctx, pi, dialogs);\n\t\treturn;\n\t}\n\t// Treat as relay id open.\n\tconst file = await loadRouterFile();\n\tconst exact = file.relays.find((relay) => relay.id.toLowerCase() === trimmed);\n\tif (exact) {\n\t\tawait editRelayFlow(ctx, pi, dialogs, exact);\n\t\treturn;\n\t}\n\tawait openMainMenu(ctx, pi, dialogs, args.trim());\n}\n\nasync function openMainMenu(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\tinitialQuery?: string,\n): Promise<void> {\n\tlet cursor: string | undefined;\n\tlet query = initialQuery;\n\twhile (true) {\n\t\tconst file = await loadRouterFile();\n\t\t// Relays first (primary content), actions at the bottom.\n\t\tconst items = [\n\t\t\t...file.relays.map((relay) => ({\n\t\t\t\tvalue: `relay:${relay.id}`,\n\t\t\t\tlabel: relay.id,\n\t\t\t\tdescription: `${relay.models.length} model${relay.models.length === 1 ? \"\" : \"s\"} · ${truncate(relay.baseUrl, 40)}`,\n\t\t\t\tsearchText: `${relay.id} ${relay.baseUrl}`,\n\t\t\t})),\n\t\t\t{\n\t\t\t\tvalue: \"action:add\",\n\t\t\t\tlabel: \"+ Add relay\",\n\t\t\t\tdescription: \"Name · base URL · API key · fetch models\",\n\t\t\t\tsearchText: \"add create new relay gateway\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tvalue: \"action:reload\",\n\t\t\t\tlabel: \"Reload from disk\",\n\t\t\t\tdescription: \"Re-register providers from router.json\",\n\t\t\t\tsearchText: \"reload refresh\",\n\t\t\t},\n\t\t];\n\n\t\tconst selected =\n\t\t\tdialogs.kind === \"tui\"\n\t\t\t\t? await dialogs.show(\n\t\t\t\t\t\tcreateSearchableSelector({\n\t\t\t\t\t\t\ttitle: \"API relays\",\n\t\t\t\t\t\t\tsubtitle:\n\t\t\t\t\t\t\t\tfile.relays.length === 0\n\t\t\t\t\t\t\t\t\t? \"No relays yet — add a base URL + API key.\"\n\t\t\t\t\t\t\t\t\t: `${file.relays.length} relay${file.relays.length === 1 ? \"\" : \"s\"} · Enter opens · Esc closes`,\n\t\t\t\t\t\t\titems,\n\t\t\t\t\t\t\tinitialValue: cursor,\n\t\t\t\t\t\t\tinitialQuery: query,\n\t\t\t\t\t\t\tmaxVisible: 10,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t: await selectRouterItem(\n\t\t\t\t\t\tdialogs,\n\t\t\t\t\t\t\"API relays\",\n\t\t\t\t\t\titems.map((item) => ({ value: item.value, label: item.label, description: item.description })),\n\t\t\t\t\t);\n\n\t\tquery = undefined;\n\t\tif (selected === undefined) return;\n\t\tcursor = selected;\n\n\t\tif (selected === \"action:add\") {\n\t\t\tconst id = await addRelayFlow(ctx, pi, dialogs);\n\t\t\tif (id) cursor = `relay:${id}`;\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected === \"action:reload\") {\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tapplyRouterFile(pi, latest);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Reloaded ${latest.relays.length} relay(s).`, \"info\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected.startsWith(\"relay:\")) {\n\t\t\tconst id = selected.slice(\"relay:\".length);\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tconst relay = latest.relays.find((entry) => entry.id === id);\n\t\t\tif (!relay) {\n\t\t\t\tctx.ui.notify(`Relay \"${id}\" not found.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait editRelayFlow(ctx, pi, dialogs, relay);\n\t\t}\n\t}\n}\n\nasync function addRelayFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n): Promise<string | undefined> {\n\tconst file = await loadRouterFile();\n\tconst existing = new Set(file.relays.map((relay) => relay.id));\n\n\tconst id = await promptText(ctx, dialogs, \"New relay · name (provider id)\", \"my-relay\", (value) => {\n\t\tconst trimmed = value.trim();\n\t\tif (!trimmed) return \"Name is required.\";\n\t\tif (!isValidRelayId(trimmed)) return \"Name cannot be empty or contain '/'.\";\n\t\tif (existing.has(trimmed)) return `Relay \"${trimmed}\" already exists.`;\n\t\treturn undefined;\n\t});\n\tif (id === undefined) return undefined;\n\n\tconst baseUrl = await promptText(\n\t\tctx,\n\t\tdialogs,\n\t\t`New relay · ${id.trim()} · base URL`,\n\t\t\"https://relay.example/v1\",\n\t\t(value) => {\n\t\t\tconst trimmed = value.trim();\n\t\t\tif (!trimmed) return \"Base URL is required.\";\n\t\t\ttry {\n\t\t\t\tconst url = new URL(trimmed);\n\t\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t\t} catch {\n\t\t\t\treturn \"Invalid URL.\";\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t);\n\tif (baseUrl === undefined) return undefined;\n\n\tconst apiKey = await promptText(\n\t\tctx,\n\t\tdialogs,\n\t\t`New relay · ${id.trim()} · API key`,\n\t\t\"sk-… or $RELAY_KEY\",\n\t\t(value) => {\n\t\t\tif (!value.trim()) return \"API key is required.\";\n\t\t\treturn undefined;\n\t\t},\n\t);\n\tif (apiKey === undefined) return undefined;\n\n\tconst relay: RelayConfig = {\n\t\tid: id.trim(),\n\t\tbaseUrl: baseUrl.trim().replace(/\\/+$/, \"\"),\n\t\tapiKey: apiKey.trim(),\n\t\tmodels: [],\n\t};\n\n\t// Connection fields are committed before the network step so cancelling or\n\t// failing catalog discovery never loses the relay the user just entered.\n\tawait persistRelay(ctx, pi, relay);\n\tawait fetchAndSelectModels(ctx, pi, dialogs, relay);\n\tif (relay.models.length === 0) {\n\t\tctx.ui.notify(`Relay \"${relay.id}\" has no models yet.`, \"warning\");\n\t}\n\treturn relay.id;\n}\n\n/**\n * Relay editor — flat menu. Every mutation writes router.json immediately.\n * Hierarchy: list → relay → (models list | connection field | fetch | remove).\n */\nasync function editRelayFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\tinitial: RelayConfig,\n): Promise<void> {\n\tconst relay = structuredClone(initial);\n\twhile (true) {\n\t\tconst modelSummary =\n\t\t\trelay.models.length === 0\n\t\t\t\t? \"none yet — fetch catalog\"\n\t\t\t\t: relay.models.length <= 3\n\t\t\t\t\t? relay.models.map((m) => displayModelLabel(m)).join(\", \")\n\t\t\t\t\t: `${relay.models.length} models · ${relay.models\n\t\t\t\t\t\t\t.slice(0, 2)\n\t\t\t\t\t\t\t.map((m) => displayModelLabel(m))\n\t\t\t\t\t\t\t.join(\", \")}…`;\n\n\t\tconst choice = await selectRouterItem(dialogs, `Relay · ${relay.id}`, [\n\t\t\t{\n\t\t\t\tvalue: \"models\",\n\t\t\t\tlabel: \"Models\",\n\t\t\t\tdescription: modelSummary,\n\t\t\t},\n\t\t\t{ value: \"baseUrl\", label: \"Base URL\", description: relay.baseUrl },\n\t\t\t{ value: \"apiKey\", label: \"API key\", description: maskKey(relay.apiKey) },\n\t\t\t{ value: \"remove\", label: \"Remove relay\", description: \"Delete from router.json\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relays\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"back\") return;\n\n\t\tif (choice === \"baseUrl\") {\n\t\t\tconst next = await promptText(ctx, dialogs, `Relay · ${relay.id} · base URL`, relay.baseUrl, (value) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst url = new URL(value.trim());\n\t\t\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t\t\t} catch {\n\t\t\t\t\treturn \"Invalid URL.\";\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t\tif (next === undefined) continue;\n\t\t\tconst normalized = next.trim().replace(/\\/+$/, \"\");\n\t\t\tif (normalized === relay.baseUrl) continue;\n\t\t\trelay.baseUrl = normalized;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"apiKey\") {\n\t\t\tconst next = await promptText(\n\t\t\t\tctx,\n\t\t\t\tdialogs,\n\t\t\t\t`Relay · ${relay.id} · API key`,\n\t\t\t\t\"Enter a new key · blank keeps the current value\",\n\t\t\t);\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tif (!trimmed || trimmed === relay.apiKey) continue;\n\t\t\trelay.apiKey = trimmed;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"models\") {\n\t\t\t// Always open the models screen (fetch lives only here). Empty list still\n\t\t\t// shows Fetch so the path is Relay → Models → Fetch, not a top-level shortcut.\n\t\t\tawait manageModelsFlow(ctx, pi, dialogs, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"remove\") {\n\t\t\tif (ctx.model?.provider === relay.id) {\n\t\t\t\tctx.ui.notify(`Switch away from relay \"${relay.id}\" before removing it.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ok = await dialogs.confirm(`Remove relay \"${relay.id}\"?`, \"Models will disappear from /model.\");\n\t\t\tif (!ok) continue;\n\t\t\tawait removeRelay(relay.id);\n\t\t\tunregisterOneRelay(pi, relay.id);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Removed relay \"${relay.id}\".`, \"info\");\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * Models screen: searchable configured models plus fetch/manual-add actions.\n * Selecting a model opens its editor (name / thinking / remove).\n */\nasync function manageModelsFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tlet cursor: string | undefined;\n\twhile (true) {\n\t\tconst items: Array<{ value: string; label: string; description?: string; searchText?: string }> = [\n\t\t\t...relay.models.map((model) => {\n\t\t\t\tconst resolved = resolveModelConfig(model);\n\t\t\t\tconst label = displayModelLabel(resolved);\n\t\t\t\tconst thinking = summarizeThinkingMap(resolved.thinkingLevelMap);\n\t\t\t\tconst current = ctx.model?.provider === relay.id && ctx.model.id === model.id ? \" ✓\" : \"\";\n\t\t\t\treturn {\n\t\t\t\t\tvalue: `model:${model.id}`,\n\t\t\t\t\tlabel: `${model.id}${current}`,\n\t\t\t\t\tdescription: label !== model.id ? `${label} · ${thinking}` : thinking,\n\t\t\t\t\tsearchText: `${getModelSelectorSearchText({ id: model.id, provider: relay.id, name: resolved.name })} ${thinking}`,\n\t\t\t\t};\n\t\t\t}),\n\t\t\t{\n\t\t\t\tvalue: \"action:fetch\",\n\t\t\t\tlabel: \"Fetch catalog\",\n\t\t\t\tdescription:\n\t\t\t\t\trelay.models.length === 0\n\t\t\t\t\t\t? \"GET /models · select models\"\n\t\t\t\t\t\t: \"Refresh from server · keeps selected customizations\",\n\t\t\t\tsearchText: \"fetch catalog refresh models server\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tvalue: \"action:manual\",\n\t\t\t\tlabel: \"Add models manually\",\n\t\t\t\tdescription: \"Comma- or newline-separated model ids\",\n\t\t\t\tsearchText: \"add manual custom model ids\",\n\t\t\t},\n\t\t\t{ value: \"action:back\", label: \"Back\", description: \"Return to relay\", searchText: \"back return\" },\n\t\t];\n\n\t\tconst currentValue = `model:${ctx.model?.id}`;\n\t\tconst initialValue = cursor ?? (ctx.model?.provider === relay.id ? currentValue : undefined);\n\t\tconst choice = await selectRouterItem(dialogs, `Relay · ${relay.id} · models`, items, { initialValue });\n\t\tif (choice === undefined || choice === \"action:back\") return;\n\t\tcursor = choice;\n\n\t\tif (choice === \"action:fetch\") {\n\t\t\tawait fetchAndSelectModels(ctx, pi, dialogs, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"action:manual\") {\n\t\t\tconst additions = await manualModelEntry(ctx, dialogs);\n\t\t\tif (!additions) continue;\n\t\t\trelay.models = mergeAddedModels(relay.models, additions);\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice.startsWith(\"model:\")) {\n\t\t\tconst modelId = choice.slice(\"model:\".length);\n\t\t\tconst model = relay.models.find((entry) => entry.id === modelId);\n\t\t\tif (!model) continue;\n\t\t\tawait editModelFlow(ctx, pi, dialogs, relay, model);\n\t\t}\n\t}\n}\n\n/** Single-model editor: display name + thinking. Every confirmed change is live. */\nasync function editModelFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n\tmodel: RelayModelConfig,\n): Promise<void> {\n\twhile (true) {\n\t\tconst resolved = resolveModelConfig(model);\n\t\tconst nameDesc = resolved.name ? resolved.name : \"(empty · /model shows id)\";\n\t\tconst action = await selectRouterItem(dialogs, `Relay · ${relay.id} · ${model.id}`, [\n\t\t\t{ value: \"name\", label: \"Display name\", description: nameDesc },\n\t\t\t{\n\t\t\t\tvalue: \"thinking\",\n\t\t\t\tlabel: \"Thinking levels\",\n\t\t\t\tdescription: summarizeThinkingMap(resolved.thinkingLevelMap),\n\t\t\t},\n\t\t\t{ value: \"remove\", label: \"Remove model\", description: \"Delete this model from the relay\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to models\" },\n\t\t]);\n\t\tif (action === undefined || action === \"back\") return;\n\n\t\tif (action === \"name\") {\n\t\t\tconst next = await promptText(\n\t\t\t\tctx,\n\t\t\t\tdialogs,\n\t\t\t\t`Display name · ${model.id} (empty = show id)`,\n\t\t\t\tresolved.name ?? \"\",\n\t\t\t);\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tconst nextName = !trimmed || trimmed === model.id ? undefined : trimmed;\n\t\t\tconst prevName = model.name?.trim() && model.name.trim() !== model.id ? model.name.trim() : undefined;\n\t\t\tif (nextName === prevName) continue;\n\t\t\tif (nextName) model.name = nextName;\n\t\t\telse delete model.name;\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"thinking\") {\n\t\t\tconst saver = new RelayAutoSaver(ctx, pi, relay);\n\t\t\tif (dialogs.kind === \"tui\") {\n\t\t\t\tawait dialogs.show(\n\t\t\t\t\tcreateThinkingMapEditor({\n\t\t\t\t\t\ttitle: `Thinking · ${relay.id} / ${model.id}`,\n\t\t\t\t\t\tmap: resolved.thinkingLevelMap,\n\t\t\t\t\t\tlevels: ROUTER_THINKING_LEVELS,\n\t\t\t\t\t\tonChange: (nextMap) => {\n\t\t\t\t\t\t\tmodel.thinkingLevelMap = nextMap;\n\t\t\t\t\t\t\tmodel.reasoning = true;\n\t\t\t\t\t\t\tsaver.save();\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait editThinkingMapNative(dialogs, resolved.thinkingLevelMap, (nextMap) => {\n\t\t\t\t\tmodel.thinkingLevelMap = nextMap;\n\t\t\t\t\tmodel.reasoning = true;\n\t\t\t\t\tsaver.save();\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait saver.flush();\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"remove\") {\n\t\t\tif (isCurrentRouterModel(ctx.model, relay.id, model.id)) {\n\t\t\t\tctx.ui.notify(`Switch away from model \"${model.id}\" before removing it.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst ok = await dialogs.confirm(\n\t\t\t\t`Remove model \"${model.id}\"?`,\n\t\t\t\t\"Its display name and thinking settings will be removed.\",\n\t\t\t);\n\t\t\tif (!ok) continue;\n\t\t\trelay.models = relay.models.filter((entry) => entry.id !== model.id);\n\t\t\tawait persistRelay(ctx, pi, relay);\n\t\t\tctx.ui.notify(`Removed model \"${model.id}\".`, \"info\");\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nasync function editThinkingMapNative(\n\tdialogs: RouterDialogs,\n\tmap: RelayModelConfig[\"thinkingLevelMap\"],\n\tonChange: (map: RelayModelConfig[\"thinkingLevelMap\"]) => void,\n): Promise<void> {\n\tlet working = resolveRouterThinkingMap(map);\n\twhile (true) {\n\t\tconst choice = await selectRouterItem(dialogs, \"Toggle thinking level\", [\n\t\t\t...ROUTER_THINKING_LEVELS.map((level) => ({\n\t\t\t\tvalue: level,\n\t\t\t\tlabel: level,\n\t\t\t\tdescription:\n\t\t\t\t\tworking[level] === null ? \"hidden\" : working[level] === undefined ? \"default\" : String(working[level]),\n\t\t\t})),\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Changes are live\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"back\") return;\n\t\tif (!ROUTER_THINKING_LEVELS.includes(choice as (typeof ROUTER_THINKING_LEVELS)[number])) continue;\n\t\tconst level = choice as (typeof ROUTER_THINKING_LEVELS)[number];\n\t\tworking = {\n\t\t\t...working,\n\t\t\t[level]: working[level] === null ? level : null,\n\t\t\toff: null,\n\t\t\tminimal: null,\n\t\t};\n\t\tonChange({ ...working });\n\t}\n}\n\nasync function fetchAndSelectModels(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tconst key = resolveProbeApiKey(relay.apiKey);\n\tif (key.error) {\n\t\tctx.ui.notify(key.error, \"warning\");\n\t\tawait recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\treturn;\n\t}\n\n\tlet result: Awaited<ReturnType<typeof probeRelayModels>> | undefined;\n\twhile (true) {\n\t\tconst probeOptions = { baseUrl: relay.baseUrl, apiKey: key.value };\n\t\tif (dialogs.kind === \"tui\") {\n\t\t\tresult = await dialogs.show<Awaited<ReturnType<typeof probeRelayModels>> | undefined>(\n\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\tconst loader = new RouterProbeLoader(tui, theme, `Fetching models · ${relay.id}`);\n\t\t\t\t\tlet settled = false;\n\t\t\t\t\tconst finish = (value: Awaited<ReturnType<typeof probeRelayModels>> | undefined) => {\n\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tloader.dispose();\n\t\t\t\t\t\tdone(value);\n\t\t\t\t\t};\n\t\t\t\t\tloader.onAbort = () => finish(undefined);\n\t\t\t\t\tvoid probeRelayModels({ ...probeOptions, signal: loader.probeSignal })\n\t\t\t\t\t\t.then(finish)\n\t\t\t\t\t\t.catch((error) => finish({ ok: false, error: formatError(error) }));\n\t\t\t\t\treturn loader;\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tctx.ui.notify(`Fetching models from ${relay.baseUrl}…`, \"info\");\n\t\t\tresult = await probeRelayModels(probeOptions);\n\t\t}\n\n\t\tif (result === undefined) return;\n\t\tif (result.ok && result.models.length === 0) {\n\t\t\tctx.ui.notify(\"Server returned an empty model list.\", \"warning\");\n\t\t\tconst recovery = await selectRouterItem(dialogs, `Catalog empty · ${relay.id}`, [\n\t\t\t\t{ value: \"retry\", label: \"Retry\", description: \"Fetch /models again\" },\n\t\t\t\t{ value: \"manual\", label: \"Add models manually\", description: \"Enter model ids without a catalog\" },\n\t\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relay settings\" },\n\t\t\t]);\n\t\t\tif (recovery === \"retry\") continue;\n\t\t\tif (recovery === \"manual\") await recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\t\treturn;\n\t\t}\n\t\tif (result.ok) break;\n\n\t\tctx.ui.notify(`Fetch failed: ${result.error}`, \"error\");\n\t\tconst recovery = await selectRouterItem(dialogs, `Catalog unavailable · ${relay.id}`, [\n\t\t\t{ value: \"retry\", label: \"Retry\", description: \"Fetch /models again\" },\n\t\t\t{ value: \"manual\", label: \"Add models manually\", description: \"Enter model ids without a catalog\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Return to relay settings\" },\n\t\t]);\n\t\tif (recovery === \"retry\") continue;\n\t\tif (recovery === \"manual\") await recoverWithManualModels(ctx, pi, dialogs, relay);\n\t\treturn;\n\t}\n\n\tif (!result || !result.ok) return;\n\tif (result.truncated) ctx.ui.notify(\"Catalog truncated to 2,000 models.\", \"warning\");\n\n\tconst activeModelId = ctx.model?.provider === relay.id ? ctx.model.id : undefined;\n\tconst catalog = mergeCatalogWithConfigured(relay.models, result.models, activeModelId);\n\tconst initiallySelected = new Set(relay.models.map((model) => model.id));\n\tif (activeModelId) initiallySelected.add(activeModelId);\n\tconst currentModelId = activeModelId;\n\tconst protectedIds = currentModelId ? new Set([currentModelId]) : undefined;\n\tconst preserved = new Map(relay.models.map((model) => [model.id, structuredClone(model)]));\n\tif (activeModelId && !preserved.has(activeModelId)) {\n\t\tpreserved.set(activeModelId, createDefaultModelConfig(activeModelId));\n\t}\n\tconst saver = new RelayAutoSaver(ctx, pi, relay);\n\tconst applySelection = (selectedIds: string[]) => {\n\t\tif (currentModelId && !selectedIds.includes(currentModelId)) {\n\t\t\tctx.ui.notify(`Switch away from model \"${currentModelId}\" before disabling it.`, \"warning\");\n\t\t\treturn;\n\t\t}\n\t\trelay.models = selectedIds.map((id) => {\n\t\t\tconst previous = preserved.get(id);\n\t\t\tif (previous) return structuredClone(previous);\n\t\t\tconst next = createDefaultModelConfig(id);\n\t\t\tpreserved.set(id, next);\n\t\t\treturn structuredClone(next);\n\t\t});\n\t\tsaver.save();\n\t};\n\n\tif (dialogs.kind === \"tui\") {\n\t\tconst choice = await dialogs.show(\n\t\t\tcreateModelChecklist({\n\t\t\t\ttitle: `Select models · ${relay.id}`,\n\t\t\t\tsubtitle: \"Space toggles immediately · Enter/Esc returns\",\n\t\t\t\tmodels: catalog,\n\t\t\t\tinitiallySelected,\n\t\t\t\tprotectedIds,\n\t\t\t\tonChange: applySelection,\n\t\t\t\tonProtectedToggle: (id) => ctx.ui.notify(`Switch away from model \"${id}\" before disabling it.`, \"warning\"),\n\t\t\t}),\n\t\t);\n\t\tif (choice.kind === \"close\") applySelectionIfChanged(relay, choice.selectedIds, applySelection);\n\t} else {\n\t\tconst ok = await dialogs.confirm(\n\t\t\t`Import ${result.models.length} models?`,\n\t\t\t\"Non-TUI mode imports the full catalog.\",\n\t\t);\n\t\tif (ok) applySelection([...new Set([...initiallySelected, ...result.models.map((model) => model.id)])]);\n\t}\n\tawait saver.flush();\n\tif (relay.models.length === 0) ctx.ui.notify(`No models enabled for \"${relay.id}\".`, \"warning\");\n}\n\nasync function manualModelEntry(\n\tctx: ExtensionCommandContext,\n\tdialogs: RouterDialogs,\n): Promise<RelayModelConfig[] | undefined> {\n\tconst value = await dialogs.input(\"Model IDs (comma-separated)\", \"gpt-5.6-sol, gpt-5.6-luna\");\n\tif (value === undefined) return undefined;\n\tconst ids = [\n\t\t...new Set(\n\t\t\tvalue\n\t\t\t\t.split(/[,\\r\\n]+/)\n\t\t\t\t.map((id) => id.trim())\n\t\t\t\t.filter(Boolean),\n\t\t),\n\t];\n\tif (ids.length === 0) {\n\t\tctx.ui.notify(\"Enter at least one model id.\", \"warning\");\n\t\treturn undefined;\n\t}\n\treturn ids.map((id) => createDefaultModelConfig(id));\n}\n\nasync function recoverWithManualModels(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\tdialogs: RouterDialogs,\n\trelay: RelayConfig,\n): Promise<void> {\n\tconst additions = await manualModelEntry(ctx, dialogs);\n\tif (!additions) return;\n\trelay.models = mergeAddedModels(relay.models, additions);\n\tawait persistRelay(ctx, pi, relay);\n}\n\nfunction mergeAddedModels(previous: RelayModelConfig[], additions: RelayModelConfig[]): RelayModelConfig[] {\n\tconst result = previous.map((model) => structuredClone(model));\n\tconst ids = new Set(result.map((model) => model.id));\n\tfor (const model of additions) {\n\t\tif (ids.has(model.id)) continue;\n\t\tids.add(model.id);\n\t\tresult.push(model);\n\t}\n\treturn result;\n}\n\nexport function mergeCatalogWithConfigured(\n\tconfigured: ReadonlyArray<RelayModelConfig>,\n\tcatalog: ReadonlyArray<{ id: string; name?: string }>,\n\tactiveModelId?: string,\n): ModelChecklistItem[] {\n\tconst items = new Map<string, ModelChecklistItem>();\n\tconst configuredById = new Map(configured.map((model) => [model.id, model]));\n\tfor (const model of catalog) {\n\t\tconst previous = configuredById.get(model.id);\n\t\titems.set(model.id, {\n\t\t\tid: model.id,\n\t\t\tname: previous?.name ?? model.name,\n\t\t});\n\t}\n\tfor (const model of configured) {\n\t\tif (!items.has(model.id)) {\n\t\t\titems.set(model.id, {\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name ?? model.id,\n\t\t\t\tunavailable: true,\n\t\t\t});\n\t\t}\n\t}\n\tif (activeModelId && !items.has(activeModelId)) {\n\t\titems.set(activeModelId, { id: activeModelId, name: activeModelId, unavailable: true });\n\t}\n\treturn [...items.values()].sort((left, right) => left.id.localeCompare(right.id));\n}\n\nfunction applySelectionIfChanged(\n\trelay: RelayConfig,\n\tselectedIds: ReadonlyArray<string>,\n\tapply: (ids: string[]) => void,\n): void {\n\tconst current = new Set(relay.models.map((model) => model.id));\n\tif (current.size === selectedIds.length && selectedIds.every((id) => current.has(id))) return;\n\tapply([...selectedIds]);\n}\n\nasync function persistRelay(ctx: ExtensionCommandContext, pi: ExtensionAPI, relay: RelayConfig): Promise<void> {\n\tawait upsertRelay(relay);\n\tregisterOneRelay(pi, relay);\n\tawait ctx.modelRegistry.refresh();\n}\n\nasync function promptText(\n\tctx: ExtensionCommandContext,\n\tdialogs: RouterDialogs,\n\ttitle: string,\n\tplaceholder: string,\n\tvalidate?: (value: string) => string | undefined,\n): Promise<string | undefined> {\n\twhile (true) {\n\t\tconst value = await dialogs.input(title, placeholder);\n\t\tif (value === undefined) return undefined;\n\t\tconst error = validate?.(value);\n\t\tif (error) {\n\t\t\tctx.ui.notify(error, \"warning\");\n\t\t\tcontinue;\n\t\t}\n\t\treturn value;\n\t}\n}\n\nasync function selectRouterItem<T extends string>(\n\tdialogs: RouterDialogs,\n\ttitle: string,\n\titems: ReadonlyArray<{ value: T; label: string; description?: string; searchText?: string }>,\n\topts?: { initialValue?: T; initialQuery?: string; maxVisible?: number },\n): Promise<T | undefined> {\n\tif (dialogs.kind === \"tui\") {\n\t\treturn dialogs.show(\n\t\t\tcreateSearchableSelector({\n\t\t\t\ttitle,\n\t\t\t\titems,\n\t\t\t\tinitialValue: opts?.initialValue,\n\t\t\t\tinitialQuery: opts?.initialQuery,\n\t\t\t\tmaxVisible: opts?.maxVisible ?? Math.min(10, Math.max(1, items.length)),\n\t\t\t}),\n\t\t);\n\t}\n\tconst labels = items.map((item) => (item.description ? `${item.label} — ${item.description}` : item.label));\n\tconst selected = await dialogs.select(title, labels);\n\tif (selected === undefined) return undefined;\n\treturn items[labels.indexOf(selected)]?.value;\n}\n\nfunction maskKey(key: string): string {\n\tif (key.startsWith(\"$\") || key.startsWith(\"!\")) return key;\n\tif (key.length <= 8) return \"••••\";\n\treturn `${key.slice(0, 4)}…${key.slice(-4)}`;\n}\n\n/** Resolve only keys that can be safely used by the catalog probe. */\nexport function resolveProbeApiKey(apiKey: string): { value?: string; error?: string } {\n\tconst trimmed = apiKey.trim();\n\tif (!trimmed) return {};\n\tif (trimmed.startsWith(\"!\")) {\n\t\treturn { error: \"This API key uses a !command and cannot be resolved for catalog probing.\" };\n\t}\n\tconst envOnly = trimmed.match(/^\\$([A-Za-z_][A-Za-z0-9_]*)$/);\n\tconst braced = trimmed.match(/^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/);\n\tconst envName = envOnly?.[1] ?? braced?.[1];\n\tif (envName) {\n\t\tconst value = process.env[envName]?.trim();\n\t\treturn value ? { value } : { error: `Environment variable $${envName} is not set.` };\n\t}\n\tif (trimmed.includes(\"$\")) {\n\t\treturn { error: \"This API key contains interpolation and cannot be resolved for catalog probing.\" };\n\t}\n\treturn { value: trimmed };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/statusline/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gCAAgC,CAAC;AA4XrF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA0FzD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/statusline/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gCAAgC,CAAC;AAkXrF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA0FzD"}
@@ -1,4 +1,5 @@
1
1
  import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
2
+ import { addUsageToTotals, createUsageTotals } from "../../core/usage-totals.js";
2
3
  const CONTEXT_WARNING_PERCENT = 70;
3
4
  const CONTEXT_ERROR_PERCENT = 90;
4
5
  const MIN_GAP = 1;
@@ -60,57 +61,53 @@ function joinSegments(segments, separator) {
60
61
  * One pass over the branch: latest thinking level + cumulative usage.
61
62
  * Cached across footer paints while leaf identity + usage fingerprint hold.
62
63
  */
64
+ function entryUsage(entry) {
65
+ if (entry.type === "message") {
66
+ if (entry.message.role === "assistant")
67
+ return entry.message.usage;
68
+ if (entry.message.role === "toolResult")
69
+ return entry.message.usage;
70
+ return undefined;
71
+ }
72
+ if (entry.type === "branch_summary" || entry.type === "compaction")
73
+ return entry.usage;
74
+ return undefined;
75
+ }
63
76
  function computeBranchStats(branchEntries) {
64
77
  let thinkingLevel = "off";
65
- const usage = {
66
- inputTokens: 0,
67
- outputTokens: 0,
68
- cacheReadTokens: 0,
69
- cacheWriteTokens: 0,
70
- totalCost: 0,
71
- };
78
+ const usageTotals = createUsageTotals();
79
+ let latestCacheHitPercent;
72
80
  for (const entry of branchEntries) {
73
81
  if (entry.type === "thinking_level_change") {
74
82
  thinkingLevel = entry.thinkingLevel;
75
83
  continue;
76
84
  }
77
- if (entry.type !== "message" || entry.message.role !== "assistant")
85
+ const usage = entryUsage(entry);
86
+ if (!usage)
78
87
  continue;
79
- const assistantMessage = entry.message;
80
- const inputTokens = assistantMessage.usage?.input ?? 0;
81
- const outputTokens = assistantMessage.usage?.output ?? 0;
82
- const cacheReadTokens = assistantMessage.usage?.cacheRead ?? 0;
83
- const cacheWriteTokens = assistantMessage.usage?.cacheWrite ?? 0;
84
- usage.inputTokens += inputTokens;
85
- usage.outputTokens += outputTokens;
86
- usage.cacheReadTokens += cacheReadTokens;
87
- usage.cacheWriteTokens += cacheWriteTokens;
88
- usage.totalCost += assistantMessage.usage?.cost?.total ?? 0;
89
- const latestPromptTokens = inputTokens + cacheReadTokens + cacheWriteTokens;
90
- const latestRequestUsedCache = cacheReadTokens > 0 || cacheWriteTokens > 0;
91
- usage.latestCacheHitPercent =
92
- latestRequestUsedCache && latestPromptTokens > 0 ? (cacheReadTokens / latestPromptTokens) * 100 : undefined;
88
+ addUsageToTotals(usageTotals, usage);
89
+ // Keep CH tied to the latest assistant request, matching the native
90
+ // footer; tool and summary usage contributes only to cumulative totals.
91
+ if (entry.type === "message" && entry.message.role === "assistant") {
92
+ const latestPromptTokens = usage.input + usage.cacheRead + usage.cacheWrite;
93
+ const latestRequestUsedCache = usage.cacheRead > 0 || usage.cacheWrite > 0;
94
+ latestCacheHitPercent =
95
+ latestRequestUsedCache && latestPromptTokens > 0 ? (usage.cacheRead / latestPromptTokens) * 100 : undefined;
96
+ }
93
97
  }
94
- return { thinkingLevel, usage };
98
+ return { thinkingLevel, usage: { ...usageTotals, latestCacheHitPercent } };
95
99
  }
96
100
  /**
97
101
  * Fingerprint the leaf so streaming usage updates invalidate even when the
98
102
  * SessionEntry object identity is reused in place.
99
103
  */
100
104
  function leafUsageFingerprint(entry) {
101
- if (!entry || entry.type !== "message" || entry.message.role !== "assistant")
105
+ if (!entry)
102
106
  return "";
103
- const assistantMessage = entry.message;
104
- const usage = assistantMessage.usage;
107
+ const usage = entryUsage(entry);
105
108
  if (!usage)
106
109
  return "";
107
- return [
108
- usage.input ?? 0,
109
- usage.output ?? 0,
110
- usage.cacheRead ?? 0,
111
- usage.cacheWrite ?? 0,
112
- usage.cost?.total ?? 0,
113
- ].join(":");
110
+ return [usage.input, usage.output, usage.cacheRead, usage.cacheWrite, usage.cost.total].join(":");
114
111
  }
115
112
  function getBranchStats(branchEntries, cache) {
116
113
  const lastEntry = branchEntries.length > 0 ? branchEntries[branchEntries.length - 1] : undefined;
@@ -151,21 +148,21 @@ function formatContextUsage(ctx, theme) {
151
148
  }
152
149
  function formatUsageSummary(summary, usesSubscription, theme, options = { includeCacheRead: true, includeCacheWrite: true }) {
153
150
  const usageParts = [];
154
- if (summary.inputTokens > 0)
155
- usageParts.push(`↑${formatTokenCount(summary.inputTokens)}`);
156
- if (summary.outputTokens > 0)
157
- usageParts.push(`↓${formatTokenCount(summary.outputTokens)}`);
158
- if (options.includeCacheRead && summary.cacheReadTokens > 0) {
159
- usageParts.push(`R${formatTokenCount(summary.cacheReadTokens)}`);
151
+ if (summary.input > 0)
152
+ usageParts.push(`↑${formatTokenCount(summary.input)}`);
153
+ if (summary.output > 0)
154
+ usageParts.push(`↓${formatTokenCount(summary.output)}`);
155
+ if (options.includeCacheRead && summary.cacheRead > 0) {
156
+ usageParts.push(`R${formatTokenCount(summary.cacheRead)}`);
160
157
  }
161
- if (options.includeCacheWrite && summary.cacheWriteTokens > 0) {
162
- usageParts.push(`W${formatTokenCount(summary.cacheWriteTokens)}`);
158
+ if (options.includeCacheWrite && summary.cacheWrite > 0) {
159
+ usageParts.push(`W${formatTokenCount(summary.cacheWrite)}`);
163
160
  }
164
161
  if (summary.latestCacheHitPercent !== undefined) {
165
162
  usageParts.push(`CH${summary.latestCacheHitPercent.toFixed(1)}%`);
166
163
  }
167
- if (summary.totalCost > 0) {
168
- usageParts.push(`$${summary.totalCost.toFixed(3)}${usesSubscription ? " (sub)" : ""}`);
164
+ if (summary.cost > 0) {
165
+ usageParts.push(`$${summary.cost.toFixed(3)}${usesSubscription ? " (sub)" : ""}`);
169
166
  }
170
167
  if (usageParts.length === 0)
171
168
  return "";