@flanksource/clicky-ui 0.3.23 → 0.3.25

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 (92) hide show
  1. package/dist/data/ai/AdvancedChatConfig.cjs +3 -0
  2. package/dist/data/ai/AdvancedChatConfig.cjs.map +1 -1
  3. package/dist/data/ai/AdvancedChatConfig.d.ts +2 -1
  4. package/dist/data/ai/AdvancedChatConfig.d.ts.map +1 -1
  5. package/dist/data/ai/AdvancedChatConfig.js +3 -0
  6. package/dist/data/ai/AdvancedChatConfig.js.map +1 -1
  7. package/dist/data/ai/ChatWindow.cjs +77 -4
  8. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  9. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  10. package/dist/data/ai/ChatWindow.js +78 -5
  11. package/dist/data/ai/ChatWindow.js.map +1 -1
  12. package/dist/data/ai/ChatWindow.runtime.cjs +19 -4
  13. package/dist/data/ai/ChatWindow.runtime.cjs.map +1 -1
  14. package/dist/data/ai/ChatWindow.runtime.d.ts +2 -0
  15. package/dist/data/ai/ChatWindow.runtime.d.ts.map +1 -1
  16. package/dist/data/ai/ChatWindow.runtime.js +19 -4
  17. package/dist/data/ai/ChatWindow.runtime.js.map +1 -1
  18. package/dist/data/ai/ChatWindow.test-utils.d.ts +2 -1
  19. package/dist/data/ai/ChatWindow.test-utils.d.ts.map +1 -1
  20. package/dist/data/ai/ToolPreferences.cjs +8 -1
  21. package/dist/data/ai/ToolPreferences.cjs.map +1 -1
  22. package/dist/data/ai/ToolPreferences.d.ts +2 -1
  23. package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
  24. package/dist/data/ai/ToolPreferences.js +8 -1
  25. package/dist/data/ai/ToolPreferences.js.map +1 -1
  26. package/dist/data/chat/Chat.cjs +34 -7
  27. package/dist/data/chat/Chat.cjs.map +1 -1
  28. package/dist/data/chat/Chat.d.ts +9 -1
  29. package/dist/data/chat/Chat.d.ts.map +1 -1
  30. package/dist/data/chat/Chat.js +34 -7
  31. package/dist/data/chat/Chat.js.map +1 -1
  32. package/dist/data/chat/ChatRuntimeToolbar.cjs +13 -7
  33. package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
  34. package/dist/data/chat/ChatRuntimeToolbar.d.ts +2 -1
  35. package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
  36. package/dist/data/chat/ChatRuntimeToolbar.js +13 -7
  37. package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
  38. package/dist/data/chat/ContextMeter.cjs +64 -27
  39. package/dist/data/chat/ContextMeter.cjs.map +1 -1
  40. package/dist/data/chat/ContextMeter.d.ts +11 -4
  41. package/dist/data/chat/ContextMeter.d.ts.map +1 -1
  42. package/dist/data/chat/ContextMeter.js +64 -27
  43. package/dist/data/chat/ContextMeter.js.map +1 -1
  44. package/dist/data/chat/Message.cjs +36 -1
  45. package/dist/data/chat/Message.cjs.map +1 -1
  46. package/dist/data/chat/Message.d.ts +1 -1
  47. package/dist/data/chat/Message.d.ts.map +1 -1
  48. package/dist/data/chat/Message.js +37 -2
  49. package/dist/data/chat/Message.js.map +1 -1
  50. package/dist/data/chat/approval.cjs +17 -0
  51. package/dist/data/chat/approval.cjs.map +1 -1
  52. package/dist/data/chat/approval.d.ts +5 -0
  53. package/dist/data/chat/approval.d.ts.map +1 -1
  54. package/dist/data/chat/approval.js +17 -0
  55. package/dist/data/chat/approval.js.map +1 -1
  56. package/dist/data/chat/fork-seed.cjs +22 -0
  57. package/dist/data/chat/fork-seed.cjs.map +1 -0
  58. package/dist/data/chat/fork-seed.d.ts +8 -0
  59. package/dist/data/chat/fork-seed.d.ts.map +1 -0
  60. package/dist/data/chat/fork-seed.js +22 -0
  61. package/dist/data/chat/fork-seed.js.map +1 -0
  62. package/dist/data/chat/types.cjs.map +1 -1
  63. package/dist/data/chat/types.d.ts +19 -0
  64. package/dist/data/chat/types.d.ts.map +1 -1
  65. package/dist/data/chat/types.js.map +1 -1
  66. package/dist/data/chat/usage-snapshot.cjs +10 -1
  67. package/dist/data/chat/usage-snapshot.cjs.map +1 -1
  68. package/dist/data/chat/usage-snapshot.d.ts.map +1 -1
  69. package/dist/data/chat/usage-snapshot.js +10 -1
  70. package/dist/data/chat/usage-snapshot.js.map +1 -1
  71. package/dist/data/runtime/RuntimeBar.cjs +3 -0
  72. package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
  73. package/dist/data/runtime/RuntimeBar.d.ts +3 -1
  74. package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
  75. package/dist/data/runtime/RuntimeBar.js +3 -0
  76. package/dist/data/runtime/RuntimeBar.js.map +1 -1
  77. package/dist/data/runtime/RuntimeBarCombo.cjs +15 -1
  78. package/dist/data/runtime/RuntimeBarCombo.cjs.map +1 -1
  79. package/dist/data/runtime/RuntimeBarCombo.d.ts +2 -1
  80. package/dist/data/runtime/RuntimeBarCombo.d.ts.map +1 -1
  81. package/dist/data/runtime/RuntimeBarCombo.js +15 -1
  82. package/dist/data/runtime/RuntimeBarCombo.js.map +1 -1
  83. package/dist/data/runtime/RuntimeBarSegments.cjs +7 -0
  84. package/dist/data/runtime/RuntimeBarSegments.cjs.map +1 -1
  85. package/dist/data/runtime/RuntimeBarSegments.d.ts +2 -1
  86. package/dist/data/runtime/RuntimeBarSegments.d.ts.map +1 -1
  87. package/dist/data/runtime/RuntimeBarSegments.js +7 -0
  88. package/dist/data/runtime/RuntimeBarSegments.js.map +1 -1
  89. package/dist/data/version-info.cjs +3 -3
  90. package/dist/data/version-info.js +3 -3
  91. package/dist/styles.css +1 -1
  92. package/package.json +1 -1
@@ -13,6 +13,7 @@ function AdvancedChatConfig({
13
13
  onRuntimeChange,
14
14
  runtimeFamilies,
15
15
  reasoningEfforts,
16
+ runtimeLocked = false,
16
17
  permissionMode,
17
18
  onPermissionModeChange,
18
19
  temperature,
@@ -35,6 +36,7 @@ function AdvancedChatConfig({
35
36
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
36
37
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
37
38
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Runtime" }),
39
+ runtimeLocked && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: "Model and backend are locked after the first message. Fork this conversation to change them; effort and generation settings remain adjustable." }),
38
40
  catalogLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: "Checking model and runtime availability…" }),
39
41
  catalogError && /* @__PURE__ */ jsxRuntime.jsxs(
40
42
  "div",
@@ -65,6 +67,7 @@ function AdvancedChatConfig({
65
67
  onChange: (next) => onRuntimeChange == null ? void 0 : onRuntimeChange(next),
66
68
  models,
67
69
  reasoningEfforts,
70
+ locked: runtimeLocked,
68
71
  ...runtimeFamilies ? { families: runtimeFamilies } : {},
69
72
  className: "max-w-full"
70
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AdvancedChatConfig.cjs","sources":["../../../src/data/ai/AdvancedChatConfig.tsx"],"sourcesContent":["import { Button } from \"../../components/button\";\nimport { cn } from \"../../lib/utils\";\nimport { ProviderStatusPanel } from \"../runtime/ProviderStatusPanel\";\nimport { RuntimeBar } from \"../runtime/RuntimeBar\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n type SpecRuntimeFamily,\n} from \"../runtime/runtime-mode\";\nimport type {\n ChatBudgetConfig,\n ChatModel,\n ChatModelRuntime,\n ChatUsageSummary,\n ClaudePermissionMode,\n} from \"../chat/types\";\nimport { CLAUDE_PERMISSION_MODE_OPTIONS } from \"../chat/types\";\n\nexport type AdvancedChatConfigProps = {\n models: ChatModel[];\n runtime: ChatModelRuntime;\n onRuntimeChange?: ((runtime: ChatModelRuntime) => void) | undefined;\n runtimeFamilies?: SpecRuntimeFamily[] | undefined;\n reasoningEfforts: string[];\n permissionMode: ClaudePermissionMode;\n onPermissionModeChange?: ((mode: ClaudePermissionMode) => void) | undefined;\n temperature?: number | undefined;\n onTemperatureChange?: ((temperature: number | undefined) => void) | undefined;\n budget?: ChatBudgetConfig | undefined;\n onBudgetChange?: ((budget: ChatBudgetConfig) => void) | undefined;\n usage?: ChatUsageSummary | null | undefined;\n catalogLoading?: boolean | undefined;\n catalogError?: string | null | undefined;\n onCatalogRetry?: (() => void) | undefined;\n};\n\nexport function AdvancedChatConfig({\n models,\n runtime,\n onRuntimeChange,\n runtimeFamilies,\n reasoningEfforts,\n permissionMode,\n onPermissionModeChange,\n temperature,\n onTemperatureChange,\n budget,\n onBudgetChange,\n usage,\n catalogLoading = false,\n catalogError = null,\n onCatalogRetry,\n}: AdvancedChatConfigProps) {\n const updateBudget = (key: keyof ChatBudgetConfig, raw: string) => {\n const next: ChatBudgetConfig = { ...budget };\n const parsed = parseOptionalNumber(raw, key === \"maxTokens\");\n if (parsed === undefined) delete next[key];\n else next[key] = parsed;\n onBudgetChange?.(next);\n };\n\n return (\n <div className=\"grid min-h-0 flex-1 gap-4 overflow-y-auto lg:grid-cols-[minmax(0,1fr)_minmax(18rem,24rem)]\">\n <div className=\"space-y-4\">\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Runtime\n </div>\n {catalogLoading && (\n <div className=\"text-xs text-muted-foreground\">\n Checking model and runtime availability…\n </div>\n )}\n {catalogError && (\n <div\n role=\"alert\"\n className=\"flex items-center justify-between gap-3 rounded border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive\"\n >\n <span>{catalogError}</span>\n {onCatalogRetry && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={onCatalogRetry}\n >\n Retry\n </Button>\n )}\n </div>\n )}\n <RuntimeBar\n variant=\"segmented\"\n ariaLabel=\"Advanced runtime\"\n value={runtime}\n onChange={(next) => onRuntimeChange?.(next)}\n models={models}\n reasoningEfforts={reasoningEfforts}\n {...(runtimeFamilies ? { families: runtimeFamilies } : {})}\n className=\"max-w-full\"\n />\n <label className=\"grid max-w-md grid-cols-[9rem_minmax(0,1fr)] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Permission mode</span>\n <select\n aria-label=\"Permission mode\"\n value={permissionMode}\n onChange={(event) =>\n onPermissionModeChange?.(\n event.target.value as ClaudePermissionMode\n )\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n >\n {CLAUDE_PERMISSION_MODE_OPTIONS.map((option) => (\n <option\n key={option.value}\n value={option.value}\n title={option.description}\n >\n {option.label}\n </option>\n ))}\n </select>\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Generation\n </div>\n <label className=\"grid grid-cols-[8rem_minmax(0,1fr)_4rem] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Temperature</span>\n <input\n type=\"range\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? 0}\n onChange={(event) =>\n onTemperatureChange?.(Number(event.target.value))\n }\n />\n <input\n type=\"number\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? \"\"}\n onChange={(event) =>\n onTemperatureChange?.(parseOptionalNumber(event.target.value))\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Budget\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max cost</span>\n <input\n type=\"number\"\n min={0}\n step={0.01}\n value={budget?.cost ?? \"\"}\n onChange={(event) => updateBudget(\"cost\", event.target.value)}\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max tokens</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n value={budget?.maxTokens ?? \"\"}\n onChange={(event) =>\n updateBudget(\"maxTokens\", event.target.value)\n }\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </div>\n </section>\n </div>\n <UsageCostPanel\n usage={usage}\n models={models}\n families={runtimeFamilies ?? SPEC_RUNTIME_FAMILIES}\n showProviderStatus={!catalogLoading}\n />\n </div>\n );\n}\n\nfunction UsageCostPanel({\n usage,\n models,\n families,\n showProviderStatus,\n}: {\n usage?: ChatUsageSummary | null | undefined;\n models: ChatModel[];\n families: SpecRuntimeFamily[];\n showProviderStatus: boolean;\n}) {\n const tokens = usage?.usage;\n const costs = usage?.costBreakdown;\n return (\n <aside className=\"space-y-3 border-t border-border pt-4 lg:border-l lg:border-t-0 lg:pl-4 lg:pt-0\">\n {/* Both tables describe the last completed turn; only the bold total is\n cumulative. Labelled explicitly because the rows will not sum to it,\n and the full conversation breakdown lives in the Costs tab. */}\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Usage (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow\n label=\"Context\"\n value={`${formatNumber(usage?.usedTokens)} / ${formatNumber(\n usage?.maxTokens\n )}`}\n />\n <MetricRow\n label=\"Input tokens\"\n value={formatNumber(tokens?.inputTokens)}\n />\n <MetricRow\n label=\"Output tokens\"\n value={formatNumber(tokens?.outputTokens)}\n />\n <MetricRow\n label=\"Reasoning tokens\"\n value={formatNumber(tokens?.reasoningTokens)}\n />\n <MetricRow\n label=\"Cache read tokens\"\n value={formatNumber(tokens?.cacheReadTokens)}\n />\n <MetricRow\n label=\"Cache write tokens\"\n value={formatNumber(tokens?.cacheWriteTokens)}\n />\n <MetricRow\n label=\"Total tokens\"\n value={formatNumber(tokens?.totalTokens)}\n />\n </div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Cost (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow label=\"Input\" value={formatUSD(costs?.inputUsd)} />\n <MetricRow label=\"Output\" value={formatUSD(costs?.outputUsd)} />\n <MetricRow label=\"Reasoning\" value={formatUSD(costs?.reasoningUsd)} />\n <MetricRow label=\"Cache read\" value={formatUSD(costs?.cacheReadUsd)} />\n <MetricRow\n label=\"Cache write\"\n value={formatUSD(costs?.cacheWriteUsd)}\n />\n <MetricRow\n label=\"Conversation total\"\n value={formatUSD(usage?.cost ?? costs?.totalUsd)}\n strong\n />\n </div>\n {showProviderStatus && (\n <ProviderStatusPanel models={models} families={families} />\n )}\n </aside>\n );\n}\n\nfunction MetricRow({\n label,\n value,\n strong = false,\n}: {\n label: string;\n value: string;\n strong?: boolean;\n}) {\n return (\n <div className=\"grid grid-cols-[minmax(0,1fr)_auto] gap-3 border-b border-border px-2 py-1.5 text-xs last:border-b-0\">\n <span className=\"truncate text-muted-foreground\">{label}</span>\n <span\n className={cn(\"font-mono\", strong && \"font-semibold text-foreground\")}\n >\n {value}\n </span>\n </div>\n );\n}\n\nfunction parseOptionalNumber(raw: string, integer = false): number | undefined {\n if (raw.trim() === \"\") return undefined;\n const value = Number(raw);\n if (!Number.isFinite(value)) return undefined;\n return integer ? Math.max(0, Math.trunc(value)) : value;\n}\n\nfunction formatNumber(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return new Intl.NumberFormat().format(value);\n}\n\nfunction formatUSD(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return `$${value.toFixed(value >= 1 ? 4 : 6)}`;\n}\n"],"names":["jsxs","jsx","Button","RuntimeBar","CLAUDE_PERMISSION_MODE_OPTIONS","SPEC_RUNTIME_FAMILIES","ProviderStatusPanel","cn"],"mappings":"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"}
1
+ {"version":3,"file":"AdvancedChatConfig.cjs","sources":["../../../src/data/ai/AdvancedChatConfig.tsx"],"sourcesContent":["import { Button } from \"../../components/button\";\nimport { cn } from \"../../lib/utils\";\nimport { ProviderStatusPanel } from \"../runtime/ProviderStatusPanel\";\nimport { RuntimeBar } from \"../runtime/RuntimeBar\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n type SpecRuntimeFamily,\n} from \"../runtime/runtime-mode\";\nimport type {\n ChatBudgetConfig,\n ChatModel,\n ChatModelRuntime,\n ChatUsageSummary,\n ClaudePermissionMode,\n} from \"../chat/types\";\nimport { CLAUDE_PERMISSION_MODE_OPTIONS } from \"../chat/types\";\n\nexport type AdvancedChatConfigProps = {\n models: ChatModel[];\n runtime: ChatModelRuntime;\n onRuntimeChange?: ((runtime: ChatModelRuntime) => void) | undefined;\n runtimeFamilies?: SpecRuntimeFamily[] | undefined;\n reasoningEfforts: string[];\n runtimeLocked?: boolean | undefined;\n permissionMode: ClaudePermissionMode;\n onPermissionModeChange?: ((mode: ClaudePermissionMode) => void) | undefined;\n temperature?: number | undefined;\n onTemperatureChange?: ((temperature: number | undefined) => void) | undefined;\n budget?: ChatBudgetConfig | undefined;\n onBudgetChange?: ((budget: ChatBudgetConfig) => void) | undefined;\n usage?: ChatUsageSummary | null | undefined;\n catalogLoading?: boolean | undefined;\n catalogError?: string | null | undefined;\n onCatalogRetry?: (() => void) | undefined;\n};\n\nexport function AdvancedChatConfig({\n models,\n runtime,\n onRuntimeChange,\n runtimeFamilies,\n reasoningEfforts,\n runtimeLocked = false,\n permissionMode,\n onPermissionModeChange,\n temperature,\n onTemperatureChange,\n budget,\n onBudgetChange,\n usage,\n catalogLoading = false,\n catalogError = null,\n onCatalogRetry,\n}: AdvancedChatConfigProps) {\n const updateBudget = (key: keyof ChatBudgetConfig, raw: string) => {\n const next: ChatBudgetConfig = { ...budget };\n const parsed = parseOptionalNumber(raw, key === \"maxTokens\");\n if (parsed === undefined) delete next[key];\n else next[key] = parsed;\n onBudgetChange?.(next);\n };\n\n return (\n <div className=\"grid min-h-0 flex-1 gap-4 overflow-y-auto lg:grid-cols-[minmax(0,1fr)_minmax(18rem,24rem)]\">\n <div className=\"space-y-4\">\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Runtime\n </div>\n {runtimeLocked && (\n <div className=\"rounded border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground\">\n Model and backend are locked after the first message. Fork this\n conversation to change them; effort and generation settings remain\n adjustable.\n </div>\n )}\n {catalogLoading && (\n <div className=\"text-xs text-muted-foreground\">\n Checking model and runtime availability…\n </div>\n )}\n {catalogError && (\n <div\n role=\"alert\"\n className=\"flex items-center justify-between gap-3 rounded border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive\"\n >\n <span>{catalogError}</span>\n {onCatalogRetry && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={onCatalogRetry}\n >\n Retry\n </Button>\n )}\n </div>\n )}\n <RuntimeBar\n variant=\"segmented\"\n ariaLabel=\"Advanced runtime\"\n value={runtime}\n onChange={(next) => onRuntimeChange?.(next)}\n models={models}\n reasoningEfforts={reasoningEfforts}\n locked={runtimeLocked}\n {...(runtimeFamilies ? { families: runtimeFamilies } : {})}\n className=\"max-w-full\"\n />\n <label className=\"grid max-w-md grid-cols-[9rem_minmax(0,1fr)] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Permission mode</span>\n <select\n aria-label=\"Permission mode\"\n value={permissionMode}\n onChange={(event) =>\n onPermissionModeChange?.(\n event.target.value as ClaudePermissionMode,\n )\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n >\n {CLAUDE_PERMISSION_MODE_OPTIONS.map((option) => (\n <option\n key={option.value}\n value={option.value}\n title={option.description}\n >\n {option.label}\n </option>\n ))}\n </select>\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Generation\n </div>\n <label className=\"grid grid-cols-[8rem_minmax(0,1fr)_4rem] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Temperature</span>\n <input\n type=\"range\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? 0}\n onChange={(event) =>\n onTemperatureChange?.(Number(event.target.value))\n }\n />\n <input\n type=\"number\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? \"\"}\n onChange={(event) =>\n onTemperatureChange?.(parseOptionalNumber(event.target.value))\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Budget\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max cost</span>\n <input\n type=\"number\"\n min={0}\n step={0.01}\n value={budget?.cost ?? \"\"}\n onChange={(event) => updateBudget(\"cost\", event.target.value)}\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max tokens</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n value={budget?.maxTokens ?? \"\"}\n onChange={(event) =>\n updateBudget(\"maxTokens\", event.target.value)\n }\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </div>\n </section>\n </div>\n <UsageCostPanel\n usage={usage}\n models={models}\n families={runtimeFamilies ?? SPEC_RUNTIME_FAMILIES}\n showProviderStatus={!catalogLoading}\n />\n </div>\n );\n}\n\nfunction UsageCostPanel({\n usage,\n models,\n families,\n showProviderStatus,\n}: {\n usage?: ChatUsageSummary | null | undefined;\n models: ChatModel[];\n families: SpecRuntimeFamily[];\n showProviderStatus: boolean;\n}) {\n const tokens = usage?.usage;\n const costs = usage?.costBreakdown;\n return (\n <aside className=\"space-y-3 border-t border-border pt-4 lg:border-l lg:border-t-0 lg:pl-4 lg:pt-0\">\n {/* Both tables describe the last completed turn; only the bold total is\n cumulative. Labelled explicitly because the rows will not sum to it,\n and the full conversation breakdown lives in the Costs tab. */}\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Usage (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow\n label=\"Context\"\n value={`${formatNumber(usage?.usedTokens)} / ${formatNumber(\n usage?.maxTokens,\n )}`}\n />\n <MetricRow\n label=\"Input tokens\"\n value={formatNumber(tokens?.inputTokens)}\n />\n <MetricRow\n label=\"Output tokens\"\n value={formatNumber(tokens?.outputTokens)}\n />\n <MetricRow\n label=\"Reasoning tokens\"\n value={formatNumber(tokens?.reasoningTokens)}\n />\n <MetricRow\n label=\"Cache read tokens\"\n value={formatNumber(tokens?.cacheReadTokens)}\n />\n <MetricRow\n label=\"Cache write tokens\"\n value={formatNumber(tokens?.cacheWriteTokens)}\n />\n <MetricRow\n label=\"Total tokens\"\n value={formatNumber(tokens?.totalTokens)}\n />\n </div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Cost (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow label=\"Input\" value={formatUSD(costs?.inputUsd)} />\n <MetricRow label=\"Output\" value={formatUSD(costs?.outputUsd)} />\n <MetricRow label=\"Reasoning\" value={formatUSD(costs?.reasoningUsd)} />\n <MetricRow label=\"Cache read\" value={formatUSD(costs?.cacheReadUsd)} />\n <MetricRow\n label=\"Cache write\"\n value={formatUSD(costs?.cacheWriteUsd)}\n />\n <MetricRow\n label=\"Conversation total\"\n value={formatUSD(usage?.cost ?? costs?.totalUsd)}\n strong\n />\n </div>\n {showProviderStatus && (\n <ProviderStatusPanel models={models} families={families} />\n )}\n </aside>\n );\n}\n\nfunction MetricRow({\n label,\n value,\n strong = false,\n}: {\n label: string;\n value: string;\n strong?: boolean;\n}) {\n return (\n <div className=\"grid grid-cols-[minmax(0,1fr)_auto] gap-3 border-b border-border px-2 py-1.5 text-xs last:border-b-0\">\n <span className=\"truncate text-muted-foreground\">{label}</span>\n <span\n className={cn(\"font-mono\", strong && \"font-semibold text-foreground\")}\n >\n {value}\n </span>\n </div>\n );\n}\n\nfunction parseOptionalNumber(raw: string, integer = false): number | undefined {\n if (raw.trim() === \"\") return undefined;\n const value = Number(raw);\n if (!Number.isFinite(value)) return undefined;\n return integer ? Math.max(0, Math.trunc(value)) : value;\n}\n\nfunction formatNumber(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return new Intl.NumberFormat().format(value);\n}\n\nfunction formatUSD(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return `$${value.toFixed(value >= 1 ? 4 : 6)}`;\n}\n"],"names":["jsxs","jsx","Button","RuntimeBar","CLAUDE_PERMISSION_MODE_OPTIONS","SPEC_RUNTIME_FAMILIES","ProviderStatusPanel","cn"],"mappings":"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"}
@@ -6,6 +6,7 @@ export type AdvancedChatConfigProps = {
6
6
  onRuntimeChange?: ((runtime: ChatModelRuntime) => void) | undefined;
7
7
  runtimeFamilies?: SpecRuntimeFamily[] | undefined;
8
8
  reasoningEfforts: string[];
9
+ runtimeLocked?: boolean | undefined;
9
10
  permissionMode: ClaudePermissionMode;
10
11
  onPermissionModeChange?: ((mode: ClaudePermissionMode) => void) | undefined;
11
12
  temperature?: number | undefined;
@@ -17,5 +18,5 @@ export type AdvancedChatConfigProps = {
17
18
  catalogError?: string | null | undefined;
18
19
  onCatalogRetry?: (() => void) | undefined;
19
20
  };
20
- export declare function AdvancedChatConfig({ models, runtime, onRuntimeChange, runtimeFamilies, reasoningEfforts, permissionMode, onPermissionModeChange, temperature, onTemperatureChange, budget, onBudgetChange, usage, catalogLoading, catalogError, onCatalogRetry, }: AdvancedChatConfigProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function AdvancedChatConfig({ models, runtime, onRuntimeChange, runtimeFamilies, reasoningEfforts, runtimeLocked, permissionMode, onPermissionModeChange, temperature, onTemperatureChange, budget, onBudgetChange, usage, catalogLoading, catalogError, onCatalogRetry, }: AdvancedChatConfigProps): import("react/jsx-runtime").JSX.Element;
21
22
  //# sourceMappingURL=AdvancedChatConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdvancedChatConfig.d.ts","sourceRoot":"","sources":["../../../src/data/ai/AdvancedChatConfig.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAGvB,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,eAAe,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACpE,eAAe,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAClD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,EAAE,oBAAoB,CAAC;IACrC,sBAAsB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mBAAmB,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACtC,cAAc,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAClE,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,cAAc,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,OAAO,EACP,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,cAAc,EACd,KAAK,EACL,cAAsB,EACtB,YAAmB,EACnB,cAAc,GACf,EAAE,uBAAuB,2CA8IzB"}
1
+ {"version":3,"file":"AdvancedChatConfig.d.ts","sourceRoot":"","sources":["../../../src/data/ai/AdvancedChatConfig.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAGvB,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,eAAe,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACpE,eAAe,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAClD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,cAAc,EAAE,oBAAoB,CAAC;IACrC,sBAAsB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mBAAmB,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACtC,cAAc,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAClE,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,cAAc,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,OAAO,EACP,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,aAAqB,EACrB,cAAc,EACd,sBAAsB,EACtB,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,cAAc,EACd,KAAK,EACL,cAAsB,EACtB,YAAmB,EACnB,cAAc,GACf,EAAE,uBAAuB,2CAsJzB"}
@@ -11,6 +11,7 @@ function AdvancedChatConfig({
11
11
  onRuntimeChange,
12
12
  runtimeFamilies,
13
13
  reasoningEfforts,
14
+ runtimeLocked = false,
14
15
  permissionMode,
15
16
  onPermissionModeChange,
16
17
  temperature,
@@ -33,6 +34,7 @@ function AdvancedChatConfig({
33
34
  /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
34
35
  /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
35
36
  /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Runtime" }),
37
+ runtimeLocked && /* @__PURE__ */ jsx("div", { className: "rounded border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground", children: "Model and backend are locked after the first message. Fork this conversation to change them; effort and generation settings remain adjustable." }),
36
38
  catalogLoading && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Checking model and runtime availability…" }),
37
39
  catalogError && /* @__PURE__ */ jsxs(
38
40
  "div",
@@ -63,6 +65,7 @@ function AdvancedChatConfig({
63
65
  onChange: (next) => onRuntimeChange == null ? void 0 : onRuntimeChange(next),
64
66
  models,
65
67
  reasoningEfforts,
68
+ locked: runtimeLocked,
66
69
  ...runtimeFamilies ? { families: runtimeFamilies } : {},
67
70
  className: "max-w-full"
68
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AdvancedChatConfig.js","sources":["../../../src/data/ai/AdvancedChatConfig.tsx"],"sourcesContent":["import { Button } from \"../../components/button\";\nimport { cn } from \"../../lib/utils\";\nimport { ProviderStatusPanel } from \"../runtime/ProviderStatusPanel\";\nimport { RuntimeBar } from \"../runtime/RuntimeBar\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n type SpecRuntimeFamily,\n} from \"../runtime/runtime-mode\";\nimport type {\n ChatBudgetConfig,\n ChatModel,\n ChatModelRuntime,\n ChatUsageSummary,\n ClaudePermissionMode,\n} from \"../chat/types\";\nimport { CLAUDE_PERMISSION_MODE_OPTIONS } from \"../chat/types\";\n\nexport type AdvancedChatConfigProps = {\n models: ChatModel[];\n runtime: ChatModelRuntime;\n onRuntimeChange?: ((runtime: ChatModelRuntime) => void) | undefined;\n runtimeFamilies?: SpecRuntimeFamily[] | undefined;\n reasoningEfforts: string[];\n permissionMode: ClaudePermissionMode;\n onPermissionModeChange?: ((mode: ClaudePermissionMode) => void) | undefined;\n temperature?: number | undefined;\n onTemperatureChange?: ((temperature: number | undefined) => void) | undefined;\n budget?: ChatBudgetConfig | undefined;\n onBudgetChange?: ((budget: ChatBudgetConfig) => void) | undefined;\n usage?: ChatUsageSummary | null | undefined;\n catalogLoading?: boolean | undefined;\n catalogError?: string | null | undefined;\n onCatalogRetry?: (() => void) | undefined;\n};\n\nexport function AdvancedChatConfig({\n models,\n runtime,\n onRuntimeChange,\n runtimeFamilies,\n reasoningEfforts,\n permissionMode,\n onPermissionModeChange,\n temperature,\n onTemperatureChange,\n budget,\n onBudgetChange,\n usage,\n catalogLoading = false,\n catalogError = null,\n onCatalogRetry,\n}: AdvancedChatConfigProps) {\n const updateBudget = (key: keyof ChatBudgetConfig, raw: string) => {\n const next: ChatBudgetConfig = { ...budget };\n const parsed = parseOptionalNumber(raw, key === \"maxTokens\");\n if (parsed === undefined) delete next[key];\n else next[key] = parsed;\n onBudgetChange?.(next);\n };\n\n return (\n <div className=\"grid min-h-0 flex-1 gap-4 overflow-y-auto lg:grid-cols-[minmax(0,1fr)_minmax(18rem,24rem)]\">\n <div className=\"space-y-4\">\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Runtime\n </div>\n {catalogLoading && (\n <div className=\"text-xs text-muted-foreground\">\n Checking model and runtime availability…\n </div>\n )}\n {catalogError && (\n <div\n role=\"alert\"\n className=\"flex items-center justify-between gap-3 rounded border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive\"\n >\n <span>{catalogError}</span>\n {onCatalogRetry && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={onCatalogRetry}\n >\n Retry\n </Button>\n )}\n </div>\n )}\n <RuntimeBar\n variant=\"segmented\"\n ariaLabel=\"Advanced runtime\"\n value={runtime}\n onChange={(next) => onRuntimeChange?.(next)}\n models={models}\n reasoningEfforts={reasoningEfforts}\n {...(runtimeFamilies ? { families: runtimeFamilies } : {})}\n className=\"max-w-full\"\n />\n <label className=\"grid max-w-md grid-cols-[9rem_minmax(0,1fr)] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Permission mode</span>\n <select\n aria-label=\"Permission mode\"\n value={permissionMode}\n onChange={(event) =>\n onPermissionModeChange?.(\n event.target.value as ClaudePermissionMode\n )\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n >\n {CLAUDE_PERMISSION_MODE_OPTIONS.map((option) => (\n <option\n key={option.value}\n value={option.value}\n title={option.description}\n >\n {option.label}\n </option>\n ))}\n </select>\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Generation\n </div>\n <label className=\"grid grid-cols-[8rem_minmax(0,1fr)_4rem] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Temperature</span>\n <input\n type=\"range\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? 0}\n onChange={(event) =>\n onTemperatureChange?.(Number(event.target.value))\n }\n />\n <input\n type=\"number\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? \"\"}\n onChange={(event) =>\n onTemperatureChange?.(parseOptionalNumber(event.target.value))\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Budget\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max cost</span>\n <input\n type=\"number\"\n min={0}\n step={0.01}\n value={budget?.cost ?? \"\"}\n onChange={(event) => updateBudget(\"cost\", event.target.value)}\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max tokens</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n value={budget?.maxTokens ?? \"\"}\n onChange={(event) =>\n updateBudget(\"maxTokens\", event.target.value)\n }\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </div>\n </section>\n </div>\n <UsageCostPanel\n usage={usage}\n models={models}\n families={runtimeFamilies ?? SPEC_RUNTIME_FAMILIES}\n showProviderStatus={!catalogLoading}\n />\n </div>\n );\n}\n\nfunction UsageCostPanel({\n usage,\n models,\n families,\n showProviderStatus,\n}: {\n usage?: ChatUsageSummary | null | undefined;\n models: ChatModel[];\n families: SpecRuntimeFamily[];\n showProviderStatus: boolean;\n}) {\n const tokens = usage?.usage;\n const costs = usage?.costBreakdown;\n return (\n <aside className=\"space-y-3 border-t border-border pt-4 lg:border-l lg:border-t-0 lg:pl-4 lg:pt-0\">\n {/* Both tables describe the last completed turn; only the bold total is\n cumulative. Labelled explicitly because the rows will not sum to it,\n and the full conversation breakdown lives in the Costs tab. */}\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Usage (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow\n label=\"Context\"\n value={`${formatNumber(usage?.usedTokens)} / ${formatNumber(\n usage?.maxTokens\n )}`}\n />\n <MetricRow\n label=\"Input tokens\"\n value={formatNumber(tokens?.inputTokens)}\n />\n <MetricRow\n label=\"Output tokens\"\n value={formatNumber(tokens?.outputTokens)}\n />\n <MetricRow\n label=\"Reasoning tokens\"\n value={formatNumber(tokens?.reasoningTokens)}\n />\n <MetricRow\n label=\"Cache read tokens\"\n value={formatNumber(tokens?.cacheReadTokens)}\n />\n <MetricRow\n label=\"Cache write tokens\"\n value={formatNumber(tokens?.cacheWriteTokens)}\n />\n <MetricRow\n label=\"Total tokens\"\n value={formatNumber(tokens?.totalTokens)}\n />\n </div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Cost (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow label=\"Input\" value={formatUSD(costs?.inputUsd)} />\n <MetricRow label=\"Output\" value={formatUSD(costs?.outputUsd)} />\n <MetricRow label=\"Reasoning\" value={formatUSD(costs?.reasoningUsd)} />\n <MetricRow label=\"Cache read\" value={formatUSD(costs?.cacheReadUsd)} />\n <MetricRow\n label=\"Cache write\"\n value={formatUSD(costs?.cacheWriteUsd)}\n />\n <MetricRow\n label=\"Conversation total\"\n value={formatUSD(usage?.cost ?? costs?.totalUsd)}\n strong\n />\n </div>\n {showProviderStatus && (\n <ProviderStatusPanel models={models} families={families} />\n )}\n </aside>\n );\n}\n\nfunction MetricRow({\n label,\n value,\n strong = false,\n}: {\n label: string;\n value: string;\n strong?: boolean;\n}) {\n return (\n <div className=\"grid grid-cols-[minmax(0,1fr)_auto] gap-3 border-b border-border px-2 py-1.5 text-xs last:border-b-0\">\n <span className=\"truncate text-muted-foreground\">{label}</span>\n <span\n className={cn(\"font-mono\", strong && \"font-semibold text-foreground\")}\n >\n {value}\n </span>\n </div>\n );\n}\n\nfunction parseOptionalNumber(raw: string, integer = false): number | undefined {\n if (raw.trim() === \"\") return undefined;\n const value = Number(raw);\n if (!Number.isFinite(value)) return undefined;\n return integer ? Math.max(0, Math.trunc(value)) : value;\n}\n\nfunction formatNumber(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return new Intl.NumberFormat().format(value);\n}\n\nfunction formatUSD(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return `$${value.toFixed(value >= 1 ? 4 : 6)}`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AdvancedChatConfig.js","sources":["../../../src/data/ai/AdvancedChatConfig.tsx"],"sourcesContent":["import { Button } from \"../../components/button\";\nimport { cn } from \"../../lib/utils\";\nimport { ProviderStatusPanel } from \"../runtime/ProviderStatusPanel\";\nimport { RuntimeBar } from \"../runtime/RuntimeBar\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n type SpecRuntimeFamily,\n} from \"../runtime/runtime-mode\";\nimport type {\n ChatBudgetConfig,\n ChatModel,\n ChatModelRuntime,\n ChatUsageSummary,\n ClaudePermissionMode,\n} from \"../chat/types\";\nimport { CLAUDE_PERMISSION_MODE_OPTIONS } from \"../chat/types\";\n\nexport type AdvancedChatConfigProps = {\n models: ChatModel[];\n runtime: ChatModelRuntime;\n onRuntimeChange?: ((runtime: ChatModelRuntime) => void) | undefined;\n runtimeFamilies?: SpecRuntimeFamily[] | undefined;\n reasoningEfforts: string[];\n runtimeLocked?: boolean | undefined;\n permissionMode: ClaudePermissionMode;\n onPermissionModeChange?: ((mode: ClaudePermissionMode) => void) | undefined;\n temperature?: number | undefined;\n onTemperatureChange?: ((temperature: number | undefined) => void) | undefined;\n budget?: ChatBudgetConfig | undefined;\n onBudgetChange?: ((budget: ChatBudgetConfig) => void) | undefined;\n usage?: ChatUsageSummary | null | undefined;\n catalogLoading?: boolean | undefined;\n catalogError?: string | null | undefined;\n onCatalogRetry?: (() => void) | undefined;\n};\n\nexport function AdvancedChatConfig({\n models,\n runtime,\n onRuntimeChange,\n runtimeFamilies,\n reasoningEfforts,\n runtimeLocked = false,\n permissionMode,\n onPermissionModeChange,\n temperature,\n onTemperatureChange,\n budget,\n onBudgetChange,\n usage,\n catalogLoading = false,\n catalogError = null,\n onCatalogRetry,\n}: AdvancedChatConfigProps) {\n const updateBudget = (key: keyof ChatBudgetConfig, raw: string) => {\n const next: ChatBudgetConfig = { ...budget };\n const parsed = parseOptionalNumber(raw, key === \"maxTokens\");\n if (parsed === undefined) delete next[key];\n else next[key] = parsed;\n onBudgetChange?.(next);\n };\n\n return (\n <div className=\"grid min-h-0 flex-1 gap-4 overflow-y-auto lg:grid-cols-[minmax(0,1fr)_minmax(18rem,24rem)]\">\n <div className=\"space-y-4\">\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Runtime\n </div>\n {runtimeLocked && (\n <div className=\"rounded border border-border bg-muted/40 px-3 py-2 text-xs text-muted-foreground\">\n Model and backend are locked after the first message. Fork this\n conversation to change them; effort and generation settings remain\n adjustable.\n </div>\n )}\n {catalogLoading && (\n <div className=\"text-xs text-muted-foreground\">\n Checking model and runtime availability…\n </div>\n )}\n {catalogError && (\n <div\n role=\"alert\"\n className=\"flex items-center justify-between gap-3 rounded border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive\"\n >\n <span>{catalogError}</span>\n {onCatalogRetry && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={onCatalogRetry}\n >\n Retry\n </Button>\n )}\n </div>\n )}\n <RuntimeBar\n variant=\"segmented\"\n ariaLabel=\"Advanced runtime\"\n value={runtime}\n onChange={(next) => onRuntimeChange?.(next)}\n models={models}\n reasoningEfforts={reasoningEfforts}\n locked={runtimeLocked}\n {...(runtimeFamilies ? { families: runtimeFamilies } : {})}\n className=\"max-w-full\"\n />\n <label className=\"grid max-w-md grid-cols-[9rem_minmax(0,1fr)] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Permission mode</span>\n <select\n aria-label=\"Permission mode\"\n value={permissionMode}\n onChange={(event) =>\n onPermissionModeChange?.(\n event.target.value as ClaudePermissionMode,\n )\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n >\n {CLAUDE_PERMISSION_MODE_OPTIONS.map((option) => (\n <option\n key={option.value}\n value={option.value}\n title={option.description}\n >\n {option.label}\n </option>\n ))}\n </select>\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Generation\n </div>\n <label className=\"grid grid-cols-[8rem_minmax(0,1fr)_4rem] items-center gap-3 text-xs\">\n <span className=\"text-muted-foreground\">Temperature</span>\n <input\n type=\"range\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? 0}\n onChange={(event) =>\n onTemperatureChange?.(Number(event.target.value))\n }\n />\n <input\n type=\"number\"\n min={0}\n max={2}\n step={0.1}\n value={temperature ?? \"\"}\n onChange={(event) =>\n onTemperatureChange?.(parseOptionalNumber(event.target.value))\n }\n className=\"h-8 rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </section>\n <section className=\"space-y-3\">\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Budget\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max cost</span>\n <input\n type=\"number\"\n min={0}\n step={0.01}\n value={budget?.cost ?? \"\"}\n onChange={(event) => updateBudget(\"cost\", event.target.value)}\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Max tokens</span>\n <input\n type=\"number\"\n min={0}\n step={1}\n value={budget?.maxTokens ?? \"\"}\n onChange={(event) =>\n updateBudget(\"maxTokens\", event.target.value)\n }\n className=\"h-8 w-full rounded border border-border bg-background px-2 text-xs\"\n />\n </label>\n </div>\n </section>\n </div>\n <UsageCostPanel\n usage={usage}\n models={models}\n families={runtimeFamilies ?? SPEC_RUNTIME_FAMILIES}\n showProviderStatus={!catalogLoading}\n />\n </div>\n );\n}\n\nfunction UsageCostPanel({\n usage,\n models,\n families,\n showProviderStatus,\n}: {\n usage?: ChatUsageSummary | null | undefined;\n models: ChatModel[];\n families: SpecRuntimeFamily[];\n showProviderStatus: boolean;\n}) {\n const tokens = usage?.usage;\n const costs = usage?.costBreakdown;\n return (\n <aside className=\"space-y-3 border-t border-border pt-4 lg:border-l lg:border-t-0 lg:pl-4 lg:pt-0\">\n {/* Both tables describe the last completed turn; only the bold total is\n cumulative. Labelled explicitly because the rows will not sum to it,\n and the full conversation breakdown lives in the Costs tab. */}\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Usage (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow\n label=\"Context\"\n value={`${formatNumber(usage?.usedTokens)} / ${formatNumber(\n usage?.maxTokens,\n )}`}\n />\n <MetricRow\n label=\"Input tokens\"\n value={formatNumber(tokens?.inputTokens)}\n />\n <MetricRow\n label=\"Output tokens\"\n value={formatNumber(tokens?.outputTokens)}\n />\n <MetricRow\n label=\"Reasoning tokens\"\n value={formatNumber(tokens?.reasoningTokens)}\n />\n <MetricRow\n label=\"Cache read tokens\"\n value={formatNumber(tokens?.cacheReadTokens)}\n />\n <MetricRow\n label=\"Cache write tokens\"\n value={formatNumber(tokens?.cacheWriteTokens)}\n />\n <MetricRow\n label=\"Total tokens\"\n value={formatNumber(tokens?.totalTokens)}\n />\n </div>\n <div className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Cost (last turn)\n </div>\n <div className=\"overflow-hidden rounded border border-border\">\n <MetricRow label=\"Input\" value={formatUSD(costs?.inputUsd)} />\n <MetricRow label=\"Output\" value={formatUSD(costs?.outputUsd)} />\n <MetricRow label=\"Reasoning\" value={formatUSD(costs?.reasoningUsd)} />\n <MetricRow label=\"Cache read\" value={formatUSD(costs?.cacheReadUsd)} />\n <MetricRow\n label=\"Cache write\"\n value={formatUSD(costs?.cacheWriteUsd)}\n />\n <MetricRow\n label=\"Conversation total\"\n value={formatUSD(usage?.cost ?? costs?.totalUsd)}\n strong\n />\n </div>\n {showProviderStatus && (\n <ProviderStatusPanel models={models} families={families} />\n )}\n </aside>\n );\n}\n\nfunction MetricRow({\n label,\n value,\n strong = false,\n}: {\n label: string;\n value: string;\n strong?: boolean;\n}) {\n return (\n <div className=\"grid grid-cols-[minmax(0,1fr)_auto] gap-3 border-b border-border px-2 py-1.5 text-xs last:border-b-0\">\n <span className=\"truncate text-muted-foreground\">{label}</span>\n <span\n className={cn(\"font-mono\", strong && \"font-semibold text-foreground\")}\n >\n {value}\n </span>\n </div>\n );\n}\n\nfunction parseOptionalNumber(raw: string, integer = false): number | undefined {\n if (raw.trim() === \"\") return undefined;\n const value = Number(raw);\n if (!Number.isFinite(value)) return undefined;\n return integer ? Math.max(0, Math.trunc(value)) : value;\n}\n\nfunction formatNumber(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return new Intl.NumberFormat().format(value);\n}\n\nfunction formatUSD(value: number | undefined): string {\n if (value == null || !Number.isFinite(value)) return \"-\";\n return `$${value.toFixed(value >= 1 ? 4 : 6)}`;\n}\n"],"names":[],"mappings":"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"}
@@ -28,6 +28,7 @@ const utils = require("../../lib/utils.cjs");
28
28
  const button = require("../../components/button.cjs");
29
29
  const Icon = require("../Icon.cjs");
30
30
  const Chat = require("../chat/Chat.cjs");
31
+ const approval = require("../chat/approval.cjs");
31
32
  const chatWindowContext = require("./chat-window-context.cjs");
32
33
  const ThreadPicker = require("./ThreadPicker.cjs");
33
34
  const ContextBadges = require("./ContextBadges.cjs");
@@ -39,6 +40,7 @@ const ChatWindow_catalogs = require("./ChatWindow.catalogs.cjs");
39
40
  const ChatWindow_toolCatalog = require("./ChatWindow.tool-catalog.cjs");
40
41
  const ChatWindow_thread = require("./ChatWindow.thread.cjs");
41
42
  const ChatWindow_threadStatus = require("./ChatWindow.thread-status.cjs");
43
+ const UiGitBranch = require("../../icons/components/UiGitBranch.cjs");
42
44
  const UiAdd = require("../../icons/components/UiAdd.cjs");
43
45
  const UiFullscreen = require("../../icons/components/UiFullscreen.cjs");
44
46
  const UiClose = require("../../icons/components/UiClose.cjs");
@@ -111,13 +113,31 @@ function ChatWindow({
111
113
  handleRuntimeChange,
112
114
  handleModelChange,
113
115
  handleReasoningEffortChange,
114
- handleTemperatureChange
116
+ handleTemperatureChange,
117
+ replaceRuntimeIdentity,
118
+ replaceRuntime
115
119
  } = ChatWindow_runtime.useChatWindowRuntime({
116
120
  chat,
117
121
  initialModel: panel.initialModel,
118
122
  models: resolvedModels,
119
123
  storedRuntime: storedPrefs.runtime
120
124
  });
125
+ const [messageCount, setMessageCount] = react.useState(0);
126
+ const [runtimeBound, setRuntimeBound] = react.useState(false);
127
+ const [forking, setForking] = react.useState(false);
128
+ const runtimeLocked = runtimeBound || messageCount > 0;
129
+ const preferredRuntimeRef = react.useRef(runtime);
130
+ const threadIdRef = react.useRef(panel.threadId);
131
+ threadIdRef.current = panel.threadId;
132
+ react.useEffect(() => {
133
+ if (!runtimeLocked) preferredRuntimeRef.current = runtime;
134
+ }, [runtime, runtimeLocked]);
135
+ react.useEffect(() => {
136
+ setMessageCount(0);
137
+ setRuntimeBound(false);
138
+ setUsage(null);
139
+ replaceRuntime(preferredRuntimeRef.current);
140
+ }, [panel.threadId, replaceRuntime]);
121
141
  react.useEffect(() => {
122
142
  if ((chat == null ? void 0 : chat.budget) !== void 0) setBudget(chat.budget);
123
143
  }, [chat == null ? void 0 : chat.budget]);
@@ -147,12 +167,12 @@ function ChatWindow({
147
167
  }, [tools, toolsApi]);
148
168
  react.useEffect(() => {
149
169
  ChatWindow_preferences.saveChatPreferences({
150
- runtime,
170
+ runtime: runtimeLocked ? preferredRuntimeRef.current : runtime,
151
171
  ...budget.cost !== void 0 || budget.maxTokens !== void 0 ? { budget } : {},
152
172
  permissionMode,
153
173
  toolPrefs: explicitToolPrefs
154
174
  });
155
- }, [budget, permissionMode, runtime, explicitToolPrefs]);
175
+ }, [budget, permissionMode, runtime, runtimeLocked, explicitToolPrefs]);
156
176
  const toolPrefs = react.useMemo(
157
177
  () => ChatWindow_toolCatalog.effectiveToolPreferences({
158
178
  tools: resolvedTools,
@@ -233,6 +253,43 @@ function ChatWindow({
233
253
  },
234
254
  [chat]
235
255
  );
256
+ const handleSessionHydrated = react.useCallback(
257
+ (session) => {
258
+ var _a, _b, _c;
259
+ if (session.id !== panel.threadId) return;
260
+ setRuntimeBound(
261
+ Boolean(((_a = session.runtime) == null ? void 0 : _a.model) && session.runtime.backend)
262
+ );
263
+ if (((_b = session.runtime) == null ? void 0 : _b.model) && session.runtime.backend) {
264
+ replaceRuntimeIdentity(session.runtime);
265
+ }
266
+ (_c = chat == null ? void 0 : chat.onSessionHydrated) == null ? void 0 : _c.call(chat, session);
267
+ },
268
+ [chat, panel.threadId, replaceRuntimeIdentity]
269
+ );
270
+ const handleMessageCountChange = react.useCallback(
271
+ (count) => {
272
+ var _a;
273
+ setMessageCount(count);
274
+ (_a = chat == null ? void 0 : chat.onMessageCountChange) == null ? void 0 : _a.call(chat, count);
275
+ },
276
+ [chat]
277
+ );
278
+ const handleFork = react.useCallback(async () => {
279
+ if (!sessionsApi || !panel.threadId || messageCount === 0 || forking)
280
+ return;
281
+ const sourceThreadId = panel.threadId;
282
+ setForking(true);
283
+ try {
284
+ const fork = await approval.forkChatSession(sessionsApi, sourceThreadId);
285
+ if (threadIdRef.current !== sourceThreadId) return;
286
+ openPanel({ threadId: fork.id });
287
+ } catch (error) {
288
+ console.warn("clicky-ui: failed to fork chat session", error);
289
+ } finally {
290
+ setForking(false);
291
+ }
292
+ }, [forking, messageCount, openPanel, panel.threadId, sessionsApi]);
236
293
  const header = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chat-drag-handle flex cursor-move items-center gap-1 border-b border-border bg-muted/40 px-2 py-1.5", children: [
237
294
  threadsSource != null || sessionsApi !== null ? /* @__PURE__ */ jsxRuntime.jsx(
238
295
  ThreadPicker.ThreadPicker,
@@ -264,6 +321,7 @@ function ChatWindow({
264
321
  budget,
265
322
  onBudgetChange: setBudget,
266
323
  usage,
324
+ runtimeLocked,
267
325
  ...sessionsApi ? { costsApi: sessionsApi } : {},
268
326
  ...panel.threadId ? { threadId: panel.threadId } : {},
269
327
  toolsLoading,
@@ -273,6 +331,17 @@ function ChatWindow({
273
331
  onCatalogRetry: retryCatalogs
274
332
  }
275
333
  ),
334
+ sessionsApi && /* @__PURE__ */ jsxRuntime.jsx(
335
+ button.Button,
336
+ {
337
+ variant: "ghost",
338
+ size: "icon",
339
+ title: messageCount === 0 ? "Send a message before forking this conversation" : "Fork conversation into a new window",
340
+ disabled: !panel.threadId || messageCount === 0 || forking,
341
+ onClick: () => void handleFork(),
342
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiGitBranch.UiGitBranch, className: "size-4" })
343
+ }
344
+ ),
276
345
  /* @__PURE__ */ jsxRuntime.jsx(
277
346
  button.Button,
278
347
  {
@@ -335,6 +404,9 @@ function ChatWindow({
335
404
  onReasoningEffortChange: handleReasoningEffortChange,
336
405
  budget,
337
406
  onUsage: handleUsage,
407
+ runtimeLocked,
408
+ onMessageCountChange: handleMessageCountChange,
409
+ onSessionHydrated: handleSessionHydrated,
338
410
  ...panel.threadId ? { threadId: panel.threadId } : {},
339
411
  sessionsApi,
340
412
  tools: resolvedTools,
@@ -342,7 +414,8 @@ function ChatWindow({
342
414
  body: mergedBody,
343
415
  initialPrompt,
344
416
  onInitialPromptSent: handleInitialPromptSent
345
- }
417
+ },
418
+ panel.threadId ?? `new-${panel.id}`
346
419
  ) })
347
420
  ] });
348
421
  const outerClass = utils.cn(
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWindow.cjs","sources":["../../../src/data/ai/ChatWindow.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useState,\n type ComponentType,\n} from \"react\";\nimport type { Props as RndProps } from \"react-rnd\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../../components/button\";\nimport { Icon } from \"../Icon\";\nimport { UiAdd, UiClose, UiFullscreen } from \"../../icons\";\nimport { Chat } from \"../chat/Chat\";\nimport type {\n ChatBudgetConfig,\n ChatUsageSummary,\n ClaudePermissionMode,\n} from \"../chat/types\";\nimport { useChatWindowManager } from \"./chat-window-context\";\nimport { ThreadPicker } from \"./ThreadPicker\";\nimport { ContextBadges } from \"./ContextBadges\";\nimport {\n ToolPreferences,\n type ToolMeta,\n type ToolMode,\n} from \"./ToolPreferences\";\nimport type { ChatContextItem } from \"./context\";\nimport { chatWindowRequestBody } from \"./ChatWindowRequestBody\";\nimport {\n loadChatPreferences,\n saveChatPreferences,\n type StoredChatPreferences,\n} from \"./ChatWindow.preferences\";\nimport { useChatWindowRuntime } from \"./ChatWindow.runtime\";\nimport { useChatWindowCatalogs } from \"./ChatWindow.catalogs\";\nimport {\n effectiveToolPreferences,\n normalizeToolCatalog,\n} from \"./ChatWindow.tool-catalog\";\nimport { useChatThreadSetup } from \"./ChatWindow.thread\";\nimport { ChatThreadSetupStatus } from \"./ChatWindow.thread-status\";\nimport type { ChatWindowProps } from \"./ChatWindow.types\";\nexport type {\n ChatContextPickerRenderProps,\n ChatWindowProps,\n} from \"./ChatWindow.types\";\n\nconst EMPTY_TOOLS: ToolMeta[] = [];\n\nconst MAXIMIZE_CSS = `\n.chat-maximized .react-draggable {\n transform: none !important;\n width: auto !important;\n height: auto !important;\n inset: 0 !important;\n position: absolute !important;\n}`;\n\n/** A draggable, resizable floating chat window. It lazy-loads `react-rnd` (an\n * optional dependency, so consumers of just the inner <Chat> never pull it)\n * and renders the existing <Chat> beneath a drag-handle header with thread\n * switching, a context-badge row and optional tool preferences. */\nexport function ChatWindow({\n panel,\n chat,\n title = \"Assistant\",\n sessionsApi = \"/api/chat/sessions\",\n threadsSource,\n contextTypeConfig,\n tools,\n defaultToolMode = \"ask\",\n toolsApi = \"/api/chat/tools\",\n runtimesApi = null,\n toolRenderers,\n headerExtras,\n renderContextPicker,\n}: ChatWindowProps) {\n const { updatePanel, closePanel, bringToFront, maximizePanel, openPanel } =\n useChatWindowManager();\n const threadSetup = useChatThreadSetup({\n threadId: panel.threadId,\n api: sessionsApi,\n source: threadsSource,\n onCreated: (threadId) => updatePanel(panel.id, { threadId }),\n });\n const [Rnd, setRnd] = useState<ComponentType<RndProps> | null>(null);\n const [storedPrefs] = useState<StoredChatPreferences>(() =>\n loadChatPreferences(),\n );\n const [budget, setBudget] = useState<ChatBudgetConfig>(\n chat?.budget ?? storedPrefs.budget ?? {},\n );\n const [permissionMode, setPermissionMode] = useState<ClaudePermissionMode>(\n chat?.permissionMode ?? storedPrefs.permissionMode ?? \"default\",\n );\n const [usage, setUsage] = useState<ChatUsageSummary | null>(null);\n const [titleRefresh, setTitleRefresh] = useState(0);\n // Only the modes the user picked in the popover are stored. Everything else\n // is derived, so a surface's declared defaults still reach tools the user has\n // never touched (see effectiveToolPreferences).\n const [explicitToolPrefs, setExplicitToolPrefs] = useState<\n Record<string, ToolMode>\n >(storedPrefs.toolPrefs ?? {});\n const [fetchedTools, setFetchedTools] = useState<ToolMeta[] | undefined>(\n undefined,\n );\n const [toolsLoading, setToolsLoading] = useState(false);\n const [toolsError, setToolsError] = useState<string | null>(null);\n const resolvedTools = tools ?? fetchedTools ?? EMPTY_TOOLS;\n const modelsApi =\n chat?.modelsApi === undefined ? \"/api/chat/models\" : chat.modelsApi;\n const {\n models: resolvedModels,\n runtimeFamilies,\n loading: catalogLoading,\n error: catalogError,\n retry: retryCatalogs,\n } = useChatWindowCatalogs({\n models: chat?.models,\n modelsApi,\n runtimesApi,\n });\n const {\n runtime,\n temperature,\n reasoningEfforts,\n handleRuntimeChange,\n handleModelChange,\n handleReasoningEffortChange,\n handleTemperatureChange,\n } = useChatWindowRuntime({\n chat,\n initialModel: panel.initialModel,\n models: resolvedModels,\n storedRuntime: storedPrefs.runtime,\n });\n\n useEffect(() => {\n if (chat?.budget !== undefined) setBudget(chat.budget);\n }, [chat?.budget]);\n\n useEffect(() => {\n if (chat?.permissionMode !== undefined)\n setPermissionMode(chat.permissionMode);\n }, [chat?.permissionMode]);\n\n useEffect(() => {\n if (tools || toolsApi === null) return;\n let active = true;\n setToolsLoading(true);\n setToolsError(null);\n fetch(toolsApi)\n .then((r) =>\n r.ok ? r.json() : Promise.reject(new Error(`tools ${r.status}`)),\n )\n .then((data) => {\n if (!active) return;\n setFetchedTools(normalizeToolCatalog(data));\n })\n .catch((err) => {\n if (!active) return;\n setToolsError(err instanceof Error ? err.message : String(err));\n })\n .finally(() => {\n if (active) setToolsLoading(false);\n });\n return () => {\n active = false;\n };\n }, [tools, toolsApi]);\n\n useEffect(() => {\n saveChatPreferences({\n runtime,\n ...(budget.cost !== undefined || budget.maxTokens !== undefined\n ? { budget }\n : {}),\n permissionMode,\n toolPrefs: explicitToolPrefs,\n });\n }, [budget, permissionMode, runtime, explicitToolPrefs]);\n\n const toolPrefs = useMemo(\n () =>\n effectiveToolPreferences({\n tools: resolvedTools,\n explicit: explicitToolPrefs,\n surfaceDefaults: panel.toolDefaults,\n fallback: defaultToolMode,\n }),\n [defaultToolMode, explicitToolPrefs, panel.toolDefaults, resolvedTools],\n );\n\n // The popover hands back the whole map, so the keys that differ from the\n // currently effective modes are exactly what the user just changed.\n const handleToolPrefsChange = useCallback(\n (next: Record<string, ToolMode>) => {\n setExplicitToolPrefs((prev) => {\n const updated = { ...prev };\n for (const [name, mode] of Object.entries(next)) {\n if (toolPrefs[name] !== mode) updated[name] = mode;\n }\n return updated;\n });\n },\n [toolPrefs],\n );\n\n useEffect(() => {\n let active = true;\n import(\"react-rnd\").then((m) => {\n if (active) setRnd(() => m.Rnd as unknown as ComponentType<RndProps>);\n });\n return () => {\n active = false;\n };\n }, []);\n\n const removeContext = useCallback(\n (id: string) =>\n updatePanel(panel.id, {\n contextItems: panel.contextItems.filter((c) => c.id !== id),\n }),\n [updatePanel, panel.id, panel.contextItems],\n );\n\n const addContextItems = useCallback(\n (items: ChatContextItem[]) =>\n updatePanel(panel.id, {\n contextItems: [\n ...panel.contextItems,\n ...items.filter(\n (item, index) =>\n !panel.contextItems.some((existing) => existing.id === item.id) &&\n items.findIndex((candidate) => candidate.id === item.id) ===\n index,\n ),\n ],\n }),\n [panel.contextItems, panel.id, updatePanel],\n );\n const addContext = useCallback(\n (item: ChatContextItem) => addContextItems([item]),\n [addContextItems],\n );\n\n const mergedBody = chatWindowRequestBody({\n base: chat?.body,\n contextItems: panel.contextItems,\n tools: resolvedTools,\n toolPrefs,\n });\n\n const initialPrompt = panel.initialPrompt ?? chat?.initialPrompt ?? null;\n const handleInitialPromptSent = useCallback(() => {\n if (panel.initialPrompt) updatePanel(panel.id, { initialPrompt: null });\n chat?.onInitialPromptSent?.();\n }, [chat, panel.id, panel.initialPrompt, updatePanel]);\n const handleUsage = useCallback(\n (snapshot: ChatUsageSummary) => {\n setUsage(snapshot);\n // A settled turn is also when the backend has named the conversation, so\n // this is what refreshes the picker's label.\n setTitleRefresh((value) => value + 1);\n chat?.onUsage?.(snapshot);\n },\n [chat],\n );\n const handlePermissionModeChange = useCallback(\n (next: ClaudePermissionMode) => {\n setPermissionMode(next);\n chat?.onPermissionModeChange?.(next);\n },\n [chat],\n );\n\n const header = (\n <div className=\"chat-drag-handle flex cursor-move items-center gap-1 border-b border-border bg-muted/40 px-2 py-1.5\">\n {threadsSource != null || sessionsApi !== null ? (\n <ThreadPicker\n threadId={panel.threadId}\n onSelect={(tid) => updatePanel(panel.id, { threadId: tid })}\n onNew={() => updatePanel(panel.id, { threadId: null })}\n refreshToken={titleRefresh}\n {...(threadsSource\n ? { source: threadsSource }\n : sessionsApi !== null\n ? { api: sessionsApi }\n : {})}\n />\n ) : (\n <span className=\"px-1 text-sm font-medium\">{title}</span>\n )}\n <div className=\"flex-1\" />\n {headerExtras}\n <ToolPreferences\n tools={resolvedTools}\n value={toolPrefs}\n onChange={handleToolPrefsChange}\n models={resolvedModels}\n runtime={runtime}\n onRuntimeChange={handleRuntimeChange}\n runtimeFamilies={runtimeFamilies}\n reasoningEfforts={reasoningEfforts}\n permissionMode={permissionMode}\n onPermissionModeChange={handlePermissionModeChange}\n temperature={temperature}\n onTemperatureChange={handleTemperatureChange}\n budget={budget}\n onBudgetChange={setBudget}\n usage={usage}\n {...(sessionsApi ? { costsApi: sessionsApi } : {})}\n {...(panel.threadId ? { threadId: panel.threadId } : {})}\n toolsLoading={toolsLoading}\n toolsError={toolsError}\n catalogLoading={catalogLoading}\n catalogError={catalogError}\n onCatalogRetry={retryCatalogs}\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"New window\"\n onClick={() => openPanel()}\n >\n <Icon icon={UiAdd} className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title={panel.maximized ? \"Restore\" : \"Maximize\"}\n onClick={() => maximizePanel(panel.id)}\n >\n <Icon icon={UiFullscreen} className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"Close\"\n onClick={() => closePanel(panel.id)}\n >\n <Icon icon={UiClose} className=\"size-4\" />\n </Button>\n </div>\n );\n\n const frame = (\n <div className=\"flex h-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\">\n {header}\n {(renderContextPicker || panel.contextItems.length > 0) && (\n <div className=\"flex flex-wrap items-center gap-1.5 border-b border-border px-2 py-1.5\">\n {renderContextPicker?.({\n items: panel.contextItems,\n onAdd: addContext,\n onAddMany: addContextItems,\n })}\n <ContextBadges\n items={panel.contextItems}\n onRemove={removeContext}\n className=\"px-0 py-0\"\n {...(contextTypeConfig ? { typeConfig: contextTypeConfig } : {})}\n />\n </div>\n )}\n <div className=\"min-h-0 flex-1\">\n {threadSetup.blocked ? (\n <ChatThreadSetupStatus setup={threadSetup} />\n ) : (\n <Chat\n {...chat}\n {...(resolvedModels.length\n ? { models: resolvedModels, modelsApi: null }\n : {})}\n runtime={runtime}\n {...(runtimeFamilies ? { runtimeFamilies } : {})}\n permissionMode={permissionMode}\n onRuntimeChange={handleRuntimeChange}\n onModelChange={handleModelChange}\n onReasoningEffortChange={handleReasoningEffortChange}\n budget={budget}\n onUsage={handleUsage}\n {...(panel.threadId ? { threadId: panel.threadId } : {})}\n sessionsApi={sessionsApi}\n tools={resolvedTools}\n {...(toolRenderers ? { toolRenderers } : {})}\n body={mergedBody}\n initialPrompt={initialPrompt}\n onInitialPromptSent={handleInitialPromptSent}\n />\n )}\n </div>\n </div>\n );\n\n const outerClass = cn(\n \"fixed pointer-events-none\",\n panel.maximized ? \"inset-4 chat-maximized\" : \"inset-0\",\n );\n\n // Until react-rnd loads (and as a graceful fallback if it never does) the\n // window is statically positioned — still usable, just not draggable.\n if (!Rnd) {\n return (\n <div className={outerClass} style={{ zIndex: panel.zIndex }}>\n <div\n className=\"pointer-events-auto h-full\"\n style={\n panel.maximized\n ? { position: \"relative\", width: \"100%\", height: \"100%\" }\n : {\n position: \"absolute\",\n left: panel.x,\n top: panel.y,\n width: panel.width,\n height: panel.height,\n }\n }\n >\n {frame}\n </div>\n </div>\n );\n }\n\n return (\n <div className={outerClass} style={{ zIndex: panel.zIndex }}>\n <style>{MAXIMIZE_CSS}</style>\n <Rnd\n default={{\n x: panel.x,\n y: panel.y,\n width: panel.width,\n height: panel.height,\n }}\n style={{ pointerEvents: \"auto\" }}\n minWidth={360}\n minHeight={400}\n bounds=\"parent\"\n dragHandleClassName=\"chat-drag-handle\"\n disableDragging={panel.maximized}\n enableResizing={!panel.maximized}\n onDragStart={() => bringToFront(panel.id)}\n onDragStop={(_e, d) => updatePanel(panel.id, { x: d.x, y: d.y })}\n onResizeStop={(_e, _dir, ref, _delta, pos) =>\n updatePanel(panel.id, {\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n x: pos.x,\n y: pos.y,\n })\n }\n >\n {frame}\n </Rnd>\n </div>\n );\n}\n\n/** Renders every open window for the current {@link useChatWindowManager}.\n * Drop one of these near the root alongside a <ChatFab/>. */\nexport function ChatWindowLayer(props: Omit<ChatWindowProps, \"panel\">) {\n const { panels } = useChatWindowManager();\n return (\n <>\n {panels.map((panel) => (\n <ChatWindow key={panel.id} panel={panel} {...props} />\n ))}\n </>\n );\n}\n"],"names":["useChatWindowManager","useChatThreadSetup","useState","loadChatPreferences","useChatWindowCatalogs","useChatWindowRuntime","useEffect","normalizeToolCatalog","saveChatPreferences","useMemo","effectiveToolPreferences","useCallback","chatWindowRequestBody","jsxs","jsx","ThreadPicker","ToolPreferences","Button","Icon","UiAdd","UiFullscreen","UiClose","ContextBadges","ChatThreadSetupStatus","Chat","cn","Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"ChatWindow.cjs","sources":["../../../src/data/ai/ChatWindow.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n} from \"react\";\nimport type { Props as RndProps } from \"react-rnd\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../../components/button\";\nimport { Icon } from \"../Icon\";\nimport { UiAdd, UiClose, UiFullscreen, UiGitBranch } from \"../../icons\";\nimport { Chat } from \"../chat/Chat\";\nimport { forkChatSession, type CaptainChatSession } from \"../chat/approval\";\nimport type {\n ChatBudgetConfig,\n ChatUsageSummary,\n ClaudePermissionMode,\n} from \"../chat/types\";\nimport { useChatWindowManager } from \"./chat-window-context\";\nimport { ThreadPicker } from \"./ThreadPicker\";\nimport { ContextBadges } from \"./ContextBadges\";\nimport {\n ToolPreferences,\n type ToolMeta,\n type ToolMode,\n} from \"./ToolPreferences\";\nimport type { ChatContextItem } from \"./context\";\nimport { chatWindowRequestBody } from \"./ChatWindowRequestBody\";\nimport {\n loadChatPreferences,\n saveChatPreferences,\n type StoredChatPreferences,\n} from \"./ChatWindow.preferences\";\nimport { useChatWindowRuntime } from \"./ChatWindow.runtime\";\nimport { useChatWindowCatalogs } from \"./ChatWindow.catalogs\";\nimport {\n effectiveToolPreferences,\n normalizeToolCatalog,\n} from \"./ChatWindow.tool-catalog\";\nimport { useChatThreadSetup } from \"./ChatWindow.thread\";\nimport { ChatThreadSetupStatus } from \"./ChatWindow.thread-status\";\nimport type { ChatWindowProps } from \"./ChatWindow.types\";\nexport type {\n ChatContextPickerRenderProps,\n ChatWindowProps,\n} from \"./ChatWindow.types\";\n\nconst EMPTY_TOOLS: ToolMeta[] = [];\n\nconst MAXIMIZE_CSS = `\n.chat-maximized .react-draggable {\n transform: none !important;\n width: auto !important;\n height: auto !important;\n inset: 0 !important;\n position: absolute !important;\n}`;\n\n/** A draggable, resizable floating chat window. It lazy-loads `react-rnd` (an\n * optional dependency, so consumers of just the inner <Chat> never pull it)\n * and renders the existing <Chat> beneath a drag-handle header with thread\n * switching, a context-badge row and optional tool preferences. */\nexport function ChatWindow({\n panel,\n chat,\n title = \"Assistant\",\n sessionsApi = \"/api/chat/sessions\",\n threadsSource,\n contextTypeConfig,\n tools,\n defaultToolMode = \"ask\",\n toolsApi = \"/api/chat/tools\",\n runtimesApi = null,\n toolRenderers,\n headerExtras,\n renderContextPicker,\n}: ChatWindowProps) {\n const { updatePanel, closePanel, bringToFront, maximizePanel, openPanel } =\n useChatWindowManager();\n const threadSetup = useChatThreadSetup({\n threadId: panel.threadId,\n api: sessionsApi,\n source: threadsSource,\n onCreated: (threadId) => updatePanel(panel.id, { threadId }),\n });\n const [Rnd, setRnd] = useState<ComponentType<RndProps> | null>(null);\n const [storedPrefs] = useState<StoredChatPreferences>(() =>\n loadChatPreferences(),\n );\n const [budget, setBudget] = useState<ChatBudgetConfig>(\n chat?.budget ?? storedPrefs.budget ?? {},\n );\n const [permissionMode, setPermissionMode] = useState<ClaudePermissionMode>(\n chat?.permissionMode ?? storedPrefs.permissionMode ?? \"default\",\n );\n const [usage, setUsage] = useState<ChatUsageSummary | null>(null);\n const [titleRefresh, setTitleRefresh] = useState(0);\n // Only the modes the user picked in the popover are stored. Everything else\n // is derived, so a surface's declared defaults still reach tools the user has\n // never touched (see effectiveToolPreferences).\n const [explicitToolPrefs, setExplicitToolPrefs] = useState<\n Record<string, ToolMode>\n >(storedPrefs.toolPrefs ?? {});\n const [fetchedTools, setFetchedTools] = useState<ToolMeta[] | undefined>(\n undefined,\n );\n const [toolsLoading, setToolsLoading] = useState(false);\n const [toolsError, setToolsError] = useState<string | null>(null);\n const resolvedTools = tools ?? fetchedTools ?? EMPTY_TOOLS;\n const modelsApi =\n chat?.modelsApi === undefined ? \"/api/chat/models\" : chat.modelsApi;\n const {\n models: resolvedModels,\n runtimeFamilies,\n loading: catalogLoading,\n error: catalogError,\n retry: retryCatalogs,\n } = useChatWindowCatalogs({\n models: chat?.models,\n modelsApi,\n runtimesApi,\n });\n const {\n runtime,\n temperature,\n reasoningEfforts,\n handleRuntimeChange,\n handleModelChange,\n handleReasoningEffortChange,\n handleTemperatureChange,\n replaceRuntimeIdentity,\n replaceRuntime,\n } = useChatWindowRuntime({\n chat,\n initialModel: panel.initialModel,\n models: resolvedModels,\n storedRuntime: storedPrefs.runtime,\n });\n const [messageCount, setMessageCount] = useState(0);\n const [runtimeBound, setRuntimeBound] = useState(false);\n const [forking, setForking] = useState(false);\n const runtimeLocked = runtimeBound || messageCount > 0;\n const preferredRuntimeRef = useRef(runtime);\n const threadIdRef = useRef(panel.threadId);\n threadIdRef.current = panel.threadId;\n\n useEffect(() => {\n if (!runtimeLocked) preferredRuntimeRef.current = runtime;\n }, [runtime, runtimeLocked]);\n\n useEffect(() => {\n setMessageCount(0);\n setRuntimeBound(false);\n setUsage(null);\n replaceRuntime(preferredRuntimeRef.current);\n }, [panel.threadId, replaceRuntime]);\n\n useEffect(() => {\n if (chat?.budget !== undefined) setBudget(chat.budget);\n }, [chat?.budget]);\n\n useEffect(() => {\n if (chat?.permissionMode !== undefined)\n setPermissionMode(chat.permissionMode);\n }, [chat?.permissionMode]);\n\n useEffect(() => {\n if (tools || toolsApi === null) return;\n let active = true;\n setToolsLoading(true);\n setToolsError(null);\n fetch(toolsApi)\n .then((r) =>\n r.ok ? r.json() : Promise.reject(new Error(`tools ${r.status}`)),\n )\n .then((data) => {\n if (!active) return;\n setFetchedTools(normalizeToolCatalog(data));\n })\n .catch((err) => {\n if (!active) return;\n setToolsError(err instanceof Error ? err.message : String(err));\n })\n .finally(() => {\n if (active) setToolsLoading(false);\n });\n return () => {\n active = false;\n };\n }, [tools, toolsApi]);\n\n useEffect(() => {\n saveChatPreferences({\n runtime: runtimeLocked ? preferredRuntimeRef.current : runtime,\n ...(budget.cost !== undefined || budget.maxTokens !== undefined\n ? { budget }\n : {}),\n permissionMode,\n toolPrefs: explicitToolPrefs,\n });\n }, [budget, permissionMode, runtime, runtimeLocked, explicitToolPrefs]);\n\n const toolPrefs = useMemo(\n () =>\n effectiveToolPreferences({\n tools: resolvedTools,\n explicit: explicitToolPrefs,\n surfaceDefaults: panel.toolDefaults,\n fallback: defaultToolMode,\n }),\n [defaultToolMode, explicitToolPrefs, panel.toolDefaults, resolvedTools],\n );\n\n // The popover hands back the whole map, so the keys that differ from the\n // currently effective modes are exactly what the user just changed.\n const handleToolPrefsChange = useCallback(\n (next: Record<string, ToolMode>) => {\n setExplicitToolPrefs((prev) => {\n const updated = { ...prev };\n for (const [name, mode] of Object.entries(next)) {\n if (toolPrefs[name] !== mode) updated[name] = mode;\n }\n return updated;\n });\n },\n [toolPrefs],\n );\n\n useEffect(() => {\n let active = true;\n import(\"react-rnd\").then((m) => {\n if (active) setRnd(() => m.Rnd as unknown as ComponentType<RndProps>);\n });\n return () => {\n active = false;\n };\n }, []);\n\n const removeContext = useCallback(\n (id: string) =>\n updatePanel(panel.id, {\n contextItems: panel.contextItems.filter((c) => c.id !== id),\n }),\n [updatePanel, panel.id, panel.contextItems],\n );\n\n const addContextItems = useCallback(\n (items: ChatContextItem[]) =>\n updatePanel(panel.id, {\n contextItems: [\n ...panel.contextItems,\n ...items.filter(\n (item, index) =>\n !panel.contextItems.some((existing) => existing.id === item.id) &&\n items.findIndex((candidate) => candidate.id === item.id) ===\n index,\n ),\n ],\n }),\n [panel.contextItems, panel.id, updatePanel],\n );\n const addContext = useCallback(\n (item: ChatContextItem) => addContextItems([item]),\n [addContextItems],\n );\n\n const mergedBody = chatWindowRequestBody({\n base: chat?.body,\n contextItems: panel.contextItems,\n tools: resolvedTools,\n toolPrefs,\n });\n\n const initialPrompt = panel.initialPrompt ?? chat?.initialPrompt ?? null;\n const handleInitialPromptSent = useCallback(() => {\n if (panel.initialPrompt) updatePanel(panel.id, { initialPrompt: null });\n chat?.onInitialPromptSent?.();\n }, [chat, panel.id, panel.initialPrompt, updatePanel]);\n const handleUsage = useCallback(\n (snapshot: ChatUsageSummary) => {\n setUsage(snapshot);\n // A settled turn is also when the backend has named the conversation, so\n // this is what refreshes the picker's label.\n setTitleRefresh((value) => value + 1);\n chat?.onUsage?.(snapshot);\n },\n [chat],\n );\n const handlePermissionModeChange = useCallback(\n (next: ClaudePermissionMode) => {\n setPermissionMode(next);\n chat?.onPermissionModeChange?.(next);\n },\n [chat],\n );\n const handleSessionHydrated = useCallback(\n (session: CaptainChatSession) => {\n if (session.id !== panel.threadId) return;\n setRuntimeBound(\n Boolean(session.runtime?.model && session.runtime.backend),\n );\n if (session.runtime?.model && session.runtime.backend) {\n replaceRuntimeIdentity(session.runtime);\n }\n chat?.onSessionHydrated?.(session);\n },\n [chat, panel.threadId, replaceRuntimeIdentity],\n );\n const handleMessageCountChange = useCallback(\n (count: number) => {\n setMessageCount(count);\n chat?.onMessageCountChange?.(count);\n },\n [chat],\n );\n const handleFork = useCallback(async () => {\n if (!sessionsApi || !panel.threadId || messageCount === 0 || forking)\n return;\n const sourceThreadId = panel.threadId;\n setForking(true);\n try {\n const fork = await forkChatSession(sessionsApi, sourceThreadId);\n if (threadIdRef.current !== sourceThreadId) return;\n openPanel({ threadId: fork.id });\n } catch (error) {\n console.warn(\"clicky-ui: failed to fork chat session\", error);\n } finally {\n setForking(false);\n }\n }, [forking, messageCount, openPanel, panel.threadId, sessionsApi]);\n\n const header = (\n <div className=\"chat-drag-handle flex cursor-move items-center gap-1 border-b border-border bg-muted/40 px-2 py-1.5\">\n {threadsSource != null || sessionsApi !== null ? (\n <ThreadPicker\n threadId={panel.threadId}\n onSelect={(tid) => updatePanel(panel.id, { threadId: tid })}\n onNew={() => updatePanel(panel.id, { threadId: null })}\n refreshToken={titleRefresh}\n {...(threadsSource\n ? { source: threadsSource }\n : sessionsApi !== null\n ? { api: sessionsApi }\n : {})}\n />\n ) : (\n <span className=\"px-1 text-sm font-medium\">{title}</span>\n )}\n <div className=\"flex-1\" />\n {headerExtras}\n <ToolPreferences\n tools={resolvedTools}\n value={toolPrefs}\n onChange={handleToolPrefsChange}\n models={resolvedModels}\n runtime={runtime}\n onRuntimeChange={handleRuntimeChange}\n runtimeFamilies={runtimeFamilies}\n reasoningEfforts={reasoningEfforts}\n permissionMode={permissionMode}\n onPermissionModeChange={handlePermissionModeChange}\n temperature={temperature}\n onTemperatureChange={handleTemperatureChange}\n budget={budget}\n onBudgetChange={setBudget}\n usage={usage}\n runtimeLocked={runtimeLocked}\n {...(sessionsApi ? { costsApi: sessionsApi } : {})}\n {...(panel.threadId ? { threadId: panel.threadId } : {})}\n toolsLoading={toolsLoading}\n toolsError={toolsError}\n catalogLoading={catalogLoading}\n catalogError={catalogError}\n onCatalogRetry={retryCatalogs}\n />\n {sessionsApi && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title={\n messageCount === 0\n ? \"Send a message before forking this conversation\"\n : \"Fork conversation into a new window\"\n }\n disabled={!panel.threadId || messageCount === 0 || forking}\n onClick={() => void handleFork()}\n >\n <Icon icon={UiGitBranch} className=\"size-4\" />\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"New window\"\n onClick={() => openPanel()}\n >\n <Icon icon={UiAdd} className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title={panel.maximized ? \"Restore\" : \"Maximize\"}\n onClick={() => maximizePanel(panel.id)}\n >\n <Icon icon={UiFullscreen} className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"Close\"\n onClick={() => closePanel(panel.id)}\n >\n <Icon icon={UiClose} className=\"size-4\" />\n </Button>\n </div>\n );\n\n const frame = (\n <div className=\"flex h-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\">\n {header}\n {(renderContextPicker || panel.contextItems.length > 0) && (\n <div className=\"flex flex-wrap items-center gap-1.5 border-b border-border px-2 py-1.5\">\n {renderContextPicker?.({\n items: panel.contextItems,\n onAdd: addContext,\n onAddMany: addContextItems,\n })}\n <ContextBadges\n items={panel.contextItems}\n onRemove={removeContext}\n className=\"px-0 py-0\"\n {...(contextTypeConfig ? { typeConfig: contextTypeConfig } : {})}\n />\n </div>\n )}\n <div className=\"min-h-0 flex-1\">\n {threadSetup.blocked ? (\n <ChatThreadSetupStatus setup={threadSetup} />\n ) : (\n <Chat\n key={panel.threadId ?? `new-${panel.id}`}\n {...chat}\n {...(resolvedModels.length\n ? { models: resolvedModels, modelsApi: null }\n : {})}\n runtime={runtime}\n {...(runtimeFamilies ? { runtimeFamilies } : {})}\n permissionMode={permissionMode}\n onRuntimeChange={handleRuntimeChange}\n onModelChange={handleModelChange}\n onReasoningEffortChange={handleReasoningEffortChange}\n budget={budget}\n onUsage={handleUsage}\n runtimeLocked={runtimeLocked}\n onMessageCountChange={handleMessageCountChange}\n onSessionHydrated={handleSessionHydrated}\n {...(panel.threadId ? { threadId: panel.threadId } : {})}\n sessionsApi={sessionsApi}\n tools={resolvedTools}\n {...(toolRenderers ? { toolRenderers } : {})}\n body={mergedBody}\n initialPrompt={initialPrompt}\n onInitialPromptSent={handleInitialPromptSent}\n />\n )}\n </div>\n </div>\n );\n\n const outerClass = cn(\n \"fixed pointer-events-none\",\n panel.maximized ? \"inset-4 chat-maximized\" : \"inset-0\",\n );\n\n // Until react-rnd loads (and as a graceful fallback if it never does) the\n // window is statically positioned — still usable, just not draggable.\n if (!Rnd) {\n return (\n <div className={outerClass} style={{ zIndex: panel.zIndex }}>\n <div\n className=\"pointer-events-auto h-full\"\n style={\n panel.maximized\n ? { position: \"relative\", width: \"100%\", height: \"100%\" }\n : {\n position: \"absolute\",\n left: panel.x,\n top: panel.y,\n width: panel.width,\n height: panel.height,\n }\n }\n >\n {frame}\n </div>\n </div>\n );\n }\n\n return (\n <div className={outerClass} style={{ zIndex: panel.zIndex }}>\n <style>{MAXIMIZE_CSS}</style>\n <Rnd\n default={{\n x: panel.x,\n y: panel.y,\n width: panel.width,\n height: panel.height,\n }}\n style={{ pointerEvents: \"auto\" }}\n minWidth={360}\n minHeight={400}\n bounds=\"parent\"\n dragHandleClassName=\"chat-drag-handle\"\n disableDragging={panel.maximized}\n enableResizing={!panel.maximized}\n onDragStart={() => bringToFront(panel.id)}\n onDragStop={(_e, d) => updatePanel(panel.id, { x: d.x, y: d.y })}\n onResizeStop={(_e, _dir, ref, _delta, pos) =>\n updatePanel(panel.id, {\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n x: pos.x,\n y: pos.y,\n })\n }\n >\n {frame}\n </Rnd>\n </div>\n );\n}\n\n/** Renders every open window for the current {@link useChatWindowManager}.\n * Drop one of these near the root alongside a <ChatFab/>. */\nexport function ChatWindowLayer(props: Omit<ChatWindowProps, \"panel\">) {\n const { panels } = useChatWindowManager();\n return (\n <>\n {panels.map((panel) => (\n <ChatWindow key={panel.id} panel={panel} {...props} />\n ))}\n </>\n );\n}\n"],"names":["useChatWindowManager","useChatThreadSetup","useState","loadChatPreferences","useChatWindowCatalogs","useChatWindowRuntime","useRef","useEffect","normalizeToolCatalog","saveChatPreferences","useMemo","effectiveToolPreferences","useCallback","chatWindowRequestBody","forkChatSession","jsxs","jsx","ThreadPicker","ToolPreferences","Button","Icon","UiGitBranch","UiAdd","UiFullscreen","UiClose","ContextBadges","ChatThreadSetupStatus","Chat","cn","Fragment"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAM,cAA0B,CAAA;AAEhC,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAad,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,EAAE,aAAa,YAAY,cAAc,eAAe,UAAA,IAC5DA,uCAAA;AACF,QAAM,cAAcC,kBAAAA,mBAAmB;AAAA,IACrC,UAAU,MAAM;AAAA,IAChB,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW,CAAC,aAAa,YAAY,MAAM,IAAI,EAAE,UAAU;AAAA,EAAA,CAC5D;AACD,QAAM,CAAC,KAAK,MAAM,IAAIC,MAAAA,SAAyC,IAAI;AACnE,QAAM,CAAC,WAAW,IAAIA,MAAAA;AAAAA,IAAgC,MACpDC,uBAAAA,oBAAA;AAAA,EAAoB;AAEtB,QAAM,CAAC,QAAQ,SAAS,IAAID,MAAAA;AAAAA,KAC1B,6BAAM,WAAU,YAAY,UAAU,CAAA;AAAA,EAAC;AAEzC,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,MAAAA;AAAAA,KAC1C,6BAAM,mBAAkB,YAAY,kBAAkB;AAAA,EAAA;AAExD,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAkC,IAAI;AAChE,QAAM,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,CAAC;AAIlD,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,MAAAA,SAEhD,YAAY,aAAa,EAAE;AAC7B,QAAM,CAAC,cAAc,eAAe,IAAIA,MAAAA;AAAAA,IACtC;AAAA,EAAA;AAEF,QAAM,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,KAAK;AACtD,QAAM,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAwB,IAAI;AAChE,QAAM,gBAAgB,SAAS,gBAAgB;AAC/C,QAAM,aACJ,6BAAM,eAAc,SAAY,qBAAqB,KAAK;AAC5D,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EAAA,IACLE,0CAAsB;AAAA,IACxB,QAAQ,6BAAM;AAAA,IACd;AAAA,IACA;AAAA,EAAA,CACD;AACD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACEC,wCAAqB;AAAA,IACvB;AAAA,IACA,cAAc,MAAM;AAAA,IACpB,QAAQ;AAAA,IACR,eAAe,YAAY;AAAA,EAAA,CAC5B;AACD,QAAM,CAAC,cAAc,eAAe,IAAIH,MAAAA,SAAS,CAAC;AAClD,QAAM,CAAC,cAAc,eAAe,IAAIA,MAAAA,SAAS,KAAK;AACtD,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,KAAK;AAC5C,QAAM,gBAAgB,gBAAgB,eAAe;AACrD,QAAM,sBAAsBI,MAAAA,OAAO,OAAO;AAC1C,QAAM,cAAcA,MAAAA,OAAO,MAAM,QAAQ;AACzC,cAAY,UAAU,MAAM;AAE5BC,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,cAAe,qBAAoB,UAAU;AAAA,EACpD,GAAG,CAAC,SAAS,aAAa,CAAC;AAE3BA,QAAAA,UAAU,MAAM;AACd,oBAAgB,CAAC;AACjB,oBAAgB,KAAK;AACrB,aAAS,IAAI;AACb,mBAAe,oBAAoB,OAAO;AAAA,EAC5C,GAAG,CAAC,MAAM,UAAU,cAAc,CAAC;AAEnCA,QAAAA,UAAU,MAAM;AACd,SAAI,6BAAM,YAAW,OAAW,WAAU,KAAK,MAAM;AAAA,EACvD,GAAG,CAAC,6BAAM,MAAM,CAAC;AAEjBA,QAAAA,UAAU,MAAM;AACd,SAAI,6BAAM,oBAAmB;AAC3B,wBAAkB,KAAK,cAAc;AAAA,EACzC,GAAG,CAAC,6BAAM,cAAc,CAAC;AAEzBA,QAAAA,UAAU,MAAM;AACd,QAAI,SAAS,aAAa,KAAM;AAChC,QAAI,SAAS;AACb,oBAAgB,IAAI;AACpB,kBAAc,IAAI;AAClB,UAAM,QAAQ,EACX;AAAA,MAAK,CAAC,MACL,EAAE,KAAK,EAAE,KAAA,IAAS,QAAQ,OAAO,IAAI,MAAM,SAAS,EAAE,MAAM,EAAE,CAAC;AAAA,IAAA,EAEhE,KAAK,CAAC,SAAS;AACd,UAAI,CAAC,OAAQ;AACb,sBAAgBC,uBAAAA,qBAAqB,IAAI,CAAC;AAAA,IAC5C,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,CAAC,OAAQ;AACb,oBAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAChE,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,wBAAwB,KAAK;AAAA,IACnC,CAAC;AACH,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpBD,QAAAA,UAAU,MAAM;AACdE,+CAAoB;AAAA,MAClB,SAAS,gBAAgB,oBAAoB,UAAU;AAAA,MACvD,GAAI,OAAO,SAAS,UAAa,OAAO,cAAc,SAClD,EAAE,OAAA,IACF,CAAA;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,IAAA,CACZ;AAAA,EACH,GAAG,CAAC,QAAQ,gBAAgB,SAAS,eAAe,iBAAiB,CAAC;AAEtE,QAAM,YAAYC,MAAAA;AAAAA,IAChB,MACEC,gDAAyB;AAAA,MACvB,OAAO;AAAA,MACP,UAAU;AAAA,MACV,iBAAiB,MAAM;AAAA,MACvB,UAAU;AAAA,IAAA,CACX;AAAA,IACH,CAAC,iBAAiB,mBAAmB,MAAM,cAAc,aAAa;AAAA,EAAA;AAKxE,QAAM,wBAAwBC,MAAAA;AAAAA,IAC5B,CAAC,SAAmC;AAClC,2BAAqB,CAAC,SAAS;AAC7B,cAAM,UAAU,EAAE,GAAG,KAAA;AACrB,mBAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,cAAI,UAAU,IAAI,MAAM,KAAM,SAAQ,IAAI,IAAI;AAAA,QAChD;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS;AAAA,EAAA;AAGZL,QAAAA,UAAU,MAAM;AACd,QAAI,SAAS;AACb,WAAO,WAAW,EAAE,KAAK,CAAC,MAAM;AAC9B,UAAI,OAAQ,QAAO,MAAM,EAAE,GAAyC;AAAA,IACtE,CAAC;AACD,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,QAAM,gBAAgBK,MAAAA;AAAAA,IACpB,CAAC,OACC,YAAY,MAAM,IAAI;AAAA,MACpB,cAAc,MAAM,aAAa,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,IAAA,CAC3D;AAAA,IACH,CAAC,aAAa,MAAM,IAAI,MAAM,YAAY;AAAA,EAAA;AAG5C,QAAM,kBAAkBA,MAAAA;AAAAA,IACtB,CAAC,UACC,YAAY,MAAM,IAAI;AAAA,MACpB,cAAc;AAAA,QACZ,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,UACP,CAAC,MAAM,UACL,CAAC,MAAM,aAAa,KAAK,CAAC,aAAa,SAAS,OAAO,KAAK,EAAE,KAC9D,MAAM,UAAU,CAAC,cAAc,UAAU,OAAO,KAAK,EAAE,MACrD;AAAA,QAAA;AAAA,MACN;AAAA,IACF,CACD;AAAA,IACH,CAAC,MAAM,cAAc,MAAM,IAAI,WAAW;AAAA,EAAA;AAE5C,QAAM,aAAaA,MAAAA;AAAAA,IACjB,CAAC,SAA0B,gBAAgB,CAAC,IAAI,CAAC;AAAA,IACjD,CAAC,eAAe;AAAA,EAAA;AAGlB,QAAM,aAAaC,sBAAAA,sBAAsB;AAAA,IACvC,MAAM,6BAAM;AAAA,IACZ,cAAc,MAAM;AAAA,IACpB,OAAO;AAAA,IACP;AAAA,EAAA,CACD;AAED,QAAM,gBAAgB,MAAM,kBAAiB,6BAAM,kBAAiB;AACpE,QAAM,0BAA0BD,MAAAA,YAAY,MAAM;;AAChD,QAAI,MAAM,cAAe,aAAY,MAAM,IAAI,EAAE,eAAe,MAAM;AACtE,uCAAM,wBAAN;AAAA,EACF,GAAG,CAAC,MAAM,MAAM,IAAI,MAAM,eAAe,WAAW,CAAC;AACrD,QAAM,cAAcA,MAAAA;AAAAA,IAClB,CAAC,aAA+B;;AAC9B,eAAS,QAAQ;AAGjB,sBAAgB,CAAC,UAAU,QAAQ,CAAC;AACpC,yCAAM,YAAN,8BAAgB;AAAA,IAClB;AAAA,IACA,CAAC,IAAI;AAAA,EAAA;AAEP,QAAM,6BAA6BA,MAAAA;AAAAA,IACjC,CAAC,SAA+B;;AAC9B,wBAAkB,IAAI;AACtB,yCAAM,2BAAN,8BAA+B;AAAA,IACjC;AAAA,IACA,CAAC,IAAI;AAAA,EAAA;AAEP,QAAM,wBAAwBA,MAAAA;AAAAA,IAC5B,CAAC,YAAgC;;AAC/B,UAAI,QAAQ,OAAO,MAAM,SAAU;AACnC;AAAA,QACE,UAAQ,aAAQ,YAAR,mBAAiB,UAAS,QAAQ,QAAQ,OAAO;AAAA,MAAA;AAE3D,YAAI,aAAQ,YAAR,mBAAiB,UAAS,QAAQ,QAAQ,SAAS;AACrD,+BAAuB,QAAQ,OAAO;AAAA,MACxC;AACA,yCAAM,sBAAN,8BAA0B;AAAA,IAC5B;AAAA,IACA,CAAC,MAAM,MAAM,UAAU,sBAAsB;AAAA,EAAA;AAE/C,QAAM,2BAA2BA,MAAAA;AAAAA,IAC/B,CAAC,UAAkB;;AACjB,sBAAgB,KAAK;AACrB,yCAAM,yBAAN,8BAA6B;AAAA,IAC/B;AAAA,IACA,CAAC,IAAI;AAAA,EAAA;AAEP,QAAM,aAAaA,MAAAA,YAAY,YAAY;AACzC,QAAI,CAAC,eAAe,CAAC,MAAM,YAAY,iBAAiB,KAAK;AAC3D;AACF,UAAM,iBAAiB,MAAM;AAC7B,eAAW,IAAI;AACf,QAAI;AACF,YAAM,OAAO,MAAME,yBAAgB,aAAa,cAAc;AAC9D,UAAI,YAAY,YAAY,eAAgB;AAC5C,gBAAU,EAAE,UAAU,KAAK,GAAA,CAAI;AAAA,IACjC,SAAS,OAAO;AACd,cAAQ,KAAK,0CAA0C,KAAK;AAAA,IAC9D,UAAA;AACE,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,SAAS,cAAc,WAAW,MAAM,UAAU,WAAW,CAAC;AAElE,QAAM,SACJC,2BAAAA,KAAC,OAAA,EAAI,WAAU,uGACZ,UAAA;AAAA,IAAA,iBAAiB,QAAQ,gBAAgB,OACxCC,2BAAAA;AAAAA,MAACC,aAAAA;AAAAA,MAAA;AAAA,QACC,UAAU,MAAM;AAAA,QAChB,UAAU,CAAC,QAAQ,YAAY,MAAM,IAAI,EAAE,UAAU,KAAK;AAAA,QAC1D,OAAO,MAAM,YAAY,MAAM,IAAI,EAAE,UAAU,MAAM;AAAA,QACrD,cAAc;AAAA,QACb,GAAI,gBACD,EAAE,QAAQ,cAAA,IACV,gBAAgB,OACd,EAAE,KAAK,gBACP,CAAA;AAAA,MAAC;AAAA,IAAA,IAGTD,2BAAAA,IAAC,QAAA,EAAK,WAAU,4BAA4B,UAAA,OAAM;AAAA,IAEpDA,2BAAAA,IAAC,OAAA,EAAI,WAAU,SAAA,CAAS;AAAA,IACvB;AAAA,IACDA,2BAAAA;AAAAA,MAACE,gBAAAA;AAAAA,MAAA;AAAA,QACC,OAAO;AAAA,QACP,OAAO;AAAA,QACP,UAAU;AAAA,QACV,QAAQ;AAAA,QACR;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA,wBAAwB;AAAA,QACxB;AAAA,QACA,qBAAqB;AAAA,QACrB;AAAA,QACA,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACC,GAAI,cAAc,EAAE,UAAU,YAAA,IAAgB,CAAA;AAAA,QAC9C,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAA,IAAa,CAAA;AAAA,QACrD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,MAAA;AAAA,IAAA;AAAA,IAEjB,eACCF,2BAAAA;AAAAA,MAACG,OAAAA;AAAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OACE,iBAAiB,IACb,oDACA;AAAA,QAEN,UAAU,CAAC,MAAM,YAAY,iBAAiB,KAAK;AAAA,QACnD,SAAS,MAAM,KAAK,WAAA;AAAA,QAEpB,UAAAH,2BAAAA,IAACI,WAAA,EAAK,MAAMC,YAAAA,aAAa,WAAU,SAAA,CAAS;AAAA,MAAA;AAAA,IAAA;AAAA,IAGhDL,2BAAAA;AAAAA,MAACG,OAAAA;AAAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OAAM;AAAA,QACN,SAAS,MAAM,UAAA;AAAA,QAEf,UAAAH,2BAAAA,IAACI,WAAA,EAAK,MAAME,MAAAA,OAAO,WAAU,SAAA,CAAS;AAAA,MAAA;AAAA,IAAA;AAAA,IAExCN,2BAAAA;AAAAA,MAACG,OAAAA;AAAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OAAO,MAAM,YAAY,YAAY;AAAA,QACrC,SAAS,MAAM,cAAc,MAAM,EAAE;AAAA,QAErC,UAAAH,2BAAAA,IAACI,WAAA,EAAK,MAAMG,aAAAA,cAAc,WAAU,SAAA,CAAS;AAAA,MAAA;AAAA,IAAA;AAAA,IAE/CP,2BAAAA;AAAAA,MAACG,OAAAA;AAAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OAAM;AAAA,QACN,SAAS,MAAM,WAAW,MAAM,EAAE;AAAA,QAElC,UAAAH,2BAAAA,IAACI,WAAA,EAAK,MAAMI,QAAAA,SAAS,WAAU,SAAA,CAAS;AAAA,MAAA;AAAA,IAAA;AAAA,EAC1C,GACF;AAGF,QAAM,QACJT,2BAAAA,KAAC,OAAA,EAAI,WAAU,gGACZ,UAAA;AAAA,IAAA;AAAA,KACC,uBAAuB,MAAM,aAAa,SAAS,MACnDA,2BAAAA,KAAC,OAAA,EAAI,WAAU,0EACZ,UAAA;AAAA,MAAA,2DAAsB;AAAA,QACrB,OAAO,MAAM;AAAA,QACb,OAAO;AAAA,QACP,WAAW;AAAA,MAAA;AAAA,MAEbC,2BAAAA;AAAAA,QAACS,cAAAA;AAAAA,QAAA;AAAA,UACC,OAAO,MAAM;AAAA,UACb,UAAU;AAAA,UACV,WAAU;AAAA,UACT,GAAI,oBAAoB,EAAE,YAAY,sBAAsB,CAAA;AAAA,QAAC;AAAA,MAAA;AAAA,IAChE,GACF;AAAA,IAEFT,2BAAAA,IAAC,OAAA,EAAI,WAAU,kBACZ,UAAA,YAAY,UACXA,2BAAAA,IAACU,wBAAAA,uBAAA,EAAsB,OAAO,YAAA,CAAa,IAE3CV,2BAAAA;AAAAA,MAACW,KAAAA;AAAAA,MAAA;AAAA,QAEE,GAAG;AAAA,QACH,GAAI,eAAe,SAChB,EAAE,QAAQ,gBAAgB,WAAW,KAAA,IACrC,CAAA;AAAA,QACJ;AAAA,QACC,GAAI,kBAAkB,EAAE,gBAAA,IAAoB,CAAA;AAAA,QAC7C;AAAA,QACA,iBAAiB;AAAA,QACjB,eAAe;AAAA,QACf,yBAAyB;AAAA,QACzB;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QAClB,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAA,IAAa,CAAA;AAAA,QACrD;AAAA,QACA,OAAO;AAAA,QACN,GAAI,gBAAgB,EAAE,cAAA,IAAkB,CAAA;AAAA,QACzC,MAAM;AAAA,QACN;AAAA,QACA,qBAAqB;AAAA,MAAA;AAAA,MAtBhB,MAAM,YAAY,OAAO,MAAM,EAAE;AAAA,IAAA,EAuBxC,CAEJ;AAAA,EAAA,GACF;AAGF,QAAM,aAAaC,MAAAA;AAAAA,IACjB;AAAA,IACA,MAAM,YAAY,2BAA2B;AAAA,EAAA;AAK/C,MAAI,CAAC,KAAK;AACR,WACEZ,+BAAC,SAAI,WAAW,YAAY,OAAO,EAAE,QAAQ,MAAM,OAAA,GACjD,UAAAA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OACE,MAAM,YACF,EAAE,UAAU,YAAY,OAAO,QAAQ,QAAQ,WAC/C;AAAA,UACE,UAAU;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,KAAK,MAAM;AAAA,UACX,OAAO,MAAM;AAAA,UACb,QAAQ,MAAM;AAAA,QAAA;AAAA,QAIrB,UAAA;AAAA,MAAA;AAAA,IAAA,GAEL;AAAA,EAEJ;AAEA,SACED,gCAAC,SAAI,WAAW,YAAY,OAAO,EAAE,QAAQ,MAAM,OAAA,GACjD,UAAA;AAAA,IAAAC,2BAAAA,IAAC,WAAO,UAAA,aAAA,CAAa;AAAA,IACrBA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,UACP,GAAG,MAAM;AAAA,UACT,GAAG,MAAM;AAAA,UACT,OAAO,MAAM;AAAA,UACb,QAAQ,MAAM;AAAA,QAAA;AAAA,QAEhB,OAAO,EAAE,eAAe,OAAA;AAAA,QACxB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,QAAO;AAAA,QACP,qBAAoB;AAAA,QACpB,iBAAiB,MAAM;AAAA,QACvB,gBAAgB,CAAC,MAAM;AAAA,QACvB,aAAa,MAAM,aAAa,MAAM,EAAE;AAAA,QACxC,YAAY,CAAC,IAAI,MAAM,YAAY,MAAM,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG;AAAA,QAC/D,cAAc,CAAC,IAAI,MAAM,KAAK,QAAQ,QACpC,YAAY,MAAM,IAAI;AAAA,UACpB,OAAO,IAAI;AAAA,UACX,QAAQ,IAAI;AAAA,UACZ,GAAG,IAAI;AAAA,UACP,GAAG,IAAI;AAAA,QAAA,CACR;AAAA,QAGF,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF;AAEJ;AAIO,SAAS,gBAAgB,OAAuC;AACrE,QAAM,EAAE,OAAA,IAAWhB,uCAAA;AACnB,SACEgB,2BAAAA,IAAAa,WAAAA,UAAA,EACG,UAAA,OAAO,IAAI,CAAC,UACXb,2BAAAA,IAAC,YAAA,EAA0B,OAAe,GAAG,MAAA,GAA5B,MAAM,EAA6B,CACrD,GACH;AAEJ;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWindow.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ChatWindow.tsx"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EACV,4BAA4B,EAC5B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAa5B;;;oEAGoE;AACpE,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,KAAmB,EACnB,WAAkC,EAClC,aAAa,EACb,iBAAiB,EACjB,KAAK,EACL,eAAuB,EACvB,QAA4B,EAC5B,WAAkB,EAClB,aAAa,EACb,YAAY,EACZ,mBAAmB,GACpB,EAAE,eAAe,2CA4XjB;AAED;8DAC8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,2CASpE"}
1
+ {"version":3,"file":"ChatWindow.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ChatWindow.tsx"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EACV,4BAA4B,EAC5B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAa5B;;;oEAGoE;AACpE,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,KAAmB,EACnB,WAAkC,EAClC,aAAa,EACb,iBAAiB,EACjB,KAAK,EACL,eAAuB,EACvB,QAA4B,EAC5B,WAAkB,EAClB,aAAa,EACb,YAAY,EACZ,mBAAmB,GACpB,EAAE,eAAe,2CAucjB;AAED;8DAC8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,2CASpE"}