@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.
@@ -26,12 +26,12 @@ var require$$1$5 = require('http');
26
26
  var require$$2$2 = require('algoliasearch');
27
27
  var require$$3$2 = require('node:path');
28
28
  var require$$0$9 = require('openai');
29
- var require$$0$b = require('@anthropic-ai/sdk');
29
+ var require$$0$a = require('@anthropic-ai/sdk');
30
30
  var require$$2$3 = require('zod-to-json-schema');
31
31
  var require$$8$1 = require('zod');
32
32
  var require$$1$7 = require('http2');
33
33
  var require$$2$4 = require('node-forge');
34
- var require$$0$a = require('css');
34
+ var require$$0$b = require('css');
35
35
  var require$$1$8 = require('node-vibrant/node');
36
36
  var require$$3$3 = require('ws');
37
37
 
@@ -589,6 +589,7 @@ const LLM_CHECK_CLI_AVAILABLE$1 = "llm-check-cli-available";
589
589
  const LLM_CLEAR_CLI_SESSION$1 = "llm-clear-cli-session";
590
590
  const LLM_CLI_SESSION_STATUS$1 = "llm-cli-session-status";
591
591
  const LLM_CLI_END_SESSION$1 = "llm-cli-end-session";
592
+ const LLM_LIST_MODELS$1 = "llm-list-models";
592
593
 
593
594
  // --- Main → Renderer (send) ---
594
595
  const LLM_STREAM_DELTA$3 = "llm-stream-delta";
@@ -610,6 +611,7 @@ var llmEvents$1 = {
610
611
  LLM_STREAM_ERROR: LLM_STREAM_ERROR$3,
611
612
  LLM_CLI_SESSION_STATUS: LLM_CLI_SESSION_STATUS$1,
612
613
  LLM_CLI_END_SESSION: LLM_CLI_END_SESSION$1,
614
+ LLM_LIST_MODELS: LLM_LIST_MODELS$1,
613
615
  };
614
616
 
615
617
  /**
@@ -40467,6 +40469,130 @@ var menuItemsController_1 = menuItemsController$1;
40467
40469
 
40468
40470
  var cliController$3 = {exports: {}};
40469
40471
 
40472
+ /**
40473
+ * modelProviders.js
40474
+ *
40475
+ * Provider-pluggable registry for discovering and validating LLM models.
40476
+ *
40477
+ * Each provider knows how to:
40478
+ * - list its currently-available models (live, when credentials allow)
40479
+ * - fall back to a curated list (offline / no key / no live API)
40480
+ * - migrate retired model IDs to a current replacement
40481
+ * - name its default model
40482
+ *
40483
+ * Today only `anthropic` is implemented. Adding a vendor (OpenAI, Google, …)
40484
+ * is a single new entry in PROVIDERS — the dispatchers below, the
40485
+ * LLM_LIST_MODELS IPC, and the Settings UI need no changes.
40486
+ *
40487
+ * NOTE: the renderer mirrors the retired map + default for the auto-migrate
40488
+ * notice (src/utils/modelMigration.js). Keep the two in sync.
40489
+ */
40490
+
40491
+ const Anthropic$1 = require$$0$a;
40492
+
40493
+ const PROVIDERS = {
40494
+ anthropic: {
40495
+ id: "anthropic",
40496
+ label: "Anthropic",
40497
+ defaultModel: "claude-opus-4-8",
40498
+ // Curated fallback — current, non-deprecated IDs. Used for the Claude
40499
+ // Code CLI backend (which has no Models API) and whenever a live fetch
40500
+ // can't run (no API key, offline, error).
40501
+ curatedModels: [
40502
+ { value: "claude-opus-4-8", label: "Claude Opus 4.8" },
40503
+ { value: "claude-opus-4-7", label: "Claude Opus 4.7" },
40504
+ { value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
40505
+ { value: "claude-haiku-4-5", label: "Claude Haiku 4.5" },
40506
+ { value: "claude-fable-5", label: "Claude Fable 5" },
40507
+ ],
40508
+ // Retired/deprecated IDs → current replacement. Lets a stale saved
40509
+ // selection self-heal instead of 404-ing at call time.
40510
+ retiredMap: {
40511
+ "claude-sonnet-4-20250514": "claude-sonnet-4-6",
40512
+ "claude-opus-4-20250514": "claude-opus-4-8",
40513
+ "claude-opus-4-1-20250805": "claude-opus-4-8",
40514
+ "claude-3-7-sonnet-20250219": "claude-sonnet-4-6",
40515
+ "claude-3-5-sonnet-20241022": "claude-sonnet-4-6",
40516
+ "claude-3-5-sonnet-20240620": "claude-sonnet-4-6",
40517
+ "claude-3-5-haiku-20241022": "claude-haiku-4-5",
40518
+ "claude-3-opus-20240229": "claude-opus-4-8",
40519
+ },
40520
+ async listModels({ apiKey } = {}) {
40521
+ const client = new Anthropic$1({ apiKey });
40522
+ const res = await client.models.list();
40523
+ return (res.data || []).map((m) => ({
40524
+ value: m.id,
40525
+ label: m.display_name || m.id,
40526
+ }));
40527
+ },
40528
+ },
40529
+ };
40530
+
40531
+ const DEFAULT_PROVIDER = "anthropic";
40532
+
40533
+ function getProvider$1(providerId) {
40534
+ return PROVIDERS[providerId] || PROVIDERS[DEFAULT_PROVIDER];
40535
+ }
40536
+
40537
+ function getCuratedModels(providerId) {
40538
+ return getProvider$1(providerId).curatedModels.slice();
40539
+ }
40540
+
40541
+ function getDefaultModel(providerId) {
40542
+ return getProvider$1(providerId).defaultModel;
40543
+ }
40544
+
40545
+ /**
40546
+ * Map a retired/deprecated model id to its current replacement. Returns the
40547
+ * provider default for a falsy id, and passes through anything not in the
40548
+ * retired map (live/curated ids are returned unchanged).
40549
+ */
40550
+ function migrateModelId$2(providerId, id) {
40551
+ if (!id) return getDefaultModel(providerId);
40552
+ const map = getProvider$1(providerId).retiredMap || {};
40553
+ return map[id] || id;
40554
+ }
40555
+
40556
+ function isKnownRetired(providerId, id) {
40557
+ const map = getProvider$1(providerId).retiredMap || {};
40558
+ return !!map[id];
40559
+ }
40560
+
40561
+ /**
40562
+ * List models for a provider. Attempts a live fetch when the provider
40563
+ * supports it and credentials are present; otherwise returns the curated
40564
+ * fallback. Never throws — always resolves to a usable list.
40565
+ *
40566
+ * @returns {Promise<{ models: Array<{value,label}>, source: "live"|"curated" }>}
40567
+ */
40568
+ async function listModels(providerId, creds = {}) {
40569
+ const provider = getProvider$1(providerId);
40570
+ if (provider.listModels && creds && creds.apiKey) {
40571
+ try {
40572
+ const models = await provider.listModels(creds);
40573
+ if (Array.isArray(models) && models.length > 0) {
40574
+ return { models, source: "live" };
40575
+ }
40576
+ } catch (e) {
40577
+ console.warn(
40578
+ `[modelProviders] live model fetch failed for ${provider.id}: ${e.message}`,
40579
+ );
40580
+ }
40581
+ }
40582
+ return { models: provider.curatedModels.slice(), source: "curated" };
40583
+ }
40584
+
40585
+ var modelProviders = {
40586
+ PROVIDERS,
40587
+ DEFAULT_PROVIDER,
40588
+ getProvider: getProvider$1,
40589
+ getCuratedModels,
40590
+ getDefaultModel,
40591
+ migrateModelId: migrateModelId$2,
40592
+ isKnownRetired,
40593
+ listModels,
40594
+ };
40595
+
40470
40596
  var mcp = {};
40471
40597
 
40472
40598
  var server$1 = {};
@@ -59318,6 +59444,7 @@ const {
59318
59444
  LLM_STREAM_COMPLETE: LLM_STREAM_COMPLETE$2,
59319
59445
  LLM_STREAM_ERROR: LLM_STREAM_ERROR$2,
59320
59446
  } = llmEvents$1;
59447
+ const { migrateModelId: migrateModelId$1 } = modelProviders;
59321
59448
 
59322
59449
  const IS_WINDOWS = process.platform === "win32";
59323
59450
 
@@ -59573,8 +59700,11 @@ const cliController$2 = {
59573
59700
  // buildClaudeCliArgs; below we only add args that depend on
59574
59701
  // runtime state (MCP config file paths) the helper can't know.
59575
59702
  const sessionIdForResume = widgetUuid ? sessions.get(widgetUuid) : null;
59703
+ // Heal a retired/stale saved model id before passing --model. Leave an
59704
+ // unset model alone so the CLI keeps its own default when none was chosen.
59705
+ const resolvedModel = model ? migrateModelId$1("anthropic", model) : model;
59576
59706
  const args = buildClaudeCliArgs({
59577
- model,
59707
+ model: resolvedModel,
59578
59708
  systemPrompt,
59579
59709
  sessionId: sessionIdForResume,
59580
59710
  replaceSystemPrompt,
@@ -60680,7 +60810,7 @@ var themeFromUrlErrors$1 = {
60680
60810
  * computed styles, and favicon/logo images (via node-vibrant).
60681
60811
  */
60682
60812
 
60683
- const css = require$$0$a;
60813
+ const css = require$$0$b;
60684
60814
  const { Vibrant } = require$$1$8;
60685
60815
  const https = require$$11;
60686
60816
  const http = require$$1$5;
@@ -65531,9 +65661,13 @@ var toolHandlers$1 = {
65531
65661
  * per-request, receiving the full messages array each time.
65532
65662
  */
65533
65663
 
65534
- const Anthropic = require$$0$b;
65664
+ const Anthropic = require$$0$a;
65535
65665
  const mcpController$2 = mcpControllerExports;
65536
65666
  const cliController$1 = cliControllerExports;
65667
+ const {
65668
+ listModels: listProviderModels,
65669
+ migrateModelId,
65670
+ } = modelProviders;
65537
65671
  const toolDefinitions = toolDefinitions$1;
65538
65672
  const toolHandlers = toolHandlers$1;
65539
65673
  const {
@@ -65674,7 +65808,6 @@ const llmController$1 = {
65674
65808
 
65675
65809
  const {
65676
65810
  apiKey,
65677
- model = "claude-sonnet-4-20250514",
65678
65811
  messages,
65679
65812
  tools = [],
65680
65813
  toolServerMap = {},
@@ -65682,6 +65815,10 @@ const llmController$1 = {
65682
65815
  maxToolRounds = DEFAULT_MAX_TOOL_ROUNDS,
65683
65816
  } = params;
65684
65817
 
65818
+ // Heal a retired/stale saved model id (and fill the provider default when
65819
+ // none was supplied) so a stored selection can't 404 the request.
65820
+ const model = migrateModelId("anthropic", params.model);
65821
+
65685
65822
  // Set up abort controller
65686
65823
  const abortController = new AbortController();
65687
65824
  activeRequests.set(requestId, abortController);
@@ -65931,6 +66068,22 @@ const llmController$1 = {
65931
66068
  // Fallback to CLI controller
65932
66069
  return cliController$1.abortRequest(requestId);
65933
66070
  },
66071
+
66072
+ /**
66073
+ * listModels
66074
+ * Discover selectable models for a provider. Attempts a live fetch via the
66075
+ * provider's API (e.g. Anthropic Models API) when an apiKey is supplied;
66076
+ * otherwise returns the provider's curated fallback list. Provider-pluggable
66077
+ * — adding OpenAI/Google later is a new entry in modelProviders.js.
66078
+ *
66079
+ * @param {BrowserWindow} win - unused (API consistency)
66080
+ * @param {string} providerId - vendor id, e.g. "anthropic"
66081
+ * @param {string|null} apiKey - decrypted key for the live fetch (optional)
66082
+ * @returns {Promise<{ models, source }>}
66083
+ */
66084
+ listModels: async (win, providerId, apiKey) => {
66085
+ return listProviderModels(providerId || "anthropic", { apiKey });
66086
+ },
65934
66087
  };
65935
66088
 
65936
66089
  var llmController_1 = llmController$1;
@@ -76088,6 +76241,7 @@ const {
76088
76241
  LLM_CLEAR_CLI_SESSION,
76089
76242
  LLM_CLI_SESSION_STATUS,
76090
76243
  LLM_CLI_END_SESSION,
76244
+ LLM_LIST_MODELS,
76091
76245
  LLM_STREAM_DELTA,
76092
76246
  LLM_STREAM_TOOL_CALL,
76093
76247
  LLM_STREAM_TOOL_RESULT,
@@ -76144,6 +76298,19 @@ const llmApi$2 = {
76144
76298
  */
76145
76299
  checkCliAvailable: () => ipcRenderer$d.invoke(LLM_CHECK_CLI_AVAILABLE),
76146
76300
 
76301
+ /**
76302
+ * listModels
76303
+ * Discover selectable models for a provider. With an apiKey, the main
76304
+ * process attempts a live fetch (e.g. Anthropic Models API); otherwise it
76305
+ * returns the provider's curated fallback list.
76306
+ *
76307
+ * @param {string} providerId - vendor id, e.g. "anthropic"
76308
+ * @param {string|null} apiKey - decrypted key for the live fetch (optional)
76309
+ * @returns {Promise<{ models, source }>}
76310
+ */
76311
+ listModels: (providerId, apiKey = null) =>
76312
+ ipcRenderer$d.invoke(LLM_LIST_MODELS, { providerId, apiKey }),
76313
+
76147
76314
  /**
76148
76315
  * clearCliSession
76149
76316
  * Clear the CLI conversation session for a widget (for "New Chat").