@trops/dash-core 0.1.611 → 0.1.612

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/index.esm.js CHANGED
@@ -52178,18 +52178,35 @@ var McpServerSection = function McpServerSection() {
52178
52178
  });
52179
52179
  };
52180
52180
 
52181
+ /**
52182
+ * modelMigration.js (renderer mirror)
52183
+ *
52184
+ * Mirrors the retired-model map + default from the main-process provider
52185
+ * registry (electron/llm/modelProviders.js) so the Settings UI can detect a
52186
+ * stale saved selection, auto-migrate it, and show a notice — without an IPC
52187
+ * round-trip. KEEP IN SYNC with modelProviders.js (anthropic provider).
52188
+ */
52189
+ var DEFAULT_MODEL = "claude-opus-4-8";
52190
+ var RETIRED_MODEL_MAP = {
52191
+ "claude-sonnet-4-20250514": "claude-sonnet-4-6",
52192
+ "claude-opus-4-20250514": "claude-opus-4-8",
52193
+ "claude-opus-4-1-20250805": "claude-opus-4-8",
52194
+ "claude-3-7-sonnet-20250219": "claude-sonnet-4-6",
52195
+ "claude-3-5-sonnet-20241022": "claude-sonnet-4-6",
52196
+ "claude-3-5-sonnet-20240620": "claude-sonnet-4-6",
52197
+ "claude-3-5-haiku-20241022": "claude-haiku-4-5",
52198
+ "claude-3-opus-20240229": "claude-opus-4-8"
52199
+ };
52200
+ function isRetiredModel(id) {
52201
+ return !!RETIRED_MODEL_MAP[id];
52202
+ }
52203
+ function migrateModelId(id) {
52204
+ if (!id) return DEFAULT_MODEL;
52205
+ return RETIRED_MODEL_MAP[id] || id;
52206
+ }
52207
+
52181
52208
  function ownKeys$m(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
52182
52209
  function _objectSpread$m(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$m(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$m(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
52183
- var MODELS = [{
52184
- value: "claude-sonnet-4-20250514",
52185
- label: "Claude Sonnet 4"
52186
- }, {
52187
- value: "claude-opus-4-20250514",
52188
- label: "Claude Opus 4"
52189
- }, {
52190
- value: "claude-haiku-4-5-20251001",
52191
- label: "Claude Haiku 4.5"
52192
- }];
52193
52210
  var BACKENDS = [{
52194
52211
  value: "claude-code",
52195
52212
  label: "Claude Code CLI"
@@ -52198,6 +52215,7 @@ var BACKENDS = [{
52198
52215
  label: "Anthropic API"
52199
52216
  }];
52200
52217
  var AiAssistantSection = function AiAssistantSection() {
52218
+ var _anthropicProvider$;
52201
52219
  var appContext = useContext(AppContext);
52202
52220
  var settings = (appContext === null || appContext === void 0 ? void 0 : appContext.settings) || {};
52203
52221
  var providers = (appContext === null || appContext === void 0 ? void 0 : appContext.providers) || {};
@@ -52215,7 +52233,7 @@ var AiAssistantSection = function AiAssistantSection() {
52215
52233
  _useState4 = _slicedToArray(_useState3, 2),
52216
52234
  preferredBackend = _useState4[0],
52217
52235
  setPreferredBackend = _useState4[1];
52218
- var _useState5 = useState(aiSettings.model || "claude-sonnet-4-20250514"),
52236
+ var _useState5 = useState(aiSettings.model || DEFAULT_MODEL),
52219
52237
  _useState6 = _slicedToArray(_useState5, 2),
52220
52238
  selectedModel = _useState6[0],
52221
52239
  setSelectedModel = _useState6[1];
@@ -52232,6 +52250,21 @@ var AiAssistantSection = function AiAssistantSection() {
52232
52250
  saveKeyStatus = _useState10[0],
52233
52251
  setSaveKeyStatus = _useState10[1];
52234
52252
 
52253
+ // Provider-pluggable model discovery (live fetch + curated fallback)
52254
+ var _useState11 = useState([]),
52255
+ _useState12 = _slicedToArray(_useState11, 2),
52256
+ availableModels = _useState12[0],
52257
+ setAvailableModels = _useState12[1];
52258
+ var _useState13 = useState(false),
52259
+ _useState14 = _slicedToArray(_useState13, 2),
52260
+ modelsLoading = _useState14[0],
52261
+ setModelsLoading = _useState14[1];
52262
+ // One-time notice when a retired saved model was auto-migrated
52263
+ var _useState15 = useState(null),
52264
+ _useState16 = _slicedToArray(_useState15, 2),
52265
+ migrationNotice = _useState16[0],
52266
+ setMigrationNotice = _useState16[1];
52267
+
52235
52268
  // Find existing Anthropic provider
52236
52269
  var anthropicProvider = Object.entries(providers).find(function (_ref) {
52237
52270
  var _ref2 = _slicedToArray(_ref, 2),
@@ -52240,6 +52273,9 @@ var AiAssistantSection = function AiAssistantSection() {
52240
52273
  });
52241
52274
  var hasAnthropicProvider = !!anthropicProvider;
52242
52275
  var anthropicProviderName = anthropicProvider === null || anthropicProvider === void 0 ? void 0 : anthropicProvider[0];
52276
+ // Decrypted key (when AppContext exposes it) enables the live Models API
52277
+ // fetch; without it, listModels returns the curated fallback list.
52278
+ var anthropicApiKey = (anthropicProvider === null || anthropicProvider === void 0 || (_anthropicProvider$ = anthropicProvider[1]) === null || _anthropicProvider$ === void 0 || (_anthropicProvider$ = _anthropicProvider$.credentials) === null || _anthropicProvider$ === void 0 ? void 0 : _anthropicProvider$.apiKey) || null;
52243
52279
 
52244
52280
  // Check CLI availability on mount
52245
52281
  useEffect(function () {
@@ -52261,6 +52297,28 @@ var AiAssistantSection = function AiAssistantSection() {
52261
52297
  }
52262
52298
  }, []);
52263
52299
 
52300
+ // Fetch selectable models for the current provider. With an API key the
52301
+ // main process does a live Anthropic Models API fetch; otherwise it returns
52302
+ // the curated fallback. Provider is "anthropic" for both current backends.
52303
+ var fetchModels = useCallback(function () {
52304
+ var _window$mainApi2;
52305
+ if (!((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && (_window$mainApi2 = _window$mainApi2.llm) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.listModels)) return;
52306
+ setModelsLoading(true);
52307
+ window.mainApi.llm.listModels("anthropic", anthropicApiKey).then(function (res) {
52308
+ return setAvailableModels(res && res.models || []);
52309
+ })["catch"](function () {
52310
+ return setAvailableModels([]);
52311
+ })["finally"](function () {
52312
+ return setModelsLoading(false);
52313
+ });
52314
+ }, [anthropicApiKey]);
52315
+
52316
+ // Load models on mount and whenever the available API key changes (so the
52317
+ // list upgrades from curated → live once a key is configured).
52318
+ useEffect(function () {
52319
+ fetchModels();
52320
+ }, [fetchModels]);
52321
+
52264
52322
  // Save AI settings to app settings
52265
52323
  var saveAiSettings = useCallback(function (updates) {
52266
52324
  if (appContext !== null && appContext !== void 0 && appContext.changeSettings) {
@@ -52271,6 +52329,24 @@ var AiAssistantSection = function AiAssistantSection() {
52271
52329
  }));
52272
52330
  }
52273
52331
  }, [appContext]);
52332
+
52333
+ // Auto-migrate a retired saved model to its current replacement (one-time,
52334
+ // on mount) so an old selection can't 404 the assistant. Shows a notice.
52335
+ useEffect(function () {
52336
+ var saved = aiSettings.model;
52337
+ if (saved && isRetiredModel(saved)) {
52338
+ var replacement = migrateModelId(saved);
52339
+ setSelectedModel(replacement);
52340
+ saveAiSettings({
52341
+ model: replacement
52342
+ });
52343
+ setMigrationNotice({
52344
+ from: saved,
52345
+ to: replacement
52346
+ });
52347
+ }
52348
+ // eslint-disable-next-line react-hooks/exhaustive-deps
52349
+ }, []);
52274
52350
  function handleBackendChange(e) {
52275
52351
  var value = e.target.value;
52276
52352
  setPreferredBackend(value);
@@ -52314,6 +52390,15 @@ var AiAssistantSection = function AiAssistantSection() {
52314
52390
  });
52315
52391
  }
52316
52392
 
52393
+ // Model dropdown options — keep the current selection selectable even if it
52394
+ // isn't in the fetched list (e.g. a pinned/custom id).
52395
+ var modelOptions = selectedModel && !availableModels.some(function (m) {
52396
+ return m.value === selectedModel;
52397
+ }) ? [{
52398
+ value: selectedModel,
52399
+ label: selectedModel
52400
+ }].concat(_toConsumableArray(availableModels)) : availableModels;
52401
+
52317
52402
  // Determine effective backend (what will actually be used)
52318
52403
  var effectiveBackend = preferredBackend === "claude-code" && cliStatus !== null && cliStatus !== void 0 && cliStatus.available ? "claude-code" : preferredBackend === "anthropic" && hasAnthropicProvider ? "anthropic" : cliStatus !== null && cliStatus !== void 0 && cliStatus.available ? "claude-code" : hasAnthropicProvider ? "anthropic" : null;
52319
52404
  return /*#__PURE__*/jsxs("div", {
@@ -52410,6 +52495,18 @@ var AiAssistantSection = function AiAssistantSection() {
52410
52495
  }, b.value);
52411
52496
  })
52412
52497
  })]
52498
+ }), migrationNotice && /*#__PURE__*/jsxs("div", {
52499
+ className: "flex items-start gap-2 rounded-lg bg-yellow-900/30 border border-yellow-700 px-3 py-2 text-xs text-yellow-300",
52500
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
52501
+ icon: "exclamation-triangle",
52502
+ className: "h-3.5 w-3.5 mt-0.5"
52503
+ }), /*#__PURE__*/jsxs("span", {
52504
+ children: ["Your previously selected model (", /*#__PURE__*/jsx("code", {
52505
+ children: migrationNotice.from
52506
+ }), ") is no longer available. Switched to ", /*#__PURE__*/jsx("code", {
52507
+ children: migrationNotice.to
52508
+ }), "."]
52509
+ })]
52413
52510
  }), /*#__PURE__*/jsxs("div", {
52414
52511
  className: "flex flex-row items-center justify-between py-1",
52415
52512
  children: [/*#__PURE__*/jsxs("div", {
@@ -52419,18 +52516,31 @@ var AiAssistantSection = function AiAssistantSection() {
52419
52516
  children: "Model"
52420
52517
  }), /*#__PURE__*/jsx("span", {
52421
52518
  className: "text-xs opacity-50",
52422
- children: "Claude model for AI Assistant conversations"
52519
+ children: "Model for AI Assistant conversations"
52520
+ })]
52521
+ }), /*#__PURE__*/jsxs("div", {
52522
+ className: "flex items-center gap-2",
52523
+ children: [/*#__PURE__*/jsx("select", {
52524
+ value: selectedModel,
52525
+ onChange: handleModelChange,
52526
+ className: "bg-white/10 border border-white/10 rounded-md px-3 py-1.5 text-sm text-gray-200 focus:outline-none focus:ring-1 focus:ring-blue-500",
52527
+ children: modelOptions.map(function (m) {
52528
+ return /*#__PURE__*/jsx("option", {
52529
+ value: m.value,
52530
+ children: m.label
52531
+ }, m.value);
52532
+ })
52533
+ }), /*#__PURE__*/jsx("button", {
52534
+ type: "button",
52535
+ onClick: fetchModels,
52536
+ disabled: modelsLoading,
52537
+ title: "Refresh available models",
52538
+ className: "text-gray-400 hover:text-gray-200 disabled:opacity-40 transition-colors p-1.5",
52539
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
52540
+ icon: "rotate",
52541
+ className: "h-3.5 w-3.5 ".concat(modelsLoading ? "animate-spin" : "")
52542
+ })
52423
52543
  })]
52424
- }), /*#__PURE__*/jsx("select", {
52425
- value: selectedModel,
52426
- onChange: handleModelChange,
52427
- className: "bg-white/10 border border-white/10 rounded-md px-3 py-1.5 text-sm text-gray-200 focus:outline-none focus:ring-1 focus:ring-blue-500",
52428
- children: MODELS.map(function (m) {
52429
- return /*#__PURE__*/jsx("option", {
52430
- value: m.value,
52431
- children: m.label
52432
- }, m.value);
52433
- })
52434
52544
  })]
52435
52545
  })]
52436
52546
  }), !hasAnthropicProvider && /*#__PURE__*/jsxs("div", {