@trops/dash-core 0.1.611 → 0.1.613
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/electron/index.js +173 -6
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +195 -23
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +195 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -46033,6 +46033,55 @@ var NewProviderPicker = function NewProviderPicker(_ref2) {
|
|
|
46033
46033
|
});
|
|
46034
46034
|
};
|
|
46035
46035
|
|
|
46036
|
+
/**
|
|
46037
|
+
* providerType.js
|
|
46038
|
+
*
|
|
46039
|
+
* Helpers for assigning a stable, UNIQUE `type` to a provider.
|
|
46040
|
+
*
|
|
46041
|
+
* A provider's identity in the widget system is its `type` string (widgets
|
|
46042
|
+
* declare `requiredProviders: [{ type }]`, runtime resolves by type). Catalog
|
|
46043
|
+
* providers each carry a unique type (`slack`, `github`, …). Hand-rolled
|
|
46044
|
+
* custom MCP servers historically all shared `type: "custom"`, which conflates
|
|
46045
|
+
* multiple customs at binding/runtime. These helpers give each NEW custom
|
|
46046
|
+
* provider a unique slug derived from its name so it behaves like a catalog
|
|
46047
|
+
* provider.
|
|
46048
|
+
*
|
|
46049
|
+
* Forward-only: existing providers are never renamed here (that would break
|
|
46050
|
+
* widgets already built against their type). Only the create path uses this.
|
|
46051
|
+
*/
|
|
46052
|
+
|
|
46053
|
+
/**
|
|
46054
|
+
* Convert a provider name into a kebab-case type slug.
|
|
46055
|
+
* "My Granola Server" → "my-granola-server". Falls back to a sane default
|
|
46056
|
+
* when the name has no slug-able characters.
|
|
46057
|
+
*/
|
|
46058
|
+
function slugifyProviderType(name) {
|
|
46059
|
+
var slug = String(name || "").toLowerCase().trim().replace(/[^\w\s-]/g, "") // drop punctuation/symbols
|
|
46060
|
+
.replace(/[\s_]+/g, "-") // whitespace/underscores → hyphen
|
|
46061
|
+
.replace(/-+/g, "-") // collapse repeats
|
|
46062
|
+
.replace(/^-+|-+$/g, ""); // trim hyphens
|
|
46063
|
+
return slug || "custom-provider";
|
|
46064
|
+
}
|
|
46065
|
+
|
|
46066
|
+
/**
|
|
46067
|
+
* Produce a slug type unique against the already-configured provider types.
|
|
46068
|
+
* Appends `-2`, `-3`, … on collision so two providers can never share a type.
|
|
46069
|
+
*
|
|
46070
|
+
* @param {string} name provider instance name
|
|
46071
|
+
* @param {Iterable<string>} existingTypes types already in use (e.g.
|
|
46072
|
+
* Object.values(providers).map(p => p.type))
|
|
46073
|
+
* @returns {string}
|
|
46074
|
+
*/
|
|
46075
|
+
function uniqueProviderType(name) {
|
|
46076
|
+
var existingTypes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
46077
|
+
var base = slugifyProviderType(name);
|
|
46078
|
+
var taken = new Set(existingTypes || []);
|
|
46079
|
+
if (!taken.has(base)) return base;
|
|
46080
|
+
var i = 2;
|
|
46081
|
+
while (taken.has("".concat(base, "-").concat(i))) i++;
|
|
46082
|
+
return "".concat(base, "-").concat(i);
|
|
46083
|
+
}
|
|
46084
|
+
|
|
46036
46085
|
var ProvidersSection = function ProvidersSection(_ref) {
|
|
46037
46086
|
var _ref$dashApi = _ref.dashApi,
|
|
46038
46087
|
dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
|
|
@@ -46257,8 +46306,21 @@ var ProvidersSection = function ProvidersSection(_ref) {
|
|
|
46257
46306
|
function handleMcpSave(providerName, providerType, mcpCredentials, mcpConfig) {
|
|
46258
46307
|
var allowedTools = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
46259
46308
|
if (!dashApi || !appId) return;
|
|
46309
|
+
// Forward-only unique types: a hand-rolled custom MCP server arrives with
|
|
46310
|
+
// the generic default type "custom", which conflates multiple customs at
|
|
46311
|
+
// widget-binding/runtime time. Give each NEW one a unique slug so it has a
|
|
46312
|
+
// distinct identity like catalog providers. Catalog installs pass a real
|
|
46313
|
+
// id (not "custom") and are untouched; the edit path preserves type, so no
|
|
46314
|
+
// existing provider is ever renamed.
|
|
46315
|
+
var resolvedType = providerType;
|
|
46316
|
+
if (resolvedType === "custom") {
|
|
46317
|
+
var existingTypes = Object.values(providers || {}).map(function (p) {
|
|
46318
|
+
return p.type;
|
|
46319
|
+
});
|
|
46320
|
+
resolvedType = uniqueProviderType(providerName, existingTypes);
|
|
46321
|
+
}
|
|
46260
46322
|
dashApi.saveProvider(appId, providerName, {
|
|
46261
|
-
providerType:
|
|
46323
|
+
providerType: resolvedType,
|
|
46262
46324
|
credentials: mcpCredentials,
|
|
46263
46325
|
providerClass: "mcp",
|
|
46264
46326
|
mcpConfig: mcpConfig,
|
|
@@ -52178,18 +52240,35 @@ var McpServerSection = function McpServerSection() {
|
|
|
52178
52240
|
});
|
|
52179
52241
|
};
|
|
52180
52242
|
|
|
52243
|
+
/**
|
|
52244
|
+
* modelMigration.js (renderer mirror)
|
|
52245
|
+
*
|
|
52246
|
+
* Mirrors the retired-model map + default from the main-process provider
|
|
52247
|
+
* registry (electron/llm/modelProviders.js) so the Settings UI can detect a
|
|
52248
|
+
* stale saved selection, auto-migrate it, and show a notice — without an IPC
|
|
52249
|
+
* round-trip. KEEP IN SYNC with modelProviders.js (anthropic provider).
|
|
52250
|
+
*/
|
|
52251
|
+
var DEFAULT_MODEL = "claude-opus-4-8";
|
|
52252
|
+
var RETIRED_MODEL_MAP = {
|
|
52253
|
+
"claude-sonnet-4-20250514": "claude-sonnet-4-6",
|
|
52254
|
+
"claude-opus-4-20250514": "claude-opus-4-8",
|
|
52255
|
+
"claude-opus-4-1-20250805": "claude-opus-4-8",
|
|
52256
|
+
"claude-3-7-sonnet-20250219": "claude-sonnet-4-6",
|
|
52257
|
+
"claude-3-5-sonnet-20241022": "claude-sonnet-4-6",
|
|
52258
|
+
"claude-3-5-sonnet-20240620": "claude-sonnet-4-6",
|
|
52259
|
+
"claude-3-5-haiku-20241022": "claude-haiku-4-5",
|
|
52260
|
+
"claude-3-opus-20240229": "claude-opus-4-8"
|
|
52261
|
+
};
|
|
52262
|
+
function isRetiredModel(id) {
|
|
52263
|
+
return !!RETIRED_MODEL_MAP[id];
|
|
52264
|
+
}
|
|
52265
|
+
function migrateModelId(id) {
|
|
52266
|
+
if (!id) return DEFAULT_MODEL;
|
|
52267
|
+
return RETIRED_MODEL_MAP[id] || id;
|
|
52268
|
+
}
|
|
52269
|
+
|
|
52181
52270
|
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
52271
|
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
52272
|
var BACKENDS = [{
|
|
52194
52273
|
value: "claude-code",
|
|
52195
52274
|
label: "Claude Code CLI"
|
|
@@ -52198,6 +52277,7 @@ var BACKENDS = [{
|
|
|
52198
52277
|
label: "Anthropic API"
|
|
52199
52278
|
}];
|
|
52200
52279
|
var AiAssistantSection = function AiAssistantSection() {
|
|
52280
|
+
var _anthropicProvider$;
|
|
52201
52281
|
var appContext = useContext(AppContext);
|
|
52202
52282
|
var settings = (appContext === null || appContext === void 0 ? void 0 : appContext.settings) || {};
|
|
52203
52283
|
var providers = (appContext === null || appContext === void 0 ? void 0 : appContext.providers) || {};
|
|
@@ -52215,7 +52295,7 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52215
52295
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
52216
52296
|
preferredBackend = _useState4[0],
|
|
52217
52297
|
setPreferredBackend = _useState4[1];
|
|
52218
|
-
var _useState5 = useState(aiSettings.model ||
|
|
52298
|
+
var _useState5 = useState(aiSettings.model || DEFAULT_MODEL),
|
|
52219
52299
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
52220
52300
|
selectedModel = _useState6[0],
|
|
52221
52301
|
setSelectedModel = _useState6[1];
|
|
@@ -52232,6 +52312,21 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52232
52312
|
saveKeyStatus = _useState10[0],
|
|
52233
52313
|
setSaveKeyStatus = _useState10[1];
|
|
52234
52314
|
|
|
52315
|
+
// Provider-pluggable model discovery (live fetch + curated fallback)
|
|
52316
|
+
var _useState11 = useState([]),
|
|
52317
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
52318
|
+
availableModels = _useState12[0],
|
|
52319
|
+
setAvailableModels = _useState12[1];
|
|
52320
|
+
var _useState13 = useState(false),
|
|
52321
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
52322
|
+
modelsLoading = _useState14[0],
|
|
52323
|
+
setModelsLoading = _useState14[1];
|
|
52324
|
+
// One-time notice when a retired saved model was auto-migrated
|
|
52325
|
+
var _useState15 = useState(null),
|
|
52326
|
+
_useState16 = _slicedToArray(_useState15, 2),
|
|
52327
|
+
migrationNotice = _useState16[0],
|
|
52328
|
+
setMigrationNotice = _useState16[1];
|
|
52329
|
+
|
|
52235
52330
|
// Find existing Anthropic provider
|
|
52236
52331
|
var anthropicProvider = Object.entries(providers).find(function (_ref) {
|
|
52237
52332
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
@@ -52240,6 +52335,9 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52240
52335
|
});
|
|
52241
52336
|
var hasAnthropicProvider = !!anthropicProvider;
|
|
52242
52337
|
var anthropicProviderName = anthropicProvider === null || anthropicProvider === void 0 ? void 0 : anthropicProvider[0];
|
|
52338
|
+
// Decrypted key (when AppContext exposes it) enables the live Models API
|
|
52339
|
+
// fetch; without it, listModels returns the curated fallback list.
|
|
52340
|
+
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
52341
|
|
|
52244
52342
|
// Check CLI availability on mount
|
|
52245
52343
|
useEffect(function () {
|
|
@@ -52261,6 +52359,28 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52261
52359
|
}
|
|
52262
52360
|
}, []);
|
|
52263
52361
|
|
|
52362
|
+
// Fetch selectable models for the current provider. With an API key the
|
|
52363
|
+
// main process does a live Anthropic Models API fetch; otherwise it returns
|
|
52364
|
+
// the curated fallback. Provider is "anthropic" for both current backends.
|
|
52365
|
+
var fetchModels = useCallback(function () {
|
|
52366
|
+
var _window$mainApi2;
|
|
52367
|
+
if (!((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && (_window$mainApi2 = _window$mainApi2.llm) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.listModels)) return;
|
|
52368
|
+
setModelsLoading(true);
|
|
52369
|
+
window.mainApi.llm.listModels("anthropic", anthropicApiKey).then(function (res) {
|
|
52370
|
+
return setAvailableModels(res && res.models || []);
|
|
52371
|
+
})["catch"](function () {
|
|
52372
|
+
return setAvailableModels([]);
|
|
52373
|
+
})["finally"](function () {
|
|
52374
|
+
return setModelsLoading(false);
|
|
52375
|
+
});
|
|
52376
|
+
}, [anthropicApiKey]);
|
|
52377
|
+
|
|
52378
|
+
// Load models on mount and whenever the available API key changes (so the
|
|
52379
|
+
// list upgrades from curated → live once a key is configured).
|
|
52380
|
+
useEffect(function () {
|
|
52381
|
+
fetchModels();
|
|
52382
|
+
}, [fetchModels]);
|
|
52383
|
+
|
|
52264
52384
|
// Save AI settings to app settings
|
|
52265
52385
|
var saveAiSettings = useCallback(function (updates) {
|
|
52266
52386
|
if (appContext !== null && appContext !== void 0 && appContext.changeSettings) {
|
|
@@ -52271,6 +52391,24 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52271
52391
|
}));
|
|
52272
52392
|
}
|
|
52273
52393
|
}, [appContext]);
|
|
52394
|
+
|
|
52395
|
+
// Auto-migrate a retired saved model to its current replacement (one-time,
|
|
52396
|
+
// on mount) so an old selection can't 404 the assistant. Shows a notice.
|
|
52397
|
+
useEffect(function () {
|
|
52398
|
+
var saved = aiSettings.model;
|
|
52399
|
+
if (saved && isRetiredModel(saved)) {
|
|
52400
|
+
var replacement = migrateModelId(saved);
|
|
52401
|
+
setSelectedModel(replacement);
|
|
52402
|
+
saveAiSettings({
|
|
52403
|
+
model: replacement
|
|
52404
|
+
});
|
|
52405
|
+
setMigrationNotice({
|
|
52406
|
+
from: saved,
|
|
52407
|
+
to: replacement
|
|
52408
|
+
});
|
|
52409
|
+
}
|
|
52410
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52411
|
+
}, []);
|
|
52274
52412
|
function handleBackendChange(e) {
|
|
52275
52413
|
var value = e.target.value;
|
|
52276
52414
|
setPreferredBackend(value);
|
|
@@ -52314,6 +52452,15 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52314
52452
|
});
|
|
52315
52453
|
}
|
|
52316
52454
|
|
|
52455
|
+
// Model dropdown options — keep the current selection selectable even if it
|
|
52456
|
+
// isn't in the fetched list (e.g. a pinned/custom id).
|
|
52457
|
+
var modelOptions = selectedModel && !availableModels.some(function (m) {
|
|
52458
|
+
return m.value === selectedModel;
|
|
52459
|
+
}) ? [{
|
|
52460
|
+
value: selectedModel,
|
|
52461
|
+
label: selectedModel
|
|
52462
|
+
}].concat(_toConsumableArray(availableModels)) : availableModels;
|
|
52463
|
+
|
|
52317
52464
|
// Determine effective backend (what will actually be used)
|
|
52318
52465
|
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
52466
|
return /*#__PURE__*/jsxs("div", {
|
|
@@ -52410,6 +52557,18 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52410
52557
|
}, b.value);
|
|
52411
52558
|
})
|
|
52412
52559
|
})]
|
|
52560
|
+
}), migrationNotice && /*#__PURE__*/jsxs("div", {
|
|
52561
|
+
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",
|
|
52562
|
+
children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
|
|
52563
|
+
icon: "exclamation-triangle",
|
|
52564
|
+
className: "h-3.5 w-3.5 mt-0.5"
|
|
52565
|
+
}), /*#__PURE__*/jsxs("span", {
|
|
52566
|
+
children: ["Your previously selected model (", /*#__PURE__*/jsx("code", {
|
|
52567
|
+
children: migrationNotice.from
|
|
52568
|
+
}), ") is no longer available. Switched to ", /*#__PURE__*/jsx("code", {
|
|
52569
|
+
children: migrationNotice.to
|
|
52570
|
+
}), "."]
|
|
52571
|
+
})]
|
|
52413
52572
|
}), /*#__PURE__*/jsxs("div", {
|
|
52414
52573
|
className: "flex flex-row items-center justify-between py-1",
|
|
52415
52574
|
children: [/*#__PURE__*/jsxs("div", {
|
|
@@ -52419,18 +52578,31 @@ var AiAssistantSection = function AiAssistantSection() {
|
|
|
52419
52578
|
children: "Model"
|
|
52420
52579
|
}), /*#__PURE__*/jsx("span", {
|
|
52421
52580
|
className: "text-xs opacity-50",
|
|
52422
|
-
children: "
|
|
52581
|
+
children: "Model for AI Assistant conversations"
|
|
52582
|
+
})]
|
|
52583
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
52584
|
+
className: "flex items-center gap-2",
|
|
52585
|
+
children: [/*#__PURE__*/jsx("select", {
|
|
52586
|
+
value: selectedModel,
|
|
52587
|
+
onChange: handleModelChange,
|
|
52588
|
+
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",
|
|
52589
|
+
children: modelOptions.map(function (m) {
|
|
52590
|
+
return /*#__PURE__*/jsx("option", {
|
|
52591
|
+
value: m.value,
|
|
52592
|
+
children: m.label
|
|
52593
|
+
}, m.value);
|
|
52594
|
+
})
|
|
52595
|
+
}), /*#__PURE__*/jsx("button", {
|
|
52596
|
+
type: "button",
|
|
52597
|
+
onClick: fetchModels,
|
|
52598
|
+
disabled: modelsLoading,
|
|
52599
|
+
title: "Refresh available models",
|
|
52600
|
+
className: "text-gray-400 hover:text-gray-200 disabled:opacity-40 transition-colors p-1.5",
|
|
52601
|
+
children: /*#__PURE__*/jsx(FontAwesomeIcon, {
|
|
52602
|
+
icon: "rotate",
|
|
52603
|
+
className: "h-3.5 w-3.5 ".concat(modelsLoading ? "animate-spin" : "")
|
|
52604
|
+
})
|
|
52423
52605
|
})]
|
|
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
52606
|
})]
|
|
52435
52607
|
})]
|
|
52436
52608
|
}), !hasAnthropicProvider && /*#__PURE__*/jsxs("div", {
|