@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.
- package/dist/data/ai/AdvancedChatConfig.cjs +3 -0
- package/dist/data/ai/AdvancedChatConfig.cjs.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.d.ts +2 -1
- package/dist/data/ai/AdvancedChatConfig.d.ts.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.js +3 -0
- package/dist/data/ai/AdvancedChatConfig.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +77 -4
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +78 -5
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.cjs +19 -4
- package/dist/data/ai/ChatWindow.runtime.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.d.ts +2 -0
- package/dist/data/ai/ChatWindow.runtime.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.js +19 -4
- package/dist/data/ai/ChatWindow.runtime.js.map +1 -1
- package/dist/data/ai/ChatWindow.test-utils.d.ts +2 -1
- package/dist/data/ai/ChatWindow.test-utils.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.cjs +8 -1
- package/dist/data/ai/ToolPreferences.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.d.ts +2 -1
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.js +8 -1
- package/dist/data/ai/ToolPreferences.js.map +1 -1
- package/dist/data/chat/Chat.cjs +34 -7
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts +9 -1
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.js +34 -7
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.cjs +13 -7
- package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.d.ts +2 -1
- package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.js +13 -7
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
- package/dist/data/chat/ContextMeter.cjs +64 -27
- package/dist/data/chat/ContextMeter.cjs.map +1 -1
- package/dist/data/chat/ContextMeter.d.ts +11 -4
- package/dist/data/chat/ContextMeter.d.ts.map +1 -1
- package/dist/data/chat/ContextMeter.js +64 -27
- package/dist/data/chat/ContextMeter.js.map +1 -1
- package/dist/data/chat/Message.cjs +36 -1
- package/dist/data/chat/Message.cjs.map +1 -1
- package/dist/data/chat/Message.d.ts +1 -1
- package/dist/data/chat/Message.d.ts.map +1 -1
- package/dist/data/chat/Message.js +37 -2
- package/dist/data/chat/Message.js.map +1 -1
- package/dist/data/chat/approval.cjs +17 -0
- package/dist/data/chat/approval.cjs.map +1 -1
- package/dist/data/chat/approval.d.ts +5 -0
- package/dist/data/chat/approval.d.ts.map +1 -1
- package/dist/data/chat/approval.js +17 -0
- package/dist/data/chat/approval.js.map +1 -1
- package/dist/data/chat/fork-seed.cjs +22 -0
- package/dist/data/chat/fork-seed.cjs.map +1 -0
- package/dist/data/chat/fork-seed.d.ts +8 -0
- package/dist/data/chat/fork-seed.d.ts.map +1 -0
- package/dist/data/chat/fork-seed.js +22 -0
- package/dist/data/chat/fork-seed.js.map +1 -0
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +19 -0
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/chat/usage-snapshot.cjs +10 -1
- package/dist/data/chat/usage-snapshot.cjs.map +1 -1
- package/dist/data/chat/usage-snapshot.d.ts.map +1 -1
- package/dist/data/chat/usage-snapshot.js +10 -1
- package/dist/data/chat/usage-snapshot.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.cjs +3 -0
- package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.d.ts +3 -1
- package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.js +3 -0
- package/dist/data/runtime/RuntimeBar.js.map +1 -1
- package/dist/data/runtime/RuntimeBarCombo.cjs +15 -1
- package/dist/data/runtime/RuntimeBarCombo.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarCombo.d.ts +2 -1
- package/dist/data/runtime/RuntimeBarCombo.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarCombo.js +15 -1
- package/dist/data/runtime/RuntimeBarCombo.js.map +1 -1
- package/dist/data/runtime/RuntimeBarSegments.cjs +7 -0
- package/dist/data/runtime/RuntimeBarSegments.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarSegments.d.ts +2 -1
- package/dist/data/runtime/RuntimeBarSegments.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarSegments.js +7 -0
- package/dist/data/runtime/RuntimeBarSegments.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/styles.css +1 -1
- 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,
|
|
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":";;;;;;;AAoCO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf;AACF,GAA4B;AAC1B,QAAM,eAAe,CAAC,KAA6B,QAAgB;AACjE,UAAM,OAAyB,EAAE,GAAG,OAAA;AACpC,UAAM,SAAS,oBAAoB,KAAK,QAAQ,WAAW;AAC3D,QAAI,WAAW,OAAW,QAAO,KAAK,GAAG;AAAA,QACpC,MAAK,GAAG,IAAI;AACjB,qDAAiB;AAAA,EACnB;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,8FACb,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,qBAAC,WAAA,EAAQ,WAAU,aACjB,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,wEAAuE,UAAA,WAEtF;AAAA,QACC,iBACC,oBAAC,OAAA,EAAI,WAAU,oFAAmF,UAAA,kJAIlG;AAAA,QAED,kBACC,oBAAC,OAAA,EAAI,WAAU,iCAAgC,UAAA,4CAE/C;AAAA,QAED,gBACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YAEV,UAAA;AAAA,cAAA,oBAAC,UAAM,UAAA,aAAA,CAAa;AAAA,cACnB,kBACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,SAAS;AAAA,kBACV,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAED;AAAA,UAAA;AAAA,QAAA;AAAA,QAIN;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,OAAO;AAAA,YACP,UAAU,CAAC,SAAS,mDAAkB;AAAA,YACtC;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACP,GAAI,kBAAkB,EAAE,UAAU,gBAAA,IAAoB,CAAA;AAAA,YACvD,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAEZ,qBAAC,SAAA,EAAM,WAAU,2EACf,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,yBAAwB,UAAA,mBAAe;AAAA,UACvD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,cAAW;AAAA,cACX,OAAO;AAAA,cACP,UAAU,CAAC,UACT;AAAA,gBACE,MAAM,OAAO;AAAA;AAAA,cAGjB,WAAU;AAAA,cAET,UAAA,+BAA+B,IAAI,CAAC,WACnC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,OAAO,OAAO;AAAA,kBACd,OAAO,OAAO;AAAA,kBAEb,UAAA,OAAO;AAAA,gBAAA;AAAA,gBAJH,OAAO;AAAA,cAAA,CAMf;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,EAAA,CACF;AAAA,MAAA,GACF;AAAA,MACA,qBAAC,WAAA,EAAQ,WAAU,aACjB,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,wEAAuE,UAAA,cAEtF;AAAA,QACA,qBAAC,SAAA,EAAM,WAAU,uEACf,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,yBAAwB,UAAA,eAAW;AAAA,UACnD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAK;AAAA,cACL,MAAM;AAAA,cACN,OAAO,eAAe;AAAA,cACtB,UAAU,CAAC,UACT,2DAAsB,OAAO,MAAM,OAAO,KAAK;AAAA,YAAC;AAAA,UAAA;AAAA,UAGpD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAK;AAAA,cACL,MAAM;AAAA,cACN,OAAO,eAAe;AAAA,cACtB,UAAU,CAAC,UACT,2DAAsB,oBAAoB,MAAM,OAAO,KAAK;AAAA,cAE9D,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ,EAAA,CACF;AAAA,MAAA,GACF;AAAA,MACA,qBAAC,WAAA,EAAQ,WAAU,aACjB,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,wEAAuE,UAAA,UAEtF;AAAA,QACA,qBAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,UAAA,qBAAC,SAAA,EAAM,WAAU,qBACf,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAK,WAAU,yBAAwB,UAAA,YAAQ;AAAA,YAChD;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,QAAO,iCAAQ,SAAQ;AAAA,gBACvB,UAAU,CAAC,UAAU,aAAa,QAAQ,MAAM,OAAO,KAAK;AAAA,gBAC5D,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,GACF;AAAA,UACA,qBAAC,SAAA,EAAM,WAAU,qBACf,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAK,WAAU,yBAAwB,UAAA,cAAU;AAAA,YAClD;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,QAAO,iCAAQ,cAAa;AAAA,gBAC5B,UAAU,CAAC,UACT,aAAa,aAAa,MAAM,OAAO,KAAK;AAAA,gBAE9C,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,EAAA,CACF;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GACF;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,UAAU,mBAAmB;AAAA,QAC7B,oBAAoB,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EACvB,GACF;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,SAAS,+BAAO;AACtB,QAAM,QAAQ,+BAAO;AACrB,SACE,qBAAC,SAAA,EAAM,WAAU,mFAIf,UAAA;AAAA,IAAA,oBAAC,OAAA,EAAI,WAAU,wEAAuE,UAAA,qBAEtF;AAAA,IACA,qBAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,GAAG,aAAa,+BAAO,UAAU,CAAC,MAAM;AAAA,YAC7C,+BAAO;AAAA,UAAA,CACR;AAAA,QAAA;AAAA,MAAA;AAAA,MAEH;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,aAAa,iCAAQ,WAAW;AAAA,QAAA;AAAA,MAAA;AAAA,MAEzC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,aAAa,iCAAQ,YAAY;AAAA,QAAA;AAAA,MAAA;AAAA,MAE1C;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,aAAa,iCAAQ,eAAe;AAAA,QAAA;AAAA,MAAA;AAAA,MAE7C;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,aAAa,iCAAQ,eAAe;AAAA,QAAA;AAAA,MAAA;AAAA,MAE7C;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,aAAa,iCAAQ,gBAAgB;AAAA,QAAA;AAAA,MAAA;AAAA,MAE9C;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,aAAa,iCAAQ,WAAW;AAAA,QAAA;AAAA,MAAA;AAAA,IACzC,GACF;AAAA,IACA,oBAAC,OAAA,EAAI,WAAU,wEAAuE,UAAA,oBAEtF;AAAA,IACA,qBAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,MAAA,oBAAC,aAAU,OAAM,SAAQ,OAAO,UAAU,+BAAO,QAAQ,GAAG;AAAA,MAC5D,oBAAC,aAAU,OAAM,UAAS,OAAO,UAAU,+BAAO,SAAS,GAAG;AAAA,MAC9D,oBAAC,aAAU,OAAM,aAAY,OAAO,UAAU,+BAAO,YAAY,GAAG;AAAA,MACpE,oBAAC,aAAU,OAAM,cAAa,OAAO,UAAU,+BAAO,YAAY,GAAG;AAAA,MACrE;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,UAAU,+BAAO,aAAa;AAAA,QAAA;AAAA,MAAA;AAAA,MAEvC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,WAAU,+BAAO,UAAQ,+BAAO,SAAQ;AAAA,UAC/C,QAAM;AAAA,QAAA;AAAA,MAAA;AAAA,IACR,GACF;AAAA,IACC,sBACC,oBAAC,qBAAA,EAAoB,QAAgB,SAAA,CAAoB;AAAA,EAAA,GAE7D;AAEJ;AAEA,SAAS,UAAU;AAAA,EACjB;AAAA,EACA;AAAA,EACA,SAAS;AACX,GAIG;AACD,SACE,qBAAC,OAAA,EAAI,WAAU,wGACb,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,WAAU,kCAAkC,UAAA,OAAM;AAAA,IACxD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,GAAG,aAAa,UAAU,+BAA+B;AAAA,QAEnE,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF;AAEJ;AAEA,SAAS,oBAAoB,KAAa,UAAU,OAA2B;AAC7E,MAAI,IAAI,WAAW,GAAI,QAAO;AAC9B,QAAM,QAAQ,OAAO,GAAG;AACxB,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACpC,SAAO,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,IAAI;AACpD;AAEA,SAAS,aAAa,OAAmC;AACvD,MAAI,SAAS,QAAQ,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACrD,SAAO,IAAI,KAAK,eAAe,OAAO,KAAK;AAC7C;AAEA,SAAS,UAAU,OAAmC;AACpD,MAAI,SAAS,QAAQ,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACrD,SAAO,IAAI,MAAM,QAAQ,SAAS,IAAI,IAAI,CAAC,CAAC;AAC9C;"}
|
|
@@ -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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatWindow.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ChatWindow.tsx"],"names":[],"mappings":"
|
|
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"}
|