@flanksource/clicky-ui 0.3.26 → 0.3.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/data/FixtureEditor/fixture-frontmatter.cjs +4 -0
  2. package/dist/data/FixtureEditor/fixture-frontmatter.cjs.map +1 -1
  3. package/dist/data/FixtureEditor/fixture-frontmatter.d.ts.map +1 -1
  4. package/dist/data/FixtureEditor/fixture-frontmatter.js +4 -0
  5. package/dist/data/FixtureEditor/fixture-frontmatter.js.map +1 -1
  6. package/dist/data/ai/PromptRunEditor/index.cjs +2 -3
  7. package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
  8. package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
  9. package/dist/data/ai/PromptRunEditor/index.js +2 -3
  10. package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
  11. package/dist/data/ai/PromptRunEditor/model.cjs +1 -0
  12. package/dist/data/ai/PromptRunEditor/model.cjs.map +1 -1
  13. package/dist/data/ai/PromptRunEditor/model.d.ts +1 -1
  14. package/dist/data/ai/PromptRunEditor/model.d.ts.map +1 -1
  15. package/dist/data/ai/PromptRunEditor/model.js +1 -0
  16. package/dist/data/ai/PromptRunEditor/model.js.map +1 -1
  17. package/dist/data/ai/RuntimeModePicker.cjs +11 -9
  18. package/dist/data/ai/RuntimeModePicker.cjs.map +1 -1
  19. package/dist/data/ai/RuntimeModePicker.d.ts.map +1 -1
  20. package/dist/data/ai/RuntimeModePicker.js +12 -10
  21. package/dist/data/ai/RuntimeModePicker.js.map +1 -1
  22. package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs +5 -0
  23. package/dist/data/ai/SpecRuntimeEditor/ModelSection.cjs.map +1 -1
  24. package/dist/data/ai/SpecRuntimeEditor/ModelSection.d.ts.map +1 -1
  25. package/dist/data/ai/SpecRuntimeEditor/ModelSection.js +5 -0
  26. package/dist/data/ai/SpecRuntimeEditor/ModelSection.js.map +1 -1
  27. package/dist/data/ai/SpecRuntimeEditor.model.cjs +4 -0
  28. package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
  29. package/dist/data/ai/SpecRuntimeEditor.model.d.ts +2 -0
  30. package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
  31. package/dist/data/ai/SpecRuntimeEditor.model.js +4 -0
  32. package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
  33. package/dist/data/chat/Chat.cjs +4 -2
  34. package/dist/data/chat/Chat.cjs.map +1 -1
  35. package/dist/data/chat/Chat.d.ts.map +1 -1
  36. package/dist/data/chat/Chat.js +4 -2
  37. package/dist/data/chat/Chat.js.map +1 -1
  38. package/dist/data/chat/Chat.runtime.cjs +14 -3
  39. package/dist/data/chat/Chat.runtime.cjs.map +1 -1
  40. package/dist/data/chat/Chat.runtime.d.ts.map +1 -1
  41. package/dist/data/chat/Chat.runtime.js +15 -4
  42. package/dist/data/chat/Chat.runtime.js.map +1 -1
  43. package/dist/data/runtime/RuntimeBar.cjs +26 -41
  44. package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
  45. package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
  46. package/dist/data/runtime/RuntimeBar.js +28 -43
  47. package/dist/data/runtime/RuntimeBar.js.map +1 -1
  48. package/dist/data/runtime/RuntimeBar.model.cjs +65 -0
  49. package/dist/data/runtime/RuntimeBar.model.cjs.map +1 -1
  50. package/dist/data/runtime/RuntimeBar.model.d.ts +11 -3
  51. package/dist/data/runtime/RuntimeBar.model.d.ts.map +1 -1
  52. package/dist/data/runtime/RuntimeBar.model.js +65 -0
  53. package/dist/data/runtime/RuntimeBar.model.js.map +1 -1
  54. package/dist/data/runtime/model-capabilities.cjs +8 -5
  55. package/dist/data/runtime/model-capabilities.cjs.map +1 -1
  56. package/dist/data/runtime/model-capabilities.d.ts +6 -1
  57. package/dist/data/runtime/model-capabilities.d.ts.map +1 -1
  58. package/dist/data/runtime/model-capabilities.js +8 -5
  59. package/dist/data/runtime/model-capabilities.js.map +1 -1
  60. package/dist/data/runtime/runtime-mode.cjs +17 -0
  61. package/dist/data/runtime/runtime-mode.cjs.map +1 -1
  62. package/dist/data/runtime/runtime-mode.d.ts +6 -0
  63. package/dist/data/runtime/runtime-mode.d.ts.map +1 -1
  64. package/dist/data/runtime/runtime-mode.js +17 -0
  65. package/dist/data/runtime/runtime-mode.js.map +1 -1
  66. package/dist/data/version-info.cjs +3 -3
  67. package/dist/data/version-info.js +3 -3
  68. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { DEFAULT_REASONING_EFFORTS } from "../chat/effort-icons.js";
3
- import { runtimeModelMatches } from "./RuntimeBar.model.js";
3
+ import { runtimeModelForValue, applyRuntimeBackend } from "./RuntimeBar.model.js";
4
4
  import { RuntimeBarCombo } from "./RuntimeBarCombo.js";
5
5
  import { RuntimeBarSegments } from "./RuntimeBarSegments.js";
6
6
  import { isSelectableModel } from "./availability.js";
7
7
  import { effortOptionsForModel, reconcileModelCapabilities } from "./model-capabilities.js";
8
- import { selectionForBackend, SPEC_RUNTIME_FAMILIES, familyById, firstMode, modelsForFamily, backendForFamilyMode, modelBelongsToFamily } from "./runtime-mode.js";
8
+ import { selectionForBackend, SPEC_RUNTIME_FAMILIES, familyById, firstMode, modelsForFamily } from "./runtime-mode.js";
9
9
  function RuntimeBar({
10
10
  value,
11
11
  onChange,
@@ -21,60 +21,45 @@ function RuntimeBar({
21
21
  const family = familyById(families, selection.family);
22
22
  const mode = family.modes.find((entry) => entry.id === selection.mode) ?? firstMode(family);
23
23
  const modelOptions = modelsForFamily(models, family, value.backend);
24
- const selectedModel = models.find(
25
- (entry) => {
26
- var _a;
27
- return isSelectableModel(entry) && ((_a = entry.runtime) == null ? void 0 : _a.backend) === value.backend && runtimeModelMatches(entry, value);
28
- }
29
- );
30
- const resolvedModel = selectedModel ?? models.find(
31
- (entry) => isSelectableModel(entry) && runtimeModelMatches(entry, value)
32
- );
24
+ const resolvedModel = runtimeModelForValue(models, value, isSelectableModel);
33
25
  const selectedModelUnavailable = Boolean(
34
- value.model && models.some(
35
- (entry) => !isSelectableModel(entry) && runtimeModelMatches(entry, value)
36
- )
26
+ (value.id || value.model) && runtimeModelForValue(models, value, (entry) => !isSelectableModel(entry))
37
27
  );
38
28
  const supportedEfforts = effortOptionsForModel(
39
29
  resolvedModel,
40
30
  reasoningEfforts
41
31
  );
42
32
  const applyBackend = (familyId, modeId) => {
43
- const backend = backendForFamilyMode(families, familyId, modeId);
44
- if (backend === (value.backend ?? "")) return;
45
- let next = withOptionalRuntimeValue(
46
- withRuntimeValue(value, { backend }),
47
- "cliArgs",
48
- void 0
49
- );
50
- if (!modelBelongsToFamily(
51
- value.model,
33
+ const next = applyRuntimeBackend(
34
+ value,
52
35
  models,
53
- familyById(families, familyId),
54
- backend
55
- )) {
56
- next = withoutCatalogModel(next);
57
- }
58
- onChange(next);
36
+ families,
37
+ familyId,
38
+ modeId,
39
+ reasoningEfforts
40
+ );
41
+ if (next !== value) onChange(next);
59
42
  };
60
- const applyCustomModel = (model) => onChange(
61
- withOptionalRuntimeValue(withoutCatalogModel(value), "model", model)
62
- );
63
- const applyModel = (model) => {
64
- const next = reconcileModelCapabilities(value, model, reasoningEfforts);
65
- if (!mode.provider || model.provider !== mode.provider) {
66
- onChange(next);
67
- return;
68
- }
43
+ const preserveSelectedMode = (next) => value.backend === mode.backend ? withRuntimeValue(next, { mode: mode.id }) : next;
44
+ const applyCustomModel = (model) => {
69
45
  onChange(
70
- withOptionalRuntimeValue(
71
- withOptionalRuntimeValue(next, "backend", mode.backend),
72
- "mode",
73
- mode.id
46
+ preserveSelectedMode(
47
+ withOptionalRuntimeValue(withoutCatalogModel(value), "model", model)
74
48
  )
75
49
  );
76
50
  };
77
- const clearModel = () => onChange(withoutCatalogModel(value));
51
+ const applyModel = (model) => {
52
+ const next = reconcileModelCapabilities(
53
+ withoutCatalogModel(value),
54
+ model,
55
+ reasoningEfforts,
56
+ { backend: mode.backend, mode: mode.id }
57
+ );
58
+ onChange(next);
59
+ };
60
+ const clearModel = () => {
61
+ onChange(preserveSelectedMode(withoutCatalogModel(value)));
62
+ };
78
63
  const applyEffort = (effort) => onChange(withOptionalRuntimeValue(value, "effort", effort));
79
64
  if (variant === "combo") {
80
65
  return /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeBar.js","sources":["../../../src/data/runtime/RuntimeBar.tsx"],"sourcesContent":["import { DEFAULT_REASONING_EFFORTS } from \"../chat/effort-icons\";\nimport type { ChatModel, ChatModelRuntime } from \"../chat/types\";\nimport { runtimeModelMatches } from \"./RuntimeBar.model\";\nimport { RuntimeBarCombo } from \"./RuntimeBarCombo\";\nimport { RuntimeBarSegments } from \"./RuntimeBarSegments\";\nimport { isSelectableModel } from \"./availability\";\nimport {\n effortOptionsForModel,\n reconcileModelCapabilities,\n} from \"./model-capabilities\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n backendForFamilyMode,\n familyById,\n firstMode,\n modelBelongsToFamily,\n modelsForFamily,\n selectionForBackend,\n type SpecRuntimeFamily,\n} from \"./runtime-mode\";\n\nexport type RuntimeBarValue = ChatModelRuntime & {\n cliArgs?: Record<string, unknown>;\n};\n\nexport type RuntimeBarProps<T extends RuntimeBarValue = RuntimeBarValue> = {\n value: T;\n onChange: (value: T) => void;\n /** `segmented` uses field triggers; `combo` uses one direct-edit menu. */\n variant?: \"combo\" | \"segmented\";\n /** Model catalog. Only the selected family's models are listed; a family the\n * catalog does not describe is served by the segment's free-text entry. */\n models?: ChatModel[] | undefined;\n families?: SpecRuntimeFamily[] | undefined;\n /** Effort tiers offered when the catalog does not describe the model. */\n reasoningEfforts?: string[] | undefined;\n /** Locks model identity (family, backend, and model) while leaving effort editable. */\n locked?: boolean | undefined;\n ariaLabel?: string | undefined;\n className?: string | undefined;\n};\n\n/** Self-describing runtime controls with segmented and combo presentations. */\nexport function RuntimeBar<T extends RuntimeBarValue>({\n value,\n onChange,\n variant = \"segmented\",\n models = [],\n families = SPEC_RUNTIME_FAMILIES,\n reasoningEfforts = DEFAULT_REASONING_EFFORTS,\n locked = false,\n ariaLabel = \"Runtime\",\n className,\n}: RuntimeBarProps<T>) {\n const selection = selectionForBackend(families, value.backend);\n const family = familyById(families, selection.family);\n const mode =\n family.modes.find((entry) => entry.id === selection.mode) ??\n firstMode(family);\n const modelOptions = modelsForFamily(models, family, value.backend);\n const selectedModel = models.find(\n (entry) =>\n isSelectableModel(entry) &&\n entry.runtime?.backend === value.backend &&\n runtimeModelMatches(entry, value),\n );\n const resolvedModel =\n selectedModel ??\n models.find(\n (entry) => isSelectableModel(entry) && runtimeModelMatches(entry, value),\n );\n const selectedModelUnavailable = Boolean(\n value.model &&\n models.some(\n (entry) => !isSelectableModel(entry) && runtimeModelMatches(entry, value),\n ),\n );\n const supportedEfforts = effortOptionsForModel(\n resolvedModel,\n reasoningEfforts,\n );\n\n const applyBackend = (familyId: string, modeId: string) => {\n const backend = backendForFamilyMode(families, familyId, modeId);\n if (backend === (value.backend ?? \"\")) return;\n let next = withOptionalRuntimeValue(\n withRuntimeValue(value, { backend }),\n \"cliArgs\",\n undefined,\n );\n if (\n !modelBelongsToFamily(\n value.model,\n models,\n familyById(families, familyId),\n backend,\n )\n ) {\n next = withoutCatalogModel(next);\n }\n onChange(next);\n };\n\n const applyCustomModel = (model: string) =>\n onChange(\n withOptionalRuntimeValue(withoutCatalogModel(value), \"model\", model),\n );\n // A menu row carries the backend of the catalog it was listed under, and one\n // catalog serves several backends — claude-cli and claude-cmux models are\n // listed as claude-agent rows. Copying the row's runtime verbatim would let\n // picking a model silently move the user off the mode they chose, so a row\n // drawn from the selected mode's own catalog keeps that mode.\n const applyModel = (model: ChatModel) => {\n const next = reconcileModelCapabilities(value, model, reasoningEfforts);\n if (!mode.provider || model.provider !== mode.provider) {\n onChange(next);\n return;\n }\n onChange(\n withOptionalRuntimeValue(\n withOptionalRuntimeValue(next, \"backend\", mode.backend),\n \"mode\",\n mode.id,\n ),\n );\n };\n const clearModel = () => onChange(withoutCatalogModel(value));\n const applyEffort = (effort: string) =>\n onChange(withOptionalRuntimeValue(value, \"effort\", effort));\n\n if (variant === \"combo\") {\n return (\n <RuntimeBarCombo\n value={value}\n families={families}\n family={family}\n mode={mode}\n selectedMode={selection.mode}\n models={modelOptions}\n selectedModel={resolvedModel}\n selectedModelUnavailable={selectedModelUnavailable}\n supportedEfforts={supportedEfforts}\n locked={locked}\n ariaLabel={ariaLabel}\n className={className}\n onFamilyChange={(familyId) => applyBackend(familyId, selection.mode)}\n onModeChange={(modeId) => applyBackend(family.id, modeId)}\n onModelSelect={applyModel}\n onModelClear={clearModel}\n onEffortChange={applyEffort}\n />\n );\n }\n\n return (\n <RuntimeBarSegments\n value={value}\n models={models}\n modelOptions={modelOptions}\n resolvedModel={resolvedModel}\n selectedModelUnavailable={selectedModelUnavailable}\n families={families}\n family={family}\n mode={mode}\n selectedMode={selection.mode}\n reasoningEfforts={reasoningEfforts}\n supportedEfforts={supportedEfforts}\n locked={locked}\n ariaLabel={ariaLabel}\n className={className}\n onBackendChange={applyBackend}\n onCustomModel={applyCustomModel}\n onModelSelect={applyModel}\n onModelClear={clearModel}\n onEffortChange={applyEffort}\n />\n );\n}\n\nfunction withoutCatalogModel<T extends RuntimeBarValue>(value: T): T {\n return withOptionalRuntimeValue(\n withOptionalRuntimeValue(value, \"model\", undefined),\n \"id\",\n undefined,\n );\n}\n\nfunction withRuntimeValue<T extends RuntimeBarValue>(\n value: T,\n patch: Partial<RuntimeBarValue>,\n): T {\n return { ...value, ...patch };\n}\n\nfunction withOptionalRuntimeValue<T extends RuntimeBarValue>(\n value: T,\n key: keyof RuntimeBarValue,\n next: unknown,\n): T {\n const updated = { ...value } as Record<string, unknown>;\n if (next === undefined || next === \"\") {\n delete updated[key];\n } else {\n updated[key] = next;\n }\n return updated as T;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RuntimeBar.js","sources":["../../../src/data/runtime/RuntimeBar.tsx"],"sourcesContent":["import { DEFAULT_REASONING_EFFORTS } from \"../chat/effort-icons\";\nimport type { ChatModel, ChatModelRuntime } from \"../chat/types\";\nimport { applyRuntimeBackend, runtimeModelForValue } from \"./RuntimeBar.model\";\nimport { RuntimeBarCombo } from \"./RuntimeBarCombo\";\nimport { RuntimeBarSegments } from \"./RuntimeBarSegments\";\nimport { isSelectableModel } from \"./availability\";\nimport {\n effortOptionsForModel,\n reconcileModelCapabilities,\n} from \"./model-capabilities\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n familyById,\n firstMode,\n modelsForFamily,\n selectionForBackend,\n type SpecRuntimeFamily,\n} from \"./runtime-mode\";\n\nexport type RuntimeBarValue = ChatModelRuntime & {\n cliArgs?: Record<string, unknown>;\n};\n\nexport type RuntimeBarProps<T extends RuntimeBarValue = RuntimeBarValue> = {\n value: T;\n onChange: (value: T) => void;\n /** `segmented` uses field triggers; `combo` uses one direct-edit menu. */\n variant?: \"combo\" | \"segmented\";\n /** Model catalog. Only the selected family's models are listed; a family the\n * catalog does not describe is served by the segment's free-text entry. */\n models?: ChatModel[] | undefined;\n families?: SpecRuntimeFamily[] | undefined;\n /** Effort tiers offered when the catalog does not describe the model. */\n reasoningEfforts?: string[] | undefined;\n /** Locks model identity (family, backend, and model) while leaving effort editable. */\n locked?: boolean | undefined;\n ariaLabel?: string | undefined;\n className?: string | undefined;\n};\n\n/** Self-describing runtime controls with segmented and combo presentations. */\nexport function RuntimeBar<T extends RuntimeBarValue>({\n value,\n onChange,\n variant = \"segmented\",\n models = [],\n families = SPEC_RUNTIME_FAMILIES,\n reasoningEfforts = DEFAULT_REASONING_EFFORTS,\n locked = false,\n ariaLabel = \"Runtime\",\n className,\n}: RuntimeBarProps<T>) {\n const selection = selectionForBackend(families, value.backend);\n const family = familyById(families, selection.family);\n const mode =\n family.modes.find((entry) => entry.id === selection.mode) ??\n firstMode(family);\n const modelOptions = modelsForFamily(models, family, value.backend);\n const resolvedModel = runtimeModelForValue(models, value, isSelectableModel);\n const selectedModelUnavailable = Boolean(\n (value.id || value.model) &&\n runtimeModelForValue(models, value, (entry) => !isSelectableModel(entry)),\n );\n const supportedEfforts = effortOptionsForModel(\n resolvedModel,\n reasoningEfforts,\n );\n\n const applyBackend = (familyId: string, modeId: string) => {\n const next = applyRuntimeBackend(\n value,\n models,\n families,\n familyId,\n modeId,\n reasoningEfforts,\n );\n if (next !== value) onChange(next);\n };\n\n const preserveSelectedMode = (next: T) =>\n value.backend === mode.backend\n ? withRuntimeValue(next, { mode: mode.id })\n : next;\n const applyCustomModel = (model: string) => {\n onChange(\n preserveSelectedMode(\n withOptionalRuntimeValue(withoutCatalogModel(value), \"model\", model),\n ),\n );\n };\n // A menu row carries the backend of the catalog it was listed under, and one\n // catalog serves several backends — claude-cli and claude-cmux models are\n // listed as claude-agent rows. Copying the row's runtime verbatim would let\n // picking a model silently move the user off the mode they chose, so a row\n // drawn from the selected mode's own catalog keeps that mode.\n const applyModel = (model: ChatModel) => {\n const next = reconcileModelCapabilities(\n withoutCatalogModel(value),\n model,\n reasoningEfforts,\n { backend: mode.backend, mode: mode.id },\n );\n onChange(next);\n };\n const clearModel = () => {\n onChange(preserveSelectedMode(withoutCatalogModel(value)));\n };\n const applyEffort = (effort: string) =>\n onChange(withOptionalRuntimeValue(value, \"effort\", effort));\n\n if (variant === \"combo\") {\n return (\n <RuntimeBarCombo\n value={value}\n families={families}\n family={family}\n mode={mode}\n selectedMode={selection.mode}\n models={modelOptions}\n selectedModel={resolvedModel}\n selectedModelUnavailable={selectedModelUnavailable}\n supportedEfforts={supportedEfforts}\n locked={locked}\n ariaLabel={ariaLabel}\n className={className}\n onFamilyChange={(familyId) => applyBackend(familyId, selection.mode)}\n onModeChange={(modeId) => applyBackend(family.id, modeId)}\n onModelSelect={applyModel}\n onModelClear={clearModel}\n onEffortChange={applyEffort}\n />\n );\n }\n\n return (\n <RuntimeBarSegments\n value={value}\n models={models}\n modelOptions={modelOptions}\n resolvedModel={resolvedModel}\n selectedModelUnavailable={selectedModelUnavailable}\n families={families}\n family={family}\n mode={mode}\n selectedMode={selection.mode}\n reasoningEfforts={reasoningEfforts}\n supportedEfforts={supportedEfforts}\n locked={locked}\n ariaLabel={ariaLabel}\n className={className}\n onBackendChange={applyBackend}\n onCustomModel={applyCustomModel}\n onModelSelect={applyModel}\n onModelClear={clearModel}\n onEffortChange={applyEffort}\n />\n );\n}\n\nfunction withoutCatalogModel<T extends RuntimeBarValue>(value: T): T {\n return withOptionalRuntimeValue(\n withOptionalRuntimeValue(value, \"model\", undefined),\n \"id\",\n undefined,\n );\n}\n\nfunction withRuntimeValue<T extends RuntimeBarValue>(\n value: T,\n patch: Partial<RuntimeBarValue>,\n): T {\n return { ...value, ...patch };\n}\n\nfunction withOptionalRuntimeValue<T extends RuntimeBarValue>(\n value: T,\n key: keyof RuntimeBarValue,\n next: unknown,\n): T {\n const updated = { ...value } as Record<string, unknown>;\n if (next === undefined || next === \"\") {\n delete updated[key];\n } else {\n updated[key] = next;\n }\n return updated as T;\n}\n"],"names":[],"mappings":"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"}
@@ -1,14 +1,79 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const providerIcons = require("../chat/provider-icons.cjs");
4
+ const modelCapabilities = require("./model-capabilities.cjs");
5
+ const runtimeMode = require("./runtime-mode.cjs");
4
6
  function runtimeFamilyBrand(family) {
5
7
  const key = providerIcons.providerIcon(family.id) ? family.id : family.provider;
6
8
  return { icon: providerIcons.providerIcon(key), color: providerIcons.providerIconColor(key) };
7
9
  }
8
10
  function runtimeModelMatches(model, value) {
11
+ var _a, _b;
12
+ if (!runtimeModelIdentityMatches(model, value)) return false;
13
+ if (!runtimeMode.modelMatchesBackend(model, value.backend)) return false;
14
+ if (value.backend !== void 0 && ((_a = model.runtime) == null ? void 0 : _a.backend) !== void 0 && model.runtime.backend !== value.backend) {
15
+ return false;
16
+ }
17
+ if (value.mode !== void 0 && ((_b = model.runtime) == null ? void 0 : _b.mode) !== void 0 && model.runtime.mode !== value.mode) {
18
+ return false;
19
+ }
20
+ return true;
21
+ }
22
+ function runtimeModelForValue(models, value, isEligible = () => true) {
23
+ var _a;
24
+ const exact = models.find(
25
+ (model) => isEligible(model) && runtimeModelMatches(model, value)
26
+ );
27
+ if (exact) return exact;
28
+ const identityMatches = models.filter(
29
+ (model) => isEligible(model) && runtimeModelIdentityMatches(model, value) && runtimeMode.modelMatchesBackend(model, value.backend)
30
+ );
31
+ const canonicalMatches = identityMatches.filter(
32
+ (model) => model.id === value.id || model.id === value.model
33
+ );
34
+ const provider = canonicalMatches.length === 1 ? (_a = canonicalMatches[0]) == null ? void 0 : _a.provider : void 0;
35
+ const scopedMatches = provider ? identityMatches.filter((model) => model.provider === provider) : identityMatches;
36
+ return scopedMatches.length === 1 ? scopedMatches[0] : void 0;
37
+ }
38
+ function runtimeModelIdentityMatches(model, value) {
9
39
  var _a, _b;
10
40
  return value.id !== void 0 && (model.id === value.id || ((_a = model.runtime) == null ? void 0 : _a.id) === value.id) || value.model !== void 0 && (model.id === value.model || ((_b = model.runtime) == null ? void 0 : _b.model) === value.model);
11
41
  }
42
+ function applyRuntimeBackend(value, models, families, familyId, modeId, reasoningEfforts) {
43
+ var _a;
44
+ const backend = runtimeMode.backendForFamilyMode(families, familyId, modeId);
45
+ const mode = runtimeMode.selectionForBackend(families, backend).mode;
46
+ if (backend === (value.backend ?? "") && (value.mode === void 0 || mode === value.mode)) {
47
+ return value;
48
+ }
49
+ const currentModel = runtimeModelForValue(models, value);
50
+ const modelId = ((_a = currentModel == null ? void 0 : currentModel.runtime) == null ? void 0 : _a.model) ?? value.model ?? (currentModel == null ? void 0 : currentModel.id) ?? value.id;
51
+ const nextModel = runtimeMode.modelForFamily(
52
+ modelId,
53
+ models,
54
+ runtimeMode.familyById(families, familyId),
55
+ backend
56
+ );
57
+ let next = withoutCatalogModel(value);
58
+ if (nextModel) {
59
+ next = modelCapabilities.reconcileModelCapabilities(next, nextModel, reasoningEfforts, {
60
+ backend,
61
+ mode
62
+ });
63
+ } else {
64
+ next = { ...next, backend, mode };
65
+ }
66
+ delete next.cliArgs;
67
+ return next;
68
+ }
69
+ function withoutCatalogModel(value) {
70
+ const next = { ...value };
71
+ delete next.model;
72
+ delete next.id;
73
+ return next;
74
+ }
75
+ exports.applyRuntimeBackend = applyRuntimeBackend;
12
76
  exports.runtimeFamilyBrand = runtimeFamilyBrand;
77
+ exports.runtimeModelForValue = runtimeModelForValue;
13
78
  exports.runtimeModelMatches = runtimeModelMatches;
14
79
  //# sourceMappingURL=RuntimeBar.model.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeBar.model.cjs","sources":["../../../src/data/runtime/RuntimeBar.model.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport { providerIcon, providerIconColor } from \"../chat/provider-icons\";\nimport type { ChatModel } from \"../chat/types\";\nimport type { RuntimeBarValue } from \"./RuntimeBar\";\nimport type { SpecRuntimeFamily } from \"./runtime-mode\";\n\nexport function runtimeFamilyBrand(family: SpecRuntimeFamily): {\n icon: StaticIconComponent | undefined;\n color: string | undefined;\n} {\n const key = providerIcon(family.id) ? family.id : family.provider;\n return { icon: providerIcon(key), color: providerIconColor(key) };\n}\n\nexport function runtimeModelMatches(\n model: ChatModel,\n value: RuntimeBarValue,\n): boolean {\n return (\n (value.id !== undefined &&\n (model.id === value.id || model.runtime?.id === value.id)) ||\n (value.model !== undefined &&\n (model.id === value.model || model.runtime?.model === value.model))\n );\n}\n"],"names":["providerIcon","providerIconColor"],"mappings":";;;AAMO,SAAS,mBAAmB,QAGjC;AACA,QAAM,MAAMA,cAAAA,aAAa,OAAO,EAAE,IAAI,OAAO,KAAK,OAAO;AACzD,SAAO,EAAE,MAAMA,2BAAa,GAAG,GAAG,OAAOC,cAAAA,kBAAkB,GAAG,EAAA;AAChE;AAEO,SAAS,oBACd,OACA,OACS;;AACT,SACG,MAAM,OAAO,WACX,MAAM,OAAO,MAAM,QAAM,WAAM,YAAN,mBAAe,QAAO,MAAM,OACvD,MAAM,UAAU,WACd,MAAM,OAAO,MAAM,WAAS,WAAM,YAAN,mBAAe,WAAU,MAAM;AAElE;;;"}
1
+ {"version":3,"file":"RuntimeBar.model.cjs","sources":["../../../src/data/runtime/RuntimeBar.model.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport { providerIcon, providerIconColor } from \"../chat/provider-icons\";\nimport type { ChatModel, ChatModelRuntime } from \"../chat/types\";\nimport { reconcileModelCapabilities } from \"./model-capabilities\";\nimport {\n backendForFamilyMode,\n familyById,\n modelForFamily,\n modelMatchesBackend,\n selectionForBackend,\n type SpecRuntimeFamily,\n} from \"./runtime-mode\";\n\ntype RuntimeBackendValue = ChatModelRuntime & {\n cliArgs?: Record<string, unknown> | undefined;\n};\n\nexport function runtimeFamilyBrand(family: SpecRuntimeFamily): {\n icon: StaticIconComponent | undefined;\n color: string | undefined;\n} {\n const key = providerIcon(family.id) ? family.id : family.provider;\n return { icon: providerIcon(key), color: providerIconColor(key) };\n}\n\n/** Matches a catalog row against both runtime identity and execution selectors. */\nexport function runtimeModelMatches(\n model: ChatModel,\n value: ChatModelRuntime,\n): boolean {\n if (!runtimeModelIdentityMatches(model, value)) return false;\n if (!modelMatchesBackend(model, value.backend)) return false;\n if (\n value.backend !== undefined &&\n model.runtime?.backend !== undefined &&\n model.runtime.backend !== value.backend\n ) {\n return false;\n }\n if (\n value.mode !== undefined &&\n model.runtime?.mode !== undefined &&\n model.runtime.mode !== value.mode\n ) {\n return false;\n }\n return true;\n}\n\n/** Finds one exact runtime row, scoping shared aliases by their canonical provider. */\nexport function runtimeModelForValue(\n models: ChatModel[],\n value: ChatModelRuntime,\n isEligible: (model: ChatModel) => boolean = () => true,\n): ChatModel | undefined {\n const exact = models.find(\n (model) => isEligible(model) && runtimeModelMatches(model, value),\n );\n if (exact) return exact;\n const identityMatches = models.filter(\n (model) =>\n isEligible(model) &&\n runtimeModelIdentityMatches(model, value) &&\n modelMatchesBackend(model, value.backend),\n );\n const canonicalMatches = identityMatches.filter(\n (model) => model.id === value.id || model.id === value.model,\n );\n const provider =\n canonicalMatches.length === 1 ? canonicalMatches[0]?.provider : undefined;\n const scopedMatches = provider\n ? identityMatches.filter((model) => model.provider === provider)\n : identityMatches;\n return scopedMatches.length === 1 ? scopedMatches[0] : undefined;\n}\n\nfunction runtimeModelIdentityMatches(\n model: ChatModel,\n value: ChatModelRuntime,\n): boolean {\n return (\n (value.id !== undefined &&\n (model.id === value.id || model.runtime?.id === value.id)) ||\n (value.model !== undefined &&\n (model.id === value.model || model.runtime?.model === value.model))\n );\n}\n\n/** Applies a family/mode transition without replacing user-owned runtime options. */\nexport function applyRuntimeBackend<T extends RuntimeBackendValue>(\n value: T,\n models: ChatModel[],\n families: SpecRuntimeFamily[],\n familyId: string,\n modeId: string,\n reasoningEfforts: readonly string[],\n): T {\n const backend = backendForFamilyMode(families, familyId, modeId);\n const mode = selectionForBackend(families, backend).mode;\n if (\n backend === (value.backend ?? \"\") &&\n (value.mode === undefined || mode === value.mode)\n ) {\n return value;\n }\n\n const currentModel = runtimeModelForValue(models, value);\n const modelId =\n currentModel?.runtime?.model ?? value.model ?? currentModel?.id ?? value.id;\n const nextModel = modelForFamily(\n modelId,\n models,\n familyById(families, familyId),\n backend,\n );\n let next = withoutCatalogModel(value);\n if (nextModel) {\n next = reconcileModelCapabilities(next, nextModel, reasoningEfforts, {\n backend,\n mode,\n });\n } else {\n next = { ...next, backend, mode };\n }\n delete next.cliArgs;\n return next;\n}\n\nfunction withoutCatalogModel<T extends RuntimeBackendValue>(value: T): T {\n const next = { ...value };\n delete next.model;\n delete next.id;\n return next;\n}\n"],"names":["providerIcon","providerIconColor","modelMatchesBackend","backendForFamilyMode","selectionForBackend","modelForFamily","familyById","reconcileModelCapabilities"],"mappings":";;;;;AAiBO,SAAS,mBAAmB,QAGjC;AACA,QAAM,MAAMA,cAAAA,aAAa,OAAO,EAAE,IAAI,OAAO,KAAK,OAAO;AACzD,SAAO,EAAE,MAAMA,2BAAa,GAAG,GAAG,OAAOC,cAAAA,kBAAkB,GAAG,EAAA;AAChE;AAGO,SAAS,oBACd,OACA,OACS;;AACT,MAAI,CAAC,4BAA4B,OAAO,KAAK,EAAG,QAAO;AACvD,MAAI,CAACC,YAAAA,oBAAoB,OAAO,MAAM,OAAO,EAAG,QAAO;AACvD,MACE,MAAM,YAAY,YAClB,WAAM,YAAN,mBAAe,aAAY,UAC3B,MAAM,QAAQ,YAAY,MAAM,SAChC;AACA,WAAO;AAAA,EACT;AACA,MACE,MAAM,SAAS,YACf,WAAM,YAAN,mBAAe,UAAS,UACxB,MAAM,QAAQ,SAAS,MAAM,MAC7B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,qBACd,QACA,OACA,aAA4C,MAAM,MAC3B;;AACvB,QAAM,QAAQ,OAAO;AAAA,IACnB,CAAC,UAAU,WAAW,KAAK,KAAK,oBAAoB,OAAO,KAAK;AAAA,EAAA;AAElE,MAAI,MAAO,QAAO;AAClB,QAAM,kBAAkB,OAAO;AAAA,IAC7B,CAAC,UACC,WAAW,KAAK,KAChB,4BAA4B,OAAO,KAAK,KACxCA,YAAAA,oBAAoB,OAAO,MAAM,OAAO;AAAA,EAAA;AAE5C,QAAM,mBAAmB,gBAAgB;AAAA,IACvC,CAAC,UAAU,MAAM,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM;AAAA,EAAA;AAEzD,QAAM,WACJ,iBAAiB,WAAW,KAAI,sBAAiB,CAAC,MAAlB,mBAAqB,WAAW;AAClE,QAAM,gBAAgB,WAClB,gBAAgB,OAAO,CAAC,UAAU,MAAM,aAAa,QAAQ,IAC7D;AACJ,SAAO,cAAc,WAAW,IAAI,cAAc,CAAC,IAAI;AACzD;AAEA,SAAS,4BACP,OACA,OACS;;AACT,SACG,MAAM,OAAO,WACX,MAAM,OAAO,MAAM,QAAM,WAAM,YAAN,mBAAe,QAAO,MAAM,OACvD,MAAM,UAAU,WACd,MAAM,OAAO,MAAM,WAAS,WAAM,YAAN,mBAAe,WAAU,MAAM;AAElE;AAGO,SAAS,oBACd,OACA,QACA,UACA,UACA,QACA,kBACG;;AACH,QAAM,UAAUC,YAAAA,qBAAqB,UAAU,UAAU,MAAM;AAC/D,QAAM,OAAOC,YAAAA,oBAAoB,UAAU,OAAO,EAAE;AACpD,MACE,aAAa,MAAM,WAAW,QAC7B,MAAM,SAAS,UAAa,SAAS,MAAM,OAC5C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,qBAAqB,QAAQ,KAAK;AACvD,QAAM,YACJ,kDAAc,YAAd,mBAAuB,UAAS,MAAM,UAAS,6CAAc,OAAM,MAAM;AAC3E,QAAM,YAAYC,YAAAA;AAAAA,IAChB;AAAA,IACA;AAAA,IACAC,YAAAA,WAAW,UAAU,QAAQ;AAAA,IAC7B;AAAA,EAAA;AAEF,MAAI,OAAO,oBAAoB,KAAK;AACpC,MAAI,WAAW;AACb,WAAOC,kBAAAA,2BAA2B,MAAM,WAAW,kBAAkB;AAAA,MACnE;AAAA,MACA;AAAA,IAAA,CACD;AAAA,EACH,OAAO;AACL,WAAO,EAAE,GAAG,MAAM,SAAS,KAAA;AAAA,EAC7B;AACA,SAAO,KAAK;AACZ,SAAO;AACT;AAEA,SAAS,oBAAmD,OAAa;AACvE,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,SAAO,KAAK;AACZ,SAAO,KAAK;AACZ,SAAO;AACT;;;;;"}
@@ -1,10 +1,18 @@
1
1
  import { StaticIconComponent } from '../Icon';
2
- import { ChatModel } from '../chat/types';
3
- import { RuntimeBarValue } from './RuntimeBar';
2
+ import { ChatModel, ChatModelRuntime } from '../chat/types';
4
3
  import { SpecRuntimeFamily } from './runtime-mode';
4
+ type RuntimeBackendValue = ChatModelRuntime & {
5
+ cliArgs?: Record<string, unknown> | undefined;
6
+ };
5
7
  export declare function runtimeFamilyBrand(family: SpecRuntimeFamily): {
6
8
  icon: StaticIconComponent | undefined;
7
9
  color: string | undefined;
8
10
  };
9
- export declare function runtimeModelMatches(model: ChatModel, value: RuntimeBarValue): boolean;
11
+ /** Matches a catalog row against both runtime identity and execution selectors. */
12
+ export declare function runtimeModelMatches(model: ChatModel, value: ChatModelRuntime): boolean;
13
+ /** Finds one exact runtime row, scoping shared aliases by their canonical provider. */
14
+ export declare function runtimeModelForValue(models: ChatModel[], value: ChatModelRuntime, isEligible?: (model: ChatModel) => boolean): ChatModel | undefined;
15
+ /** Applies a family/mode transition without replacing user-owned runtime options. */
16
+ export declare function applyRuntimeBackend<T extends RuntimeBackendValue>(value: T, models: ChatModel[], families: SpecRuntimeFamily[], familyId: string, modeId: string, reasoningEfforts: readonly string[]): T;
17
+ export {};
10
18
  //# sourceMappingURL=RuntimeBar.model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeBar.model.d.ts","sourceRoot":"","sources":["../../../src/data/runtime/RuntimeBar.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG;IAC7D,IAAI,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACtC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAGA;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,eAAe,GACrB,OAAO,CAOT"}
1
+ {"version":3,"file":"RuntimeBar.model.d.ts","sourceRoot":"","sources":["../../../src/data/runtime/RuntimeBar.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAML,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAExB,KAAK,mBAAmB,GAAG,gBAAgB,GAAG;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC/C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG;IAC7D,IAAI,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACtC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAGA;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAkBT;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EAAE,EACnB,KAAK,EAAE,gBAAgB,EACvB,UAAU,GAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAoB,GACrD,SAAS,GAAG,SAAS,CAoBvB;AAcD,qFAAqF;AACrF,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,mBAAmB,EAC/D,KAAK,EAAE,CAAC,EACR,MAAM,EAAE,SAAS,EAAE,EACnB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,CAAC,CA8BH"}
@@ -1,14 +1,79 @@
1
1
  import { providerIcon, providerIconColor } from "../chat/provider-icons.js";
2
+ import { reconcileModelCapabilities } from "./model-capabilities.js";
3
+ import { modelMatchesBackend, backendForFamilyMode, selectionForBackend, modelForFamily, familyById } from "./runtime-mode.js";
2
4
  function runtimeFamilyBrand(family) {
3
5
  const key = providerIcon(family.id) ? family.id : family.provider;
4
6
  return { icon: providerIcon(key), color: providerIconColor(key) };
5
7
  }
6
8
  function runtimeModelMatches(model, value) {
9
+ var _a, _b;
10
+ if (!runtimeModelIdentityMatches(model, value)) return false;
11
+ if (!modelMatchesBackend(model, value.backend)) return false;
12
+ if (value.backend !== void 0 && ((_a = model.runtime) == null ? void 0 : _a.backend) !== void 0 && model.runtime.backend !== value.backend) {
13
+ return false;
14
+ }
15
+ if (value.mode !== void 0 && ((_b = model.runtime) == null ? void 0 : _b.mode) !== void 0 && model.runtime.mode !== value.mode) {
16
+ return false;
17
+ }
18
+ return true;
19
+ }
20
+ function runtimeModelForValue(models, value, isEligible = () => true) {
21
+ var _a;
22
+ const exact = models.find(
23
+ (model) => isEligible(model) && runtimeModelMatches(model, value)
24
+ );
25
+ if (exact) return exact;
26
+ const identityMatches = models.filter(
27
+ (model) => isEligible(model) && runtimeModelIdentityMatches(model, value) && modelMatchesBackend(model, value.backend)
28
+ );
29
+ const canonicalMatches = identityMatches.filter(
30
+ (model) => model.id === value.id || model.id === value.model
31
+ );
32
+ const provider = canonicalMatches.length === 1 ? (_a = canonicalMatches[0]) == null ? void 0 : _a.provider : void 0;
33
+ const scopedMatches = provider ? identityMatches.filter((model) => model.provider === provider) : identityMatches;
34
+ return scopedMatches.length === 1 ? scopedMatches[0] : void 0;
35
+ }
36
+ function runtimeModelIdentityMatches(model, value) {
7
37
  var _a, _b;
8
38
  return value.id !== void 0 && (model.id === value.id || ((_a = model.runtime) == null ? void 0 : _a.id) === value.id) || value.model !== void 0 && (model.id === value.model || ((_b = model.runtime) == null ? void 0 : _b.model) === value.model);
9
39
  }
40
+ function applyRuntimeBackend(value, models, families, familyId, modeId, reasoningEfforts) {
41
+ var _a;
42
+ const backend = backendForFamilyMode(families, familyId, modeId);
43
+ const mode = selectionForBackend(families, backend).mode;
44
+ if (backend === (value.backend ?? "") && (value.mode === void 0 || mode === value.mode)) {
45
+ return value;
46
+ }
47
+ const currentModel = runtimeModelForValue(models, value);
48
+ const modelId = ((_a = currentModel == null ? void 0 : currentModel.runtime) == null ? void 0 : _a.model) ?? value.model ?? (currentModel == null ? void 0 : currentModel.id) ?? value.id;
49
+ const nextModel = modelForFamily(
50
+ modelId,
51
+ models,
52
+ familyById(families, familyId),
53
+ backend
54
+ );
55
+ let next = withoutCatalogModel(value);
56
+ if (nextModel) {
57
+ next = reconcileModelCapabilities(next, nextModel, reasoningEfforts, {
58
+ backend,
59
+ mode
60
+ });
61
+ } else {
62
+ next = { ...next, backend, mode };
63
+ }
64
+ delete next.cliArgs;
65
+ return next;
66
+ }
67
+ function withoutCatalogModel(value) {
68
+ const next = { ...value };
69
+ delete next.model;
70
+ delete next.id;
71
+ return next;
72
+ }
10
73
  export {
74
+ applyRuntimeBackend,
11
75
  runtimeFamilyBrand,
76
+ runtimeModelForValue,
12
77
  runtimeModelMatches
13
78
  };
14
79
  //# sourceMappingURL=RuntimeBar.model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeBar.model.js","sources":["../../../src/data/runtime/RuntimeBar.model.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport { providerIcon, providerIconColor } from \"../chat/provider-icons\";\nimport type { ChatModel } from \"../chat/types\";\nimport type { RuntimeBarValue } from \"./RuntimeBar\";\nimport type { SpecRuntimeFamily } from \"./runtime-mode\";\n\nexport function runtimeFamilyBrand(family: SpecRuntimeFamily): {\n icon: StaticIconComponent | undefined;\n color: string | undefined;\n} {\n const key = providerIcon(family.id) ? family.id : family.provider;\n return { icon: providerIcon(key), color: providerIconColor(key) };\n}\n\nexport function runtimeModelMatches(\n model: ChatModel,\n value: RuntimeBarValue,\n): boolean {\n return (\n (value.id !== undefined &&\n (model.id === value.id || model.runtime?.id === value.id)) ||\n (value.model !== undefined &&\n (model.id === value.model || model.runtime?.model === value.model))\n );\n}\n"],"names":[],"mappings":";AAMO,SAAS,mBAAmB,QAGjC;AACA,QAAM,MAAM,aAAa,OAAO,EAAE,IAAI,OAAO,KAAK,OAAO;AACzD,SAAO,EAAE,MAAM,aAAa,GAAG,GAAG,OAAO,kBAAkB,GAAG,EAAA;AAChE;AAEO,SAAS,oBACd,OACA,OACS;;AACT,SACG,MAAM,OAAO,WACX,MAAM,OAAO,MAAM,QAAM,WAAM,YAAN,mBAAe,QAAO,MAAM,OACvD,MAAM,UAAU,WACd,MAAM,OAAO,MAAM,WAAS,WAAM,YAAN,mBAAe,WAAU,MAAM;AAElE;"}
1
+ {"version":3,"file":"RuntimeBar.model.js","sources":["../../../src/data/runtime/RuntimeBar.model.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport { providerIcon, providerIconColor } from \"../chat/provider-icons\";\nimport type { ChatModel, ChatModelRuntime } from \"../chat/types\";\nimport { reconcileModelCapabilities } from \"./model-capabilities\";\nimport {\n backendForFamilyMode,\n familyById,\n modelForFamily,\n modelMatchesBackend,\n selectionForBackend,\n type SpecRuntimeFamily,\n} from \"./runtime-mode\";\n\ntype RuntimeBackendValue = ChatModelRuntime & {\n cliArgs?: Record<string, unknown> | undefined;\n};\n\nexport function runtimeFamilyBrand(family: SpecRuntimeFamily): {\n icon: StaticIconComponent | undefined;\n color: string | undefined;\n} {\n const key = providerIcon(family.id) ? family.id : family.provider;\n return { icon: providerIcon(key), color: providerIconColor(key) };\n}\n\n/** Matches a catalog row against both runtime identity and execution selectors. */\nexport function runtimeModelMatches(\n model: ChatModel,\n value: ChatModelRuntime,\n): boolean {\n if (!runtimeModelIdentityMatches(model, value)) return false;\n if (!modelMatchesBackend(model, value.backend)) return false;\n if (\n value.backend !== undefined &&\n model.runtime?.backend !== undefined &&\n model.runtime.backend !== value.backend\n ) {\n return false;\n }\n if (\n value.mode !== undefined &&\n model.runtime?.mode !== undefined &&\n model.runtime.mode !== value.mode\n ) {\n return false;\n }\n return true;\n}\n\n/** Finds one exact runtime row, scoping shared aliases by their canonical provider. */\nexport function runtimeModelForValue(\n models: ChatModel[],\n value: ChatModelRuntime,\n isEligible: (model: ChatModel) => boolean = () => true,\n): ChatModel | undefined {\n const exact = models.find(\n (model) => isEligible(model) && runtimeModelMatches(model, value),\n );\n if (exact) return exact;\n const identityMatches = models.filter(\n (model) =>\n isEligible(model) &&\n runtimeModelIdentityMatches(model, value) &&\n modelMatchesBackend(model, value.backend),\n );\n const canonicalMatches = identityMatches.filter(\n (model) => model.id === value.id || model.id === value.model,\n );\n const provider =\n canonicalMatches.length === 1 ? canonicalMatches[0]?.provider : undefined;\n const scopedMatches = provider\n ? identityMatches.filter((model) => model.provider === provider)\n : identityMatches;\n return scopedMatches.length === 1 ? scopedMatches[0] : undefined;\n}\n\nfunction runtimeModelIdentityMatches(\n model: ChatModel,\n value: ChatModelRuntime,\n): boolean {\n return (\n (value.id !== undefined &&\n (model.id === value.id || model.runtime?.id === value.id)) ||\n (value.model !== undefined &&\n (model.id === value.model || model.runtime?.model === value.model))\n );\n}\n\n/** Applies a family/mode transition without replacing user-owned runtime options. */\nexport function applyRuntimeBackend<T extends RuntimeBackendValue>(\n value: T,\n models: ChatModel[],\n families: SpecRuntimeFamily[],\n familyId: string,\n modeId: string,\n reasoningEfforts: readonly string[],\n): T {\n const backend = backendForFamilyMode(families, familyId, modeId);\n const mode = selectionForBackend(families, backend).mode;\n if (\n backend === (value.backend ?? \"\") &&\n (value.mode === undefined || mode === value.mode)\n ) {\n return value;\n }\n\n const currentModel = runtimeModelForValue(models, value);\n const modelId =\n currentModel?.runtime?.model ?? value.model ?? currentModel?.id ?? value.id;\n const nextModel = modelForFamily(\n modelId,\n models,\n familyById(families, familyId),\n backend,\n );\n let next = withoutCatalogModel(value);\n if (nextModel) {\n next = reconcileModelCapabilities(next, nextModel, reasoningEfforts, {\n backend,\n mode,\n });\n } else {\n next = { ...next, backend, mode };\n }\n delete next.cliArgs;\n return next;\n}\n\nfunction withoutCatalogModel<T extends RuntimeBackendValue>(value: T): T {\n const next = { ...value };\n delete next.model;\n delete next.id;\n return next;\n}\n"],"names":[],"mappings":";;;AAiBO,SAAS,mBAAmB,QAGjC;AACA,QAAM,MAAM,aAAa,OAAO,EAAE,IAAI,OAAO,KAAK,OAAO;AACzD,SAAO,EAAE,MAAM,aAAa,GAAG,GAAG,OAAO,kBAAkB,GAAG,EAAA;AAChE;AAGO,SAAS,oBACd,OACA,OACS;;AACT,MAAI,CAAC,4BAA4B,OAAO,KAAK,EAAG,QAAO;AACvD,MAAI,CAAC,oBAAoB,OAAO,MAAM,OAAO,EAAG,QAAO;AACvD,MACE,MAAM,YAAY,YAClB,WAAM,YAAN,mBAAe,aAAY,UAC3B,MAAM,QAAQ,YAAY,MAAM,SAChC;AACA,WAAO;AAAA,EACT;AACA,MACE,MAAM,SAAS,YACf,WAAM,YAAN,mBAAe,UAAS,UACxB,MAAM,QAAQ,SAAS,MAAM,MAC7B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,qBACd,QACA,OACA,aAA4C,MAAM,MAC3B;;AACvB,QAAM,QAAQ,OAAO;AAAA,IACnB,CAAC,UAAU,WAAW,KAAK,KAAK,oBAAoB,OAAO,KAAK;AAAA,EAAA;AAElE,MAAI,MAAO,QAAO;AAClB,QAAM,kBAAkB,OAAO;AAAA,IAC7B,CAAC,UACC,WAAW,KAAK,KAChB,4BAA4B,OAAO,KAAK,KACxC,oBAAoB,OAAO,MAAM,OAAO;AAAA,EAAA;AAE5C,QAAM,mBAAmB,gBAAgB;AAAA,IACvC,CAAC,UAAU,MAAM,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM;AAAA,EAAA;AAEzD,QAAM,WACJ,iBAAiB,WAAW,KAAI,sBAAiB,CAAC,MAAlB,mBAAqB,WAAW;AAClE,QAAM,gBAAgB,WAClB,gBAAgB,OAAO,CAAC,UAAU,MAAM,aAAa,QAAQ,IAC7D;AACJ,SAAO,cAAc,WAAW,IAAI,cAAc,CAAC,IAAI;AACzD;AAEA,SAAS,4BACP,OACA,OACS;;AACT,SACG,MAAM,OAAO,WACX,MAAM,OAAO,MAAM,QAAM,WAAM,YAAN,mBAAe,QAAO,MAAM,OACvD,MAAM,UAAU,WACd,MAAM,OAAO,MAAM,WAAS,WAAM,YAAN,mBAAe,WAAU,MAAM;AAElE;AAGO,SAAS,oBACd,OACA,QACA,UACA,UACA,QACA,kBACG;;AACH,QAAM,UAAU,qBAAqB,UAAU,UAAU,MAAM;AAC/D,QAAM,OAAO,oBAAoB,UAAU,OAAO,EAAE;AACpD,MACE,aAAa,MAAM,WAAW,QAC7B,MAAM,SAAS,UAAa,SAAS,MAAM,OAC5C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,qBAAqB,QAAQ,KAAK;AACvD,QAAM,YACJ,kDAAc,YAAd,mBAAuB,UAAS,MAAM,UAAS,6CAAc,OAAM,MAAM;AAC3E,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA,WAAW,UAAU,QAAQ;AAAA,IAC7B;AAAA,EAAA;AAEF,MAAI,OAAO,oBAAoB,KAAK;AACpC,MAAI,WAAW;AACb,WAAO,2BAA2B,MAAM,WAAW,kBAAkB;AAAA,MACnE;AAAA,MACA;AAAA,IAAA,CACD;AAAA,EACH,OAAO;AACL,WAAO,EAAE,GAAG,MAAM,SAAS,KAAA;AAAA,EAC7B;AACA,SAAO,KAAK;AACZ,SAAO;AACT;AAEA,SAAS,oBAAmD,OAAa;AACvE,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,SAAO,KAAK;AACZ,SAAO,KAAK;AACZ,SAAO;AACT;"}
@@ -5,20 +5,23 @@ function effortOptionsForModel(model, fallbackEfforts) {
5
5
  if (!model.reasoning) return [];
6
6
  return [...model.supportedEfforts ?? []];
7
7
  }
8
- function reconcileModelCapabilities(value, model, fallbackEfforts) {
8
+ function reconcileModelCapabilities(value, model, fallbackEfforts, execution) {
9
9
  const next = { ...value };
10
10
  if (model == null ? void 0 : model.runtime) {
11
11
  delete next.model;
12
12
  delete next.id;
13
13
  delete next.backend;
14
- delete next.temperature;
15
- delete next.effort;
16
- delete next.noCache;
17
- delete next.fallbacks;
14
+ delete next.mode;
18
15
  Object.assign(next, model.runtime);
19
16
  } else if (model) {
20
17
  next.model = model.id;
21
18
  }
19
+ if (execution) {
20
+ if (execution.backend) next.backend = execution.backend;
21
+ else delete next.backend;
22
+ if (execution.mode) next.mode = execution.mode;
23
+ else delete next.mode;
24
+ }
22
25
  const efforts = effortOptionsForModel(model, fallbackEfforts);
23
26
  if ((model == null ? void 0 : model.capabilitiesKnown) && efforts.length === 0) {
24
27
  delete next.effort;
@@ -1 +1 @@
1
- {"version":3,"file":"model-capabilities.cjs","sources":["../../../src/data/runtime/model-capabilities.ts"],"sourcesContent":["import type { ChatModel, ChatModelRuntime } from \"../chat/types\";\n\n// A runtime control edits exactly the wire value a catalog row\n// carries (`reconcileModelCapabilities` copies one onto the other), so it stays\n// one declaration a field added to the catalog shape cannot drift out of the\n// editable shape.\nexport type ModelRuntimeSelection = ChatModelRuntime;\n\nexport function effortOptionsForModel(\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n): string[] {\n if (!model?.capabilitiesKnown) return [...fallbackEfforts];\n if (!model.reasoning) return [];\n return [...(model.supportedEfforts ?? [])];\n}\n\nexport function reconcileModelCapabilities<T extends ModelRuntimeSelection>(\n value: T,\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n): T {\n const next = { ...value } as ModelRuntimeSelection;\n if (model?.runtime) {\n delete next.model;\n delete next.id;\n delete next.backend;\n delete next.temperature;\n delete next.effort;\n delete next.noCache;\n delete next.fallbacks;\n Object.assign(next, model.runtime);\n } else if (model) {\n next.model = model.id;\n }\n\n const efforts = effortOptionsForModel(model, fallbackEfforts);\n if (model?.capabilitiesKnown && efforts.length === 0) {\n delete next.effort;\n } else if (\n efforts.length > 0 &&\n (!next.effort || !efforts.includes(next.effort))\n ) {\n const preferred = model?.defaultEffort;\n next.effort =\n preferred && efforts.includes(preferred)\n ? preferred\n : efforts.includes(\"medium\")\n ? \"medium\"\n : efforts[0]!;\n }\n\n if (model?.temperature === false) delete next.temperature;\n return next as T;\n}\n"],"names":[],"mappings":";;AAQO,SAAS,sBACd,OACA,iBACU;AACV,MAAI,EAAC,+BAAO,mBAAmB,QAAO,CAAC,GAAG,eAAe;AACzD,MAAI,CAAC,MAAM,UAAW,QAAO,CAAA;AAC7B,SAAO,CAAC,GAAI,MAAM,oBAAoB,EAAG;AAC3C;AAEO,SAAS,2BACd,OACA,OACA,iBACG;AACH,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,MAAI,+BAAO,SAAS;AAClB,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,OAAO,MAAM,MAAM,OAAO;AAAA,EACnC,WAAW,OAAO;AAChB,SAAK,QAAQ,MAAM;AAAA,EACrB;AAEA,QAAM,UAAU,sBAAsB,OAAO,eAAe;AAC5D,OAAI,+BAAO,sBAAqB,QAAQ,WAAW,GAAG;AACpD,WAAO,KAAK;AAAA,EACd,WACE,QAAQ,SAAS,MAChB,CAAC,KAAK,UAAU,CAAC,QAAQ,SAAS,KAAK,MAAM,IAC9C;AACA,UAAM,YAAY,+BAAO;AACzB,SAAK,SACH,aAAa,QAAQ,SAAS,SAAS,IACnC,YACA,QAAQ,SAAS,QAAQ,IACvB,WACF,QAAQ,CAAC;AAAA,EACjB;AAEA,OAAI,+BAAO,iBAAgB,MAAO,QAAO,KAAK;AAC9C,SAAO;AACT;;;"}
1
+ {"version":3,"file":"model-capabilities.cjs","sources":["../../../src/data/runtime/model-capabilities.ts"],"sourcesContent":["import type { ChatModel, ChatModelRuntime } from \"../chat/types\";\n\n// Runtime controls and catalog rows share one wire shape. Reconciliation copies\n// catalog identity while retaining user-owned runtime options that remain valid.\nexport type ModelRuntimeSelection = ChatModelRuntime;\n\n/** Lists the effort values accepted by the selected catalog model. */\nexport function effortOptionsForModel(\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n): string[] {\n if (!model?.capabilitiesKnown) return [...fallbackEfforts];\n if (!model.reasoning) return [];\n return [...(model.supportedEfforts ?? [])];\n}\n\n/** Applies catalog identity and capabilities under the caller's execution policy. */\nexport function reconcileModelCapabilities<T extends ModelRuntimeSelection>(\n value: T,\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n execution?: {\n backend: string | undefined;\n mode: string | undefined;\n },\n): T {\n const next = { ...value } as ModelRuntimeSelection;\n if (model?.runtime) {\n delete next.model;\n delete next.id;\n delete next.backend;\n delete next.mode;\n Object.assign(next, model.runtime);\n } else if (model) {\n next.model = model.id;\n }\n\n if (execution) {\n if (execution.backend) next.backend = execution.backend;\n else delete next.backend;\n if (execution.mode) next.mode = execution.mode;\n else delete next.mode;\n }\n\n const efforts = effortOptionsForModel(model, fallbackEfforts);\n if (model?.capabilitiesKnown && efforts.length === 0) {\n delete next.effort;\n } else if (\n efforts.length > 0 &&\n (!next.effort || !efforts.includes(next.effort))\n ) {\n const preferred = model?.defaultEffort;\n next.effort =\n preferred && efforts.includes(preferred)\n ? preferred\n : efforts.includes(\"medium\")\n ? \"medium\"\n : efforts[0]!;\n }\n\n if (model?.temperature === false) delete next.temperature;\n return next as T;\n}\n"],"names":[],"mappings":";;AAOO,SAAS,sBACd,OACA,iBACU;AACV,MAAI,EAAC,+BAAO,mBAAmB,QAAO,CAAC,GAAG,eAAe;AACzD,MAAI,CAAC,MAAM,UAAW,QAAO,CAAA;AAC7B,SAAO,CAAC,GAAI,MAAM,oBAAoB,EAAG;AAC3C;AAGO,SAAS,2BACd,OACA,OACA,iBACA,WAIG;AACH,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,MAAI,+BAAO,SAAS;AAClB,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,OAAO,MAAM,MAAM,OAAO;AAAA,EACnC,WAAW,OAAO;AAChB,SAAK,QAAQ,MAAM;AAAA,EACrB;AAEA,MAAI,WAAW;AACb,QAAI,UAAU,QAAS,MAAK,UAAU,UAAU;AAAA,gBACpC,KAAK;AACjB,QAAI,UAAU,KAAM,MAAK,OAAO,UAAU;AAAA,gBAC9B,KAAK;AAAA,EACnB;AAEA,QAAM,UAAU,sBAAsB,OAAO,eAAe;AAC5D,OAAI,+BAAO,sBAAqB,QAAQ,WAAW,GAAG;AACpD,WAAO,KAAK;AAAA,EACd,WACE,QAAQ,SAAS,MAChB,CAAC,KAAK,UAAU,CAAC,QAAQ,SAAS,KAAK,MAAM,IAC9C;AACA,UAAM,YAAY,+BAAO;AACzB,SAAK,SACH,aAAa,QAAQ,SAAS,SAAS,IACnC,YACA,QAAQ,SAAS,QAAQ,IACvB,WACF,QAAQ,CAAC;AAAA,EACjB;AAEA,OAAI,+BAAO,iBAAgB,MAAO,QAAO,KAAK;AAC9C,SAAO;AACT;;;"}
@@ -1,5 +1,10 @@
1
1
  import { ChatModel, ChatModelRuntime } from '../chat/types';
2
2
  export type ModelRuntimeSelection = ChatModelRuntime;
3
+ /** Lists the effort values accepted by the selected catalog model. */
3
4
  export declare function effortOptionsForModel(model: ChatModel | undefined, fallbackEfforts: readonly string[]): string[];
4
- export declare function reconcileModelCapabilities<T extends ModelRuntimeSelection>(value: T, model: ChatModel | undefined, fallbackEfforts: readonly string[]): T;
5
+ /** Applies catalog identity and capabilities under the caller's execution policy. */
6
+ export declare function reconcileModelCapabilities<T extends ModelRuntimeSelection>(value: T, model: ChatModel | undefined, fallbackEfforts: readonly string[], execution?: {
7
+ backend: string | undefined;
8
+ mode: string | undefined;
9
+ }): T;
5
10
  //# sourceMappingURL=model-capabilities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-capabilities.d.ts","sourceRoot":"","sources":["../../../src/data/runtime/model-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAMjE,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,CAAC;AAErD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,eAAe,EAAE,SAAS,MAAM,EAAE,GACjC,MAAM,EAAE,CAIV;AAED,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,qBAAqB,EACxE,KAAK,EAAE,CAAC,EACR,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,eAAe,EAAE,SAAS,MAAM,EAAE,GACjC,CAAC,CAiCH"}
1
+ {"version":3,"file":"model-capabilities.d.ts","sourceRoot":"","sources":["../../../src/data/runtime/model-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIjE,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,CAAC;AAErD,sEAAsE;AACtE,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,eAAe,EAAE,SAAS,MAAM,EAAE,GACjC,MAAM,EAAE,CAIV;AAED,qFAAqF;AACrF,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,qBAAqB,EACxE,KAAK,EAAE,CAAC,EACR,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,SAAS,CAAC,EAAE;IACV,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,GACA,CAAC,CAqCH"}
@@ -3,20 +3,23 @@ function effortOptionsForModel(model, fallbackEfforts) {
3
3
  if (!model.reasoning) return [];
4
4
  return [...model.supportedEfforts ?? []];
5
5
  }
6
- function reconcileModelCapabilities(value, model, fallbackEfforts) {
6
+ function reconcileModelCapabilities(value, model, fallbackEfforts, execution) {
7
7
  const next = { ...value };
8
8
  if (model == null ? void 0 : model.runtime) {
9
9
  delete next.model;
10
10
  delete next.id;
11
11
  delete next.backend;
12
- delete next.temperature;
13
- delete next.effort;
14
- delete next.noCache;
15
- delete next.fallbacks;
12
+ delete next.mode;
16
13
  Object.assign(next, model.runtime);
17
14
  } else if (model) {
18
15
  next.model = model.id;
19
16
  }
17
+ if (execution) {
18
+ if (execution.backend) next.backend = execution.backend;
19
+ else delete next.backend;
20
+ if (execution.mode) next.mode = execution.mode;
21
+ else delete next.mode;
22
+ }
20
23
  const efforts = effortOptionsForModel(model, fallbackEfforts);
21
24
  if ((model == null ? void 0 : model.capabilitiesKnown) && efforts.length === 0) {
22
25
  delete next.effort;
@@ -1 +1 @@
1
- {"version":3,"file":"model-capabilities.js","sources":["../../../src/data/runtime/model-capabilities.ts"],"sourcesContent":["import type { ChatModel, ChatModelRuntime } from \"../chat/types\";\n\n// A runtime control edits exactly the wire value a catalog row\n// carries (`reconcileModelCapabilities` copies one onto the other), so it stays\n// one declaration a field added to the catalog shape cannot drift out of the\n// editable shape.\nexport type ModelRuntimeSelection = ChatModelRuntime;\n\nexport function effortOptionsForModel(\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n): string[] {\n if (!model?.capabilitiesKnown) return [...fallbackEfforts];\n if (!model.reasoning) return [];\n return [...(model.supportedEfforts ?? [])];\n}\n\nexport function reconcileModelCapabilities<T extends ModelRuntimeSelection>(\n value: T,\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n): T {\n const next = { ...value } as ModelRuntimeSelection;\n if (model?.runtime) {\n delete next.model;\n delete next.id;\n delete next.backend;\n delete next.temperature;\n delete next.effort;\n delete next.noCache;\n delete next.fallbacks;\n Object.assign(next, model.runtime);\n } else if (model) {\n next.model = model.id;\n }\n\n const efforts = effortOptionsForModel(model, fallbackEfforts);\n if (model?.capabilitiesKnown && efforts.length === 0) {\n delete next.effort;\n } else if (\n efforts.length > 0 &&\n (!next.effort || !efforts.includes(next.effort))\n ) {\n const preferred = model?.defaultEffort;\n next.effort =\n preferred && efforts.includes(preferred)\n ? preferred\n : efforts.includes(\"medium\")\n ? \"medium\"\n : efforts[0]!;\n }\n\n if (model?.temperature === false) delete next.temperature;\n return next as T;\n}\n"],"names":[],"mappings":"AAQO,SAAS,sBACd,OACA,iBACU;AACV,MAAI,EAAC,+BAAO,mBAAmB,QAAO,CAAC,GAAG,eAAe;AACzD,MAAI,CAAC,MAAM,UAAW,QAAO,CAAA;AAC7B,SAAO,CAAC,GAAI,MAAM,oBAAoB,EAAG;AAC3C;AAEO,SAAS,2BACd,OACA,OACA,iBACG;AACH,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,MAAI,+BAAO,SAAS;AAClB,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,OAAO,MAAM,MAAM,OAAO;AAAA,EACnC,WAAW,OAAO;AAChB,SAAK,QAAQ,MAAM;AAAA,EACrB;AAEA,QAAM,UAAU,sBAAsB,OAAO,eAAe;AAC5D,OAAI,+BAAO,sBAAqB,QAAQ,WAAW,GAAG;AACpD,WAAO,KAAK;AAAA,EACd,WACE,QAAQ,SAAS,MAChB,CAAC,KAAK,UAAU,CAAC,QAAQ,SAAS,KAAK,MAAM,IAC9C;AACA,UAAM,YAAY,+BAAO;AACzB,SAAK,SACH,aAAa,QAAQ,SAAS,SAAS,IACnC,YACA,QAAQ,SAAS,QAAQ,IACvB,WACF,QAAQ,CAAC;AAAA,EACjB;AAEA,OAAI,+BAAO,iBAAgB,MAAO,QAAO,KAAK;AAC9C,SAAO;AACT;"}
1
+ {"version":3,"file":"model-capabilities.js","sources":["../../../src/data/runtime/model-capabilities.ts"],"sourcesContent":["import type { ChatModel, ChatModelRuntime } from \"../chat/types\";\n\n// Runtime controls and catalog rows share one wire shape. Reconciliation copies\n// catalog identity while retaining user-owned runtime options that remain valid.\nexport type ModelRuntimeSelection = ChatModelRuntime;\n\n/** Lists the effort values accepted by the selected catalog model. */\nexport function effortOptionsForModel(\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n): string[] {\n if (!model?.capabilitiesKnown) return [...fallbackEfforts];\n if (!model.reasoning) return [];\n return [...(model.supportedEfforts ?? [])];\n}\n\n/** Applies catalog identity and capabilities under the caller's execution policy. */\nexport function reconcileModelCapabilities<T extends ModelRuntimeSelection>(\n value: T,\n model: ChatModel | undefined,\n fallbackEfforts: readonly string[],\n execution?: {\n backend: string | undefined;\n mode: string | undefined;\n },\n): T {\n const next = { ...value } as ModelRuntimeSelection;\n if (model?.runtime) {\n delete next.model;\n delete next.id;\n delete next.backend;\n delete next.mode;\n Object.assign(next, model.runtime);\n } else if (model) {\n next.model = model.id;\n }\n\n if (execution) {\n if (execution.backend) next.backend = execution.backend;\n else delete next.backend;\n if (execution.mode) next.mode = execution.mode;\n else delete next.mode;\n }\n\n const efforts = effortOptionsForModel(model, fallbackEfforts);\n if (model?.capabilitiesKnown && efforts.length === 0) {\n delete next.effort;\n } else if (\n efforts.length > 0 &&\n (!next.effort || !efforts.includes(next.effort))\n ) {\n const preferred = model?.defaultEffort;\n next.effort =\n preferred && efforts.includes(preferred)\n ? preferred\n : efforts.includes(\"medium\")\n ? \"medium\"\n : efforts[0]!;\n }\n\n if (model?.temperature === false) delete next.temperature;\n return next as T;\n}\n"],"names":[],"mappings":"AAOO,SAAS,sBACd,OACA,iBACU;AACV,MAAI,EAAC,+BAAO,mBAAmB,QAAO,CAAC,GAAG,eAAe;AACzD,MAAI,CAAC,MAAM,UAAW,QAAO,CAAA;AAC7B,SAAO,CAAC,GAAI,MAAM,oBAAoB,EAAG;AAC3C;AAGO,SAAS,2BACd,OACA,OACA,iBACA,WAIG;AACH,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,MAAI,+BAAO,SAAS;AAClB,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,OAAO,MAAM,MAAM,OAAO;AAAA,EACnC,WAAW,OAAO;AAChB,SAAK,QAAQ,MAAM;AAAA,EACrB;AAEA,MAAI,WAAW;AACb,QAAI,UAAU,QAAS,MAAK,UAAU,UAAU;AAAA,gBACpC,KAAK;AACjB,QAAI,UAAU,KAAM,MAAK,OAAO,UAAU;AAAA,gBAC9B,KAAK;AAAA,EACnB;AAEA,QAAM,UAAU,sBAAsB,OAAO,eAAe;AAC5D,OAAI,+BAAO,sBAAqB,QAAQ,WAAW,GAAG;AACpD,WAAO,KAAK;AAAA,EACd,WACE,QAAQ,SAAS,MAChB,CAAC,KAAK,UAAU,CAAC,QAAQ,SAAS,KAAK,MAAM,IAC9C;AACA,UAAM,YAAY,+BAAO;AACzB,SAAK,SACH,aAAa,QAAQ,SAAS,SAAS,IACnC,YACA,QAAQ,SAAS,QAAQ,IACvB,WACF,QAAQ,CAAC;AAAA,EACjB;AAEA,OAAI,+BAAO,iBAAgB,MAAO,QAAO,KAAK;AAC9C,SAAO;AACT;"}
@@ -274,6 +274,21 @@ function modelBelongsToFamily(modelId, models, family, backend) {
274
274
  const providerMatches = !provider || selected.provider === provider;
275
275
  return providerMatches && modelMatchesBackend(selected, backend);
276
276
  }
277
+ function modelForFamily(modelId, models, family, backend) {
278
+ if (!modelId) return void 0;
279
+ const matches = modelsForFamily(models, family, backend).filter(
280
+ (model) => {
281
+ var _a, _b;
282
+ return model.id === modelId || ((_a = model.runtime) == null ? void 0 : _a.model) === modelId || ((_b = model.runtime) == null ? void 0 : _b.id) === modelId;
283
+ }
284
+ );
285
+ return matches.find(
286
+ (model) => {
287
+ var _a;
288
+ return !backend || !((_a = model.runtime) == null ? void 0 : _a.backend) || model.runtime.backend === backend;
289
+ }
290
+ ) ?? (matches.length === 1 ? matches[0] : void 0);
291
+ }
277
292
  function modelMatchesBackend(model, backend) {
278
293
  var _a;
279
294
  if (!backend) return true;
@@ -290,6 +305,8 @@ exports.firstMode = firstMode;
290
305
  exports.labelForBackend = labelForBackend;
291
306
  exports.modeForBackend = modeForBackend;
292
307
  exports.modelBelongsToFamily = modelBelongsToFamily;
308
+ exports.modelForFamily = modelForFamily;
309
+ exports.modelMatchesBackend = modelMatchesBackend;
293
310
  exports.modelsForFamily = modelsForFamily;
294
311
  exports.runtimeModeOptions = runtimeModeOptions;
295
312
  exports.selectionForBackend = selectionForBackend;