@iblai/iblai-js 2.11.0 → 2.11.2
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.
|
@@ -96915,7 +96915,7 @@ var analyticsAnalyticsOverview$3 = {
|
|
|
96915
96915
|
topicsChartDescription: "The most discussed topics, ranked by how many messages each one generated.",
|
|
96916
96916
|
activeUsersChartDescription: "Unique active users per day, showing how engagement changes over time.",
|
|
96917
96917
|
llmSpend: "LLM spend",
|
|
96918
|
-
llmSpendDescription: "Raw cost of every traced LLM call in the selected period, from the trace store. Billing totals live on the Cost
|
|
96918
|
+
llmSpendDescription: "Raw cost of every traced LLM call in the selected period, from the trace store. Billing totals live on the Cost tab.",
|
|
96919
96919
|
allTopics: "All topics",
|
|
96920
96920
|
topicsRankedFooter: "{shown} of {total} topics · ranked by message volume"
|
|
96921
96921
|
};
|
|
@@ -102872,7 +102872,7 @@ var analyticsChartCard$3 = {
|
|
|
102872
102872
|
adjustRangeHint: "This card only — the page range stays where it is."
|
|
102873
102873
|
};
|
|
102874
102874
|
var analyticsCostTabs$3 = {
|
|
102875
|
-
ariaLabel: "Cost
|
|
102875
|
+
ariaLabel: "Cost sections",
|
|
102876
102876
|
spend: "Spend",
|
|
102877
102877
|
usage: "Usage & latency",
|
|
102878
102878
|
traces: "Traces"
|
|
@@ -104063,7 +104063,7 @@ var analyticsAnalyticsOverview$2 = {
|
|
|
104063
104063
|
topicsChartDescription: "Les sujets les plus abordés, classés selon le nombre de messages générés.",
|
|
104064
104064
|
activeUsersChartDescription: "Utilisateurs actifs uniques par jour, pour suivre l’évolution de l’engagement.",
|
|
104065
104065
|
llmSpend: "Dépenses LLM",
|
|
104066
|
-
llmSpendDescription: "Coût brut de chaque appel LLM tracé sur la période sélectionnée, issu du magasin de traces. Les totaux de facturation sont dans l'onglet Coûts
|
|
104066
|
+
llmSpendDescription: "Coût brut de chaque appel LLM tracé sur la période sélectionnée, issu du magasin de traces. Les totaux de facturation sont dans l'onglet Coûts.",
|
|
104067
104067
|
allTopics: "Tous les sujets",
|
|
104068
104068
|
topicsRankedFooter: "{shown} sur {total} sujets · classés par volume de messages"
|
|
104069
104069
|
};
|
|
@@ -110020,7 +110020,7 @@ var analyticsChartCard$2 = {
|
|
|
110020
110020
|
adjustRangeHint: "Cette carte uniquement — la plage de la page reste inchangée."
|
|
110021
110021
|
};
|
|
110022
110022
|
var analyticsCostTabs$2 = {
|
|
110023
|
-
ariaLabel: "Sections Coûts
|
|
110023
|
+
ariaLabel: "Sections Coûts",
|
|
110024
110024
|
spend: "Dépenses",
|
|
110025
110025
|
usage: "Utilisation et latence",
|
|
110026
110026
|
traces: "Traces"
|
|
@@ -111211,7 +111211,7 @@ var analyticsAnalyticsOverview$1 = {
|
|
|
111211
111211
|
topicsChartDescription: "Los temas más tratados, ordenados por la cantidad de mensajes que generó cada uno.",
|
|
111212
111212
|
activeUsersChartDescription: "Usuarios activos únicos por día, para ver cómo cambia la participación con el tiempo.",
|
|
111213
111213
|
llmSpend: "Gasto LLM",
|
|
111214
|
-
llmSpendDescription: "Costo bruto de cada llamada LLM trazada en el período seleccionado, del almacén de trazas. Los totales de facturación están en la pestaña Costos
|
|
111214
|
+
llmSpendDescription: "Costo bruto de cada llamada LLM trazada en el período seleccionado, del almacén de trazas. Los totales de facturación están en la pestaña Costos.",
|
|
111215
111215
|
allTopics: "Todos los temas",
|
|
111216
111216
|
topicsRankedFooter: "{shown} de {total} temas · ordenados por volumen de mensajes"
|
|
111217
111217
|
};
|
|
@@ -117168,7 +117168,7 @@ var analyticsChartCard$1 = {
|
|
|
117168
117168
|
adjustRangeHint: "Solo esta tarjeta — el rango de la página no cambia."
|
|
117169
117169
|
};
|
|
117170
117170
|
var analyticsCostTabs$1 = {
|
|
117171
|
-
ariaLabel: "Secciones de Costos
|
|
117171
|
+
ariaLabel: "Secciones de Costos",
|
|
117172
117172
|
spend: "Gasto",
|
|
117173
117173
|
usage: "Uso y latencia",
|
|
117174
117174
|
traces: "Trazas"
|
|
@@ -118359,7 +118359,7 @@ var analyticsAnalyticsOverview = {
|
|
|
118359
118359
|
topicsChartDescription: "讨论最多的主题,按各自产生的消息数排序。",
|
|
118360
118360
|
activeUsersChartDescription: "每日独立活跃用户数,展示参与度随时间的变化。",
|
|
118361
118361
|
llmSpend: "LLM 支出",
|
|
118362
|
-
llmSpendDescription: "所选时段内每次被追踪的 LLM
|
|
118362
|
+
llmSpendDescription: "所选时段内每次被追踪的 LLM 调用的原始成本,来自追踪存储。计费总额在成本页。",
|
|
118363
118363
|
allTopics: "所有主题",
|
|
118364
118364
|
topicsRankedFooter: "共 {total} 个主题,显示 {shown} 个 · 按消息量排序"
|
|
118365
118365
|
};
|
|
@@ -124316,7 +124316,7 @@ var analyticsChartCard = {
|
|
|
124316
124316
|
adjustRangeHint: "仅此卡片 — 页面范围保持不变。"
|
|
124317
124317
|
};
|
|
124318
124318
|
var analyticsCostTabs = {
|
|
124319
|
-
ariaLabel: "
|
|
124319
|
+
ariaLabel: "成本分区",
|
|
124320
124320
|
spend: "支出",
|
|
124321
124321
|
usage: "用量与延迟",
|
|
124322
124322
|
traces: "追踪"
|
|
@@ -225376,217 +225376,6 @@ function CreateApiModal$1({ isOpen, onClose, tenantKey, username }) {
|
|
|
225376
225376
|
: t('apiTabLabels.createModal.submit') })) }) })] })] }) }), apiKey && jsx(ApiKeyModal$1, { isOpen: true, onClose: () => setApiKey(null), apiKey: apiKey })] }));
|
|
225377
225377
|
}
|
|
225378
225378
|
|
|
225379
|
-
/**
|
|
225380
|
-
* Small pure utilities colocated with the LLM tab.
|
|
225381
|
-
* Ported from standalone's `@/lib/utils` and `@/lib/error`.
|
|
225382
|
-
*/
|
|
225383
|
-
// Canonical provider name for any label — a backend key ("azure_openai"), a
|
|
225384
|
-
// human label ("Microsoft"), or a local model's provider ("Meta"). Folds every
|
|
225385
|
-
// alias onto one identity so the same provider from different sources compares
|
|
225386
|
-
// equal. See getProviderName.
|
|
225387
|
-
const PROVIDER_NAME_BY_ALIAS = {
|
|
225388
|
-
microsoft: 'azure_openai',
|
|
225389
|
-
azureopenai: 'azure_openai',
|
|
225390
|
-
openai: 'openai',
|
|
225391
|
-
google: 'google',
|
|
225392
|
-
gemini: 'google',
|
|
225393
|
-
meta: 'llama',
|
|
225394
|
-
metallama: 'llama',
|
|
225395
|
-
llama: 'llama',
|
|
225396
|
-
mistral: 'mistral',
|
|
225397
|
-
mistralai: 'mistral',
|
|
225398
|
-
nvidia: 'nvidia',
|
|
225399
|
-
iblchatnvidia: 'nvidia',
|
|
225400
|
-
deepseek: 'deepseek',
|
|
225401
|
-
anthropic: 'anthropic',
|
|
225402
|
-
iblchatanthropic: 'anthropic',
|
|
225403
|
-
claude: 'anthropic',
|
|
225404
|
-
groq: 'groq',
|
|
225405
|
-
perplexity: 'perplexity',
|
|
225406
|
-
xai: 'xai',
|
|
225407
|
-
bedrock: 'bedrock',
|
|
225408
|
-
amazonbedrock: 'bedrock',
|
|
225409
|
-
amazon: 'bedrock',
|
|
225410
|
-
iblchatbedrock: 'bedrock',
|
|
225411
|
-
alibaba: 'alibaba',
|
|
225412
|
-
qwen: 'alibaba',
|
|
225413
|
-
ibm: 'ibm',
|
|
225414
|
-
granite: 'ibm',
|
|
225415
|
-
// ibl.ai's own hosted provider. The backend key is `iblai` (NameEnum.IBLAI);
|
|
225416
|
-
// the extra aliases cover the `IBLChat<Vendor>` house spelling and the
|
|
225417
|
-
// dotted/spaced brand forms, which all normalize to one of these.
|
|
225418
|
-
iblai: 'iblai',
|
|
225419
|
-
ibl: 'iblai',
|
|
225420
|
-
iblchatibl: 'iblai',
|
|
225421
|
-
iblchatiblai: 'iblai',
|
|
225422
|
-
};
|
|
225423
|
-
/**
|
|
225424
|
-
* Canonical provider name for any label, case- and punctuation-insensitive.
|
|
225425
|
-
* Folds backend keys and human/display labels onto one identity — e.g.
|
|
225426
|
-
* `getProviderName('Microsoft') === 'azure_openai'`,
|
|
225427
|
-
* `getProviderName('Meta') === 'llama'`, `getProviderName('Google') === 'google'`.
|
|
225428
|
-
* Unknown providers return their normalized (lowercased, alphanumeric-only) form.
|
|
225429
|
-
*
|
|
225430
|
-
* This is the single source of truth for provider identity, which matters as
|
|
225431
|
-
* soon as on-device models enter the picture: the local catalog labels its
|
|
225432
|
-
* providers the human way ("Meta", "Microsoft", "Alibaba") while the backend LLM
|
|
225433
|
-
* list uses wire keys ("llama", "azure_openai"). Comparing the two raw would
|
|
225434
|
-
* render a duplicate card for the same vendor.
|
|
225435
|
-
*/
|
|
225436
|
-
function getProviderName(llmProvider) {
|
|
225437
|
-
var _a;
|
|
225438
|
-
const normalized = (llmProvider !== null && llmProvider !== void 0 ? llmProvider : '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
225439
|
-
return (_a = PROVIDER_NAME_BY_ALIAS[normalized]) !== null && _a !== void 0 ? _a : normalized;
|
|
225440
|
-
}
|
|
225441
|
-
/**
|
|
225442
|
-
* Whether two Ollama model refs name the same model, comparing by base name and
|
|
225443
|
-
* ignoring a trailing `:tag` (so "llama3.2" ≡ "llama3.2:latest", and
|
|
225444
|
-
* "granite4.1:8b" ≡ "granite4.1"). The download state and Ollama's /api/tags may
|
|
225445
|
-
* carry a tag suffix the catalog id doesn't (or vice-versa); an exact `===` then
|
|
225446
|
-
* fails to recognize a row's own in-flight download — the row shows "Download"
|
|
225447
|
-
* with no progress while the pull runs. Base-name matching is safe here because
|
|
225448
|
-
* every catalog model has a unique base (llama3.2, qwen3, mistral, granite4.1,
|
|
225449
|
-
* gpt-oss, gemma4), so it can never light up the wrong row.
|
|
225450
|
-
*/
|
|
225451
|
-
function sameModel(a, b) {
|
|
225452
|
-
const base = (ref) => (ref !== null && ref !== void 0 ? ref : '').toLowerCase().split(':')[0];
|
|
225453
|
-
const ba = base(a);
|
|
225454
|
-
return ba.length > 0 && ba === base(b);
|
|
225455
|
-
}
|
|
225456
|
-
/**
|
|
225457
|
-
* Whether a catalog model id (e.g. "granite4.1:8b") is among the installed
|
|
225458
|
-
* Ollama tags (e.g. "granite4.1:latest").
|
|
225459
|
-
*
|
|
225460
|
-
* Deliberately NOT the profile tab's `isModelInstalled`, which matches an exact
|
|
225461
|
-
* tag or the `<id>:` prefix: that is one-directional and misses a catalog id
|
|
225462
|
-
* that itself carries a tag ("granite4.1:8b" against an installed
|
|
225463
|
-
* "granite4.1:latest"). The picker needs the symmetric base-name comparison of
|
|
225464
|
-
* {@link sameModel} so a pulled model is recognized whichever side wears the tag.
|
|
225465
|
-
*/
|
|
225466
|
-
function isLocalModelInstalled(modelId, installedTags) {
|
|
225467
|
-
return !!(installedTags === null || installedTags === void 0 ? void 0 : installedTags.some((tag) => sameModel(tag, modelId)));
|
|
225468
|
-
}
|
|
225469
|
-
function canSwitchProvider(providers, name) {
|
|
225470
|
-
const provider = providers.find((p) => p.name === name);
|
|
225471
|
-
return !!(provider === null || provider === void 0 ? void 0 : provider.chat_models) && provider.chat_models.length > 0;
|
|
225472
|
-
}
|
|
225473
|
-
/**
|
|
225474
|
-
* Whether we hold a usable LLM key for this provider — its own credentials, or
|
|
225475
|
-
* the tenant's main keys when it is allowed to borrow them. An *absent*
|
|
225476
|
-
* `main_has_credentials` means the backend did not report on the main keys and
|
|
225477
|
-
* is treated as available (matching standalone's `@/lib/utils` and
|
|
225478
|
-
* `claw-sandbox`'s copy); only an explicit `false` rules the main keys out.
|
|
225479
|
-
*/
|
|
225480
|
-
function canSwitchLLm(llm) {
|
|
225481
|
-
if (llm === null || llm === void 0 ? void 0 : llm.has_credentials) {
|
|
225482
|
-
return true;
|
|
225483
|
-
}
|
|
225484
|
-
return ((llm === null || llm === void 0 ? void 0 : llm.can_use_main_keys) &&
|
|
225485
|
-
((llm === null || llm === void 0 ? void 0 : llm.main_has_credentials) === true || (llm === null || llm === void 0 ? void 0 : llm.main_has_credentials) === undefined));
|
|
225486
|
-
}
|
|
225487
|
-
/**
|
|
225488
|
-
* Compares two raw provider names by the label the user actually sees on the
|
|
225489
|
-
* card, not by the backend key — the two diverge often enough to matter
|
|
225490
|
-
* (`bedrock` renders as "Amazon", `azure_openai` as "Microsoft", `iblai` as
|
|
225491
|
-
* "ibl.ai"). Comparison is case-insensitive (`sensitivity: 'base'`) so casing
|
|
225492
|
-
* never produces a surprising order. `getDetails` is the host-provided resolver
|
|
225493
|
-
* the grid renders with, so the sort always matches what is on screen; unknown
|
|
225494
|
-
* providers fall back to their raw name as the display name.
|
|
225495
|
-
*/
|
|
225496
|
-
function compareLLMProvidersByDisplayName(a, b, getDetails) {
|
|
225497
|
-
return getDetails(a).name.localeCompare(getDetails(b).name, undefined, {
|
|
225498
|
-
sensitivity: 'base',
|
|
225499
|
-
});
|
|
225500
|
-
}
|
|
225501
|
-
/**
|
|
225502
|
-
* Whether the user can reach *any* model of this provider.
|
|
225503
|
-
*
|
|
225504
|
-
* This is exactly the provider-level half of the per-model `isDisabled` rule in
|
|
225505
|
-
* `llm-tab/llm-provider-modal.tsx`: a model row there is disabled when
|
|
225506
|
-
* `!canSwitchLLm(provider) || !canSwitchProvider(llms, provider.name)`, and both
|
|
225507
|
-
* of those depend only on the provider — so when either fails, *every* model row
|
|
225508
|
-
* of that provider is disabled. `canSwitchProvider` is just "has at least one
|
|
225509
|
-
* `chat_models` entry", which is checked inline here to keep the helper pure and
|
|
225510
|
-
* free of the surrounding provider list.
|
|
225511
|
-
*
|
|
225512
|
-
* `canSwitchLLm` can return `undefined` (its `can_use_main_keys` branch), hence
|
|
225513
|
-
* the explicit `Boolean(...)`.
|
|
225514
|
-
*/
|
|
225515
|
-
function canAccessProvider(provider) {
|
|
225516
|
-
var _a, _b;
|
|
225517
|
-
return Boolean(canSwitchLLm(provider !== null && provider !== void 0 ? provider : {})) && ((_b = (_a = provider === null || provider === void 0 ? void 0 : provider.chat_models) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
225518
|
-
}
|
|
225519
|
-
/**
|
|
225520
|
-
* Orders LLM provider cards as two alphabetical groups: providers the user can
|
|
225521
|
-
* actually use (see {@link canAccessProvider}) first, then the ones they can't —
|
|
225522
|
-
* each group sorted alphabetically by display name.
|
|
225523
|
-
*
|
|
225524
|
-
* The grouping predicate is deliberately the same one the grid grays cards with,
|
|
225525
|
-
* so the two always line up: group 1 renders normally, group 2 renders grayed.
|
|
225526
|
-
* Grouping on credentials alone would let a provider that has a key but ships no
|
|
225527
|
-
* chat models sort into the "usable" group while rendering grayed.
|
|
225528
|
-
*
|
|
225529
|
-
* Pure and non-mutating: RTK Query results are frozen, so the input is copied
|
|
225530
|
-
* before sorting. `Array.prototype.sort` is stable, so providers that tie on
|
|
225531
|
-
* both group and display name keep their original relative order.
|
|
225532
|
-
*/
|
|
225533
|
-
function sortLLMProvidersByCredentials(providers, getDetails) {
|
|
225534
|
-
return [...providers].sort((a, b) => {
|
|
225535
|
-
const aUsable = canAccessProvider(a);
|
|
225536
|
-
const bUsable = canAccessProvider(b);
|
|
225537
|
-
if (aUsable !== bUsable)
|
|
225538
|
-
return aUsable ? -1 : 1;
|
|
225539
|
-
return compareLLMProvidersByDisplayName(a.name, b.name, getDetails);
|
|
225540
|
-
});
|
|
225541
|
-
}
|
|
225542
|
-
function extractErrorMessage$1(error, fallback) {
|
|
225543
|
-
var _a, _b;
|
|
225544
|
-
const apiError = error;
|
|
225545
|
-
return ((_a = apiError === null || apiError === void 0 ? void 0 : apiError.data) === null || _a === void 0 ? void 0 : _a.error) || ((_b = apiError === null || apiError === void 0 ? void 0 : apiError.error) === null || _b === void 0 ? void 0 : _b.error) || fallback;
|
|
225546
|
-
}
|
|
225547
|
-
|
|
225548
|
-
// Logo + display name keyed by canonical provider name (see getProviderName).
|
|
225549
|
-
const PROVIDER_DETAILS_BY_NAME = {
|
|
225550
|
-
groq: { logo: '/llm-groq-provider.png', name: 'Groq' },
|
|
225551
|
-
nvidia: { logo: '/llm-nvidia-provider.webp', name: 'NVIDIA' },
|
|
225552
|
-
azure_openai: { logo: '/llm-microsoft-provider.png', name: 'Microsoft' },
|
|
225553
|
-
openai: { logo: '/llm-openai-provider-2.svg', name: 'OpenAI' },
|
|
225554
|
-
mistral: { logo: '/llm-mistral-provider.jpeg', name: 'Mistral' },
|
|
225555
|
-
google: { logo: '/llm-google-provider.svg', name: 'Google' },
|
|
225556
|
-
llama: { logo: '/llm-llama-provider.jpeg', name: 'Meta' },
|
|
225557
|
-
anthropic: { logo: '/llm-claude-provider.png', name: 'Anthropic' },
|
|
225558
|
-
perplexity: { logo: '/llm-perplexity-provider.webp', name: 'Perplexity' },
|
|
225559
|
-
deepseek: { logo: '/llm-deepseek-provider.png', name: 'DeepSeek' },
|
|
225560
|
-
xai: { logo: '/llm-xai-provider.jpg', name: 'xAI' },
|
|
225561
|
-
bedrock: { logo: '/llm-amazon-provider.png', name: 'Amazon' },
|
|
225562
|
-
alibaba: { logo: '/llm-alibaba-provider.png', name: 'Alibaba' },
|
|
225563
|
-
ibm: { logo: '/llm-ibm-provider.png', name: 'IBM' },
|
|
225564
|
-
iblai: { logo: '/llm-iblai-provider.png', name: 'ibl.ai' },
|
|
225565
|
-
};
|
|
225566
|
-
/**
|
|
225567
|
-
* Returns the canonical logo path and display name for an LLM provider.
|
|
225568
|
-
*
|
|
225569
|
-
* Resolution goes through {@link getProviderName}, so a backend wire key
|
|
225570
|
-
* (`azure_openai`), a human label (`Microsoft`) and an on-device catalog's
|
|
225571
|
-
* provider string (`Meta`, `Alibaba`) all land on the same entry — the provider
|
|
225572
|
-
* grid merges cloud and on-device providers into one list, so the two spellings
|
|
225573
|
-
* have to agree.
|
|
225574
|
-
*
|
|
225575
|
-
* `logo` is a static-root path (e.g. `/llm-amazon-provider.png`); the package
|
|
225576
|
-
* ships the canonical assets under `@iblai/web-containers/public/` — copy them
|
|
225577
|
-
* into your app's static-root (`public/` for Next.js) so the paths resolve.
|
|
225578
|
-
*/
|
|
225579
|
-
function getLLMProviderDetails(llmProvider, llmName) {
|
|
225580
|
-
var _a;
|
|
225581
|
-
const name = getProviderName(llmProvider);
|
|
225582
|
-
// OpenAI and Google use a model-specific logo when a concrete model is named.
|
|
225583
|
-
if (name === 'openai' && llmName)
|
|
225584
|
-
return { logo: '/llm-openai-provider.jpg', name: 'OpenAI' };
|
|
225585
|
-
if (name === 'google' && llmName)
|
|
225586
|
-
return { logo: '/llm-gemini-provider.png', name: 'Google' };
|
|
225587
|
-
return (_a = PROVIDER_DETAILS_BY_NAME[name]) !== null && _a !== void 0 ? _a : { logo: '/llm-generic-provider.png', name: llmProvider };
|
|
225588
|
-
}
|
|
225589
|
-
|
|
225590
225379
|
// Dynamic schema based on selected provider
|
|
225591
225380
|
const createDynamicSchema$1 = (schemaFields) => {
|
|
225592
225381
|
const schemaObj = {
|
|
@@ -225815,14 +225604,9 @@ function CreateLLMModal({ isOpen, onClose, tenantKey, onSuccess }) {
|
|
|
225815
225604
|
}
|
|
225816
225605
|
}, children: [jsx(SelectTrigger, { children: jsx(SelectValue, { placeholder: t('llmsTabCreateLlmModal.selectProviderPlaceholder') }) }), jsx(SelectContent, { children: availableProviders.map((provider) => {
|
|
225817
225606
|
var _a, _b;
|
|
225818
|
-
|
|
225819
|
-
|
|
225820
|
-
|
|
225821
|
-
const providerLogo = ((_a = provider === null || provider === void 0 ? void 0 : provider.service_info) === null || _a === void 0 ? void 0 : _a.logo) ||
|
|
225822
|
-
getLLMProviderDetails(provider.name).logo;
|
|
225823
|
-
const providerName = ((_b = provider === null || provider === void 0 ? void 0 : provider.service_info) === null || _b === void 0 ? void 0 : _b.display_name) ||
|
|
225824
|
-
provider.name;
|
|
225825
|
-
return (jsx(SelectItem, { value: provider.name, children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("img", { src: providerLogo, alt: provider.name, className: "w-4 h-4 rounded-sm object-contain" }), providerName || provider.name] }) }, provider.name));
|
|
225607
|
+
const providerLogo = (_a = provider.service_info) === null || _a === void 0 ? void 0 : _a.logo;
|
|
225608
|
+
const providerName = ((_b = provider.service_info) === null || _b === void 0 ? void 0 : _b.display_name) || provider.name;
|
|
225609
|
+
return (jsx(SelectItem, { value: provider.name, children: jsxs("div", { className: "flex items-center gap-2", children: [providerLogo ? (jsx("img", { src: providerLogo, alt: providerName, className: "w-4 h-4 rounded-sm object-contain" })) : (jsx("span", { children: "\uD83D\uDD11" })), providerName] }) }, provider.name));
|
|
225826
225610
|
}) })] }), shouldShowError && (jsx("p", { className: "text-red-500 text-xs", children: (_b = field.state.meta.errors[0]) === null || _b === void 0 ? void 0 : _b.message }))] }));
|
|
225827
225611
|
} })), isCredentialsSchemaLoading && (jsxs("div", { className: "flex items-center justify-center py-4", children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2" }), jsx("span", { className: "text-sm text-gray-600", children: t('llmsTabCreateLlmModal.loadingProviderConfigurations') })] })), showProviderForm && !isCredentialsSchemaLoading && !isAzureOpenAI && (jsx(Fragment$1, { children: schemaFields.map((fieldName) => (jsx(form.Field, { name: fieldName, children: (field) => {
|
|
225828
225612
|
var _a, _b;
|
|
@@ -225909,26 +225693,18 @@ function IntegrationLLMsTab({ tenantKey }) {
|
|
|
225909
225693
|
}
|
|
225910
225694
|
};
|
|
225911
225695
|
return (jsxs("div", { className: "space-y-4", children: [jsx(InfoBanner, { icon: jsx(Bot, { className: "w-5 h-5" }), children: t('llmsTabIntegrationLlmsTab.infoBannerText') }), jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm min-w-[600px]", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('llmsTabIntegrationLlmsTab.colName') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('llmsTabIntegrationLlmsTab.colKey') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[50px]" })] }) }), jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: isMaskedCredentialsLoading ? (jsx("tr", { children: jsx("td", { colSpan: 3, className: "px-6 py-8 text-center text-sm text-gray-500", children: t('llmsTabIntegrationLlmsTab.loading') }) })) : maskedCredentials.length === 0 ? (jsx("tr", { children: jsx("td", { colSpan: 3, className: "px-6 py-8 text-center text-sm text-gray-500", children: t('llmsTabIntegrationLlmsTab.noLlmKeysFound') }) })) : (maskedCredentials.map((cred, idx) => {
|
|
225912
|
-
var _a, _b, _c;
|
|
225696
|
+
var _a, _b, _c, _d, _e;
|
|
225913
225697
|
const provider = ((_a = cred.service_info) === null || _a === void 0 ? void 0 : _a.display_name) || cred.name;
|
|
225914
|
-
//
|
|
225915
|
-
|
|
225916
|
-
// degrade to a generic key emoji.
|
|
225917
|
-
let logoUrl;
|
|
225918
|
-
let logoAlt;
|
|
225919
|
-
if ((_b = cred.service_info) === null || _b === void 0 ? void 0 : _b.logo) {
|
|
225920
|
-
logoUrl = cred.service_info.logo;
|
|
225921
|
-
logoAlt = cred.service_info.display_name || cred.service_info.name;
|
|
225922
|
-
}
|
|
225923
|
-
else {
|
|
225924
|
-
logoUrl = getLLMProviderDetails(cred.name).logo;
|
|
225925
|
-
}
|
|
225698
|
+
// Logos are backend-owned (`service_info.logo`); no bundled fallback.
|
|
225699
|
+
const logoUrl = (_b = cred.service_info) === null || _b === void 0 ? void 0 : _b.logo;
|
|
225926
225700
|
const isAzure = isAzureOpenAI(cred);
|
|
225927
225701
|
const azureModels = isAzure ? getAzureModels(cred) : [];
|
|
225928
225702
|
const isExpanded = expandedRows.has(cred.name);
|
|
225929
|
-
return (jsxs(React__default.Fragment, { children: [jsxs("tr", { children: [jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("img", { src: logoUrl, alt:
|
|
225703
|
+
return (jsxs(React__default.Fragment, { children: [jsxs("tr", { children: [jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex items-center gap-2", children: [logoUrl ? (jsx("img", { src: logoUrl, alt: ((_c = cred.service_info) === null || _c === void 0 ? void 0 : _c.display_name) ||
|
|
225704
|
+
((_d = cred.service_info) === null || _d === void 0 ? void 0 : _d.name) ||
|
|
225705
|
+
cred.name, className: "w-6 h-6 rounded-sm object-contain" })) : (jsx("span", { className: "text-lg", children: '🔑' })), jsx("span", { className: "font-normal text-gray-900 dark:text-gray-100", children: provider || cred.name }), isAzure && azureModels.length > 0 && (jsx("button", { type: "button", onClick: () => toggleRowExpansion(cred.name), className: "p-0.5 hover:bg-gray-100 rounded", children: isExpanded ? (jsx(ChevronUp, { className: "h-4 w-4 text-gray-500" })) : (jsx(ChevronDown, { className: "h-4 w-4 text-gray-500" })) }))] }) }), jsx("td", { className: "px-6 py-4 font-mono text-sm text-gray-900 dark:text-gray-100", children: isAzure ? (jsx("span", { className: "text-xs text-gray-500", children: t('llmsTabIntegrationLlmsTab.azureModelCount', {
|
|
225930
225706
|
count: azureModels.length,
|
|
225931
|
-
}) })) : (String((
|
|
225707
|
+
}) })) : (String((_e = cred === null || cred === void 0 ? void 0 : cred.value) === null || _e === void 0 ? void 0 : _e.key).slice(0, 15) || '') }), jsx("td", { className: "px-6 py-4", children: jsx(Button$1, { variant: "ghost", size: "sm", className: "cursor-pointer mr-2", disabled: isDeletingIntegration || isDeletingCredential, onClick: () => handleDeleteCredential(cred.name, cred.platform, false), children: jsx(Trash, { className: "h-4 w-4" }) }) })] }), isAzure &&
|
|
225932
225708
|
isExpanded &&
|
|
225933
225709
|
azureModels.map((model, modelIdx) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 pl-12", children: jsx("span", { className: "text-sm text-gray-700", children: model.modelName.toLowerCase() }) }), jsx("td", { className: "px-6 py-4 font-mono text-sm text-gray-600", children: model.maskedKey.slice(0, 15) || '' }), jsx("td", { className: "px-6 py-4", children: jsx(Button$1, { variant: "ghost", size: "sm", className: "cursor-pointer", disabled: isDeletingIntegration || isDeletingCredential, onClick: () => handleDeleteCredential(cred.name, cred.platform, false, model.modelName), children: jsx(Trash, { className: "h-4 w-4" }) }) })] }, `${cred.name}-${model.modelName}-${modelIdx}`)))] }, cred.name + idx));
|
|
225934
225710
|
})) })] }) })] }));
|
|
@@ -259377,6 +259153,202 @@ var reactPaginate = {exports: {}};
|
|
|
259377
259153
|
|
|
259378
259154
|
} (reactPaginate));
|
|
259379
259155
|
|
|
259156
|
+
/**
|
|
259157
|
+
* A provider's logo as the backend serves it. Provider naming and artwork are
|
|
259158
|
+
* owned by the API (`LLMResponse.logo`, `ExternalServiceInfo.logo`), so there
|
|
259159
|
+
* is no bundled fallback image: a provider without a logo renders a neutral
|
|
259160
|
+
* initial instead, keeping the card layout intact.
|
|
259161
|
+
*/
|
|
259162
|
+
function LLMProviderLogo({ logo, label, alt = label, size = 32, className, }) {
|
|
259163
|
+
if (logo) {
|
|
259164
|
+
return (jsx(Image$4, { src: logo, alt: alt, className: cn('h-full w-full object-contain', className), width: size, height: size, loading: "lazy" }));
|
|
259165
|
+
}
|
|
259166
|
+
return (jsx("span", { role: "img", "aria-label": alt, "data-testid": "llm-provider-logo-placeholder", className: cn('flex h-full w-full items-center justify-center rounded bg-gray-100 text-xs font-semibold text-gray-500 uppercase', className), children: label.charAt(0) }));
|
|
259167
|
+
}
|
|
259168
|
+
|
|
259169
|
+
/**
|
|
259170
|
+
* Small pure utilities colocated with the LLM tab.
|
|
259171
|
+
* Ported from standalone's `@/lib/utils` and `@/lib/error`.
|
|
259172
|
+
*/
|
|
259173
|
+
/**
|
|
259174
|
+
* The label a provider renders with: the backend's `display_name` when it
|
|
259175
|
+
* ships one, else its raw `name`. There is deliberately no frontend map behind
|
|
259176
|
+
* this — naming (and the logo next to it) is owned by the backend.
|
|
259177
|
+
*/
|
|
259178
|
+
function llmProviderLabel(provider) {
|
|
259179
|
+
return provider.display_name || provider.name;
|
|
259180
|
+
}
|
|
259181
|
+
/**
|
|
259182
|
+
* The label a chat model renders with: the backend's `display_name` (`GPT-4.1
|
|
259183
|
+
* Mini`) when it ships one, else the raw wire key (`gpt-4.1-mini`). Same rule
|
|
259184
|
+
* as {@link llmProviderLabel}; every model list (LLM tab, sandbox) goes through
|
|
259185
|
+
* here so they never drift apart.
|
|
259186
|
+
*/
|
|
259187
|
+
function llmModelLabel(model) {
|
|
259188
|
+
return model.display_name || model.llm_name;
|
|
259189
|
+
}
|
|
259190
|
+
// Canonical provider name for any label — a backend key ("azure_openai"), a
|
|
259191
|
+
// human label ("Microsoft"), or a local model's provider ("Meta"). Folds every
|
|
259192
|
+
// alias onto one identity so the same provider from different sources compares
|
|
259193
|
+
// equal. See getProviderName.
|
|
259194
|
+
const PROVIDER_NAME_BY_ALIAS = {
|
|
259195
|
+
microsoft: 'azure_openai',
|
|
259196
|
+
azureopenai: 'azure_openai',
|
|
259197
|
+
openai: 'openai',
|
|
259198
|
+
google: 'google',
|
|
259199
|
+
gemini: 'google',
|
|
259200
|
+
meta: 'llama',
|
|
259201
|
+
metallama: 'llama',
|
|
259202
|
+
llama: 'llama',
|
|
259203
|
+
mistral: 'mistral',
|
|
259204
|
+
mistralai: 'mistral',
|
|
259205
|
+
nvidia: 'nvidia',
|
|
259206
|
+
iblchatnvidia: 'nvidia',
|
|
259207
|
+
deepseek: 'deepseek',
|
|
259208
|
+
anthropic: 'anthropic',
|
|
259209
|
+
iblchatanthropic: 'anthropic',
|
|
259210
|
+
claude: 'anthropic',
|
|
259211
|
+
groq: 'groq',
|
|
259212
|
+
perplexity: 'perplexity',
|
|
259213
|
+
xai: 'xai',
|
|
259214
|
+
bedrock: 'bedrock',
|
|
259215
|
+
amazonbedrock: 'bedrock',
|
|
259216
|
+
amazon: 'bedrock',
|
|
259217
|
+
iblchatbedrock: 'bedrock',
|
|
259218
|
+
alibaba: 'alibaba',
|
|
259219
|
+
qwen: 'alibaba',
|
|
259220
|
+
ibm: 'ibm',
|
|
259221
|
+
granite: 'ibm',
|
|
259222
|
+
// ibl.ai's own hosted provider. The backend key is `iblai` (NameEnum.IBLAI);
|
|
259223
|
+
// the extra aliases cover the `IBLChat<Vendor>` house spelling and the
|
|
259224
|
+
// dotted/spaced brand forms, which all normalize to one of these.
|
|
259225
|
+
iblai: 'iblai',
|
|
259226
|
+
ibl: 'iblai',
|
|
259227
|
+
iblchatibl: 'iblai',
|
|
259228
|
+
iblchatiblai: 'iblai',
|
|
259229
|
+
};
|
|
259230
|
+
/**
|
|
259231
|
+
* Canonical provider name for any label, case- and punctuation-insensitive.
|
|
259232
|
+
* Folds backend keys and human/display labels onto one identity — e.g.
|
|
259233
|
+
* `getProviderName('Microsoft') === 'azure_openai'`,
|
|
259234
|
+
* `getProviderName('Meta') === 'llama'`, `getProviderName('Google') === 'google'`.
|
|
259235
|
+
* Unknown providers return their normalized (lowercased, alphanumeric-only) form.
|
|
259236
|
+
*
|
|
259237
|
+
* This is the single source of truth for provider identity, which matters as
|
|
259238
|
+
* soon as on-device models enter the picture: the local catalog labels its
|
|
259239
|
+
* providers the human way ("Meta", "Microsoft", "Alibaba") while the backend LLM
|
|
259240
|
+
* list uses wire keys ("llama", "azure_openai"). Comparing the two raw would
|
|
259241
|
+
* render a duplicate card for the same vendor.
|
|
259242
|
+
*/
|
|
259243
|
+
function getProviderName(llmProvider) {
|
|
259244
|
+
var _a;
|
|
259245
|
+
const normalized = (llmProvider !== null && llmProvider !== void 0 ? llmProvider : '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
259246
|
+
return (_a = PROVIDER_NAME_BY_ALIAS[normalized]) !== null && _a !== void 0 ? _a : normalized;
|
|
259247
|
+
}
|
|
259248
|
+
/**
|
|
259249
|
+
* Whether two Ollama model refs name the same model, comparing by base name and
|
|
259250
|
+
* ignoring a trailing `:tag` (so "llama3.2" ≡ "llama3.2:latest", and
|
|
259251
|
+
* "granite4.1:8b" ≡ "granite4.1"). The download state and Ollama's /api/tags may
|
|
259252
|
+
* carry a tag suffix the catalog id doesn't (or vice-versa); an exact `===` then
|
|
259253
|
+
* fails to recognize a row's own in-flight download — the row shows "Download"
|
|
259254
|
+
* with no progress while the pull runs. Base-name matching is safe here because
|
|
259255
|
+
* every catalog model has a unique base (llama3.2, qwen3, mistral, granite4.1,
|
|
259256
|
+
* gpt-oss, gemma4), so it can never light up the wrong row.
|
|
259257
|
+
*/
|
|
259258
|
+
function sameModel(a, b) {
|
|
259259
|
+
const base = (ref) => (ref !== null && ref !== void 0 ? ref : '').toLowerCase().split(':')[0];
|
|
259260
|
+
const ba = base(a);
|
|
259261
|
+
return ba.length > 0 && ba === base(b);
|
|
259262
|
+
}
|
|
259263
|
+
/**
|
|
259264
|
+
* Whether a catalog model id (e.g. "granite4.1:8b") is among the installed
|
|
259265
|
+
* Ollama tags (e.g. "granite4.1:latest").
|
|
259266
|
+
*
|
|
259267
|
+
* Deliberately NOT the profile tab's `isModelInstalled`, which matches an exact
|
|
259268
|
+
* tag or the `<id>:` prefix: that is one-directional and misses a catalog id
|
|
259269
|
+
* that itself carries a tag ("granite4.1:8b" against an installed
|
|
259270
|
+
* "granite4.1:latest"). The picker needs the symmetric base-name comparison of
|
|
259271
|
+
* {@link sameModel} so a pulled model is recognized whichever side wears the tag.
|
|
259272
|
+
*/
|
|
259273
|
+
function isLocalModelInstalled(modelId, installedTags) {
|
|
259274
|
+
return !!(installedTags === null || installedTags === void 0 ? void 0 : installedTags.some((tag) => sameModel(tag, modelId)));
|
|
259275
|
+
}
|
|
259276
|
+
function canSwitchProvider(providers, name) {
|
|
259277
|
+
const provider = providers.find((p) => p.name === name);
|
|
259278
|
+
return !!(provider === null || provider === void 0 ? void 0 : provider.chat_models) && provider.chat_models.length > 0;
|
|
259279
|
+
}
|
|
259280
|
+
/**
|
|
259281
|
+
* Whether we hold a usable LLM key for this provider — its own credentials, or
|
|
259282
|
+
* the tenant's main keys when it is allowed to borrow them. An *absent*
|
|
259283
|
+
* `main_has_credentials` means the backend did not report on the main keys and
|
|
259284
|
+
* is treated as available (matching standalone's `@/lib/utils` and
|
|
259285
|
+
* `claw-sandbox`'s copy); only an explicit `false` rules the main keys out.
|
|
259286
|
+
*/
|
|
259287
|
+
function canSwitchLLm(llm) {
|
|
259288
|
+
if (llm === null || llm === void 0 ? void 0 : llm.has_credentials) {
|
|
259289
|
+
return true;
|
|
259290
|
+
}
|
|
259291
|
+
return ((llm === null || llm === void 0 ? void 0 : llm.can_use_main_keys) &&
|
|
259292
|
+
((llm === null || llm === void 0 ? void 0 : llm.main_has_credentials) === true || (llm === null || llm === void 0 ? void 0 : llm.main_has_credentials) === undefined));
|
|
259293
|
+
}
|
|
259294
|
+
/**
|
|
259295
|
+
* Compares two providers by the label the user actually sees on the card (see
|
|
259296
|
+
* {@link llmProviderLabel}), not by the backend key. Comparison is
|
|
259297
|
+
* case-insensitive (`sensitivity: 'base'`) so casing never produces a
|
|
259298
|
+
* surprising order.
|
|
259299
|
+
*/
|
|
259300
|
+
function compareLLMProvidersByDisplayName(a, b) {
|
|
259301
|
+
return llmProviderLabel(a).localeCompare(llmProviderLabel(b), undefined, {
|
|
259302
|
+
sensitivity: 'base',
|
|
259303
|
+
});
|
|
259304
|
+
}
|
|
259305
|
+
/**
|
|
259306
|
+
* Whether the user can reach *any* model of this provider.
|
|
259307
|
+
*
|
|
259308
|
+
* This is exactly the provider-level half of the per-model `isDisabled` rule in
|
|
259309
|
+
* `llm-tab/llm-provider-modal.tsx`: a model row there is disabled when
|
|
259310
|
+
* `!canSwitchLLm(provider) || !canSwitchProvider(llms, provider.name)`, and both
|
|
259311
|
+
* of those depend only on the provider — so when either fails, *every* model row
|
|
259312
|
+
* of that provider is disabled. `canSwitchProvider` is just "has at least one
|
|
259313
|
+
* `chat_models` entry", which is checked inline here to keep the helper pure and
|
|
259314
|
+
* free of the surrounding provider list.
|
|
259315
|
+
*
|
|
259316
|
+
* `canSwitchLLm` can return `undefined` (its `can_use_main_keys` branch), hence
|
|
259317
|
+
* the explicit `Boolean(...)`.
|
|
259318
|
+
*/
|
|
259319
|
+
function canAccessProvider(provider) {
|
|
259320
|
+
var _a, _b;
|
|
259321
|
+
return Boolean(canSwitchLLm(provider !== null && provider !== void 0 ? provider : {})) && ((_b = (_a = provider === null || provider === void 0 ? void 0 : provider.chat_models) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
259322
|
+
}
|
|
259323
|
+
/**
|
|
259324
|
+
* Orders LLM provider cards as two alphabetical groups: providers the user can
|
|
259325
|
+
* actually use (see {@link canAccessProvider}) first, then the ones they can't —
|
|
259326
|
+
* each group sorted alphabetically by display name.
|
|
259327
|
+
*
|
|
259328
|
+
* The grouping predicate is deliberately the same one the grid grays cards with,
|
|
259329
|
+
* so the two always line up: group 1 renders normally, group 2 renders grayed.
|
|
259330
|
+
* Grouping on credentials alone would let a provider that has a key but ships no
|
|
259331
|
+
* chat models sort into the "usable" group while rendering grayed.
|
|
259332
|
+
*
|
|
259333
|
+
* Pure and non-mutating: RTK Query results are frozen, so the input is copied
|
|
259334
|
+
* before sorting. `Array.prototype.sort` is stable, so providers that tie on
|
|
259335
|
+
* both group and display name keep their original relative order.
|
|
259336
|
+
*/
|
|
259337
|
+
function sortLLMProvidersByCredentials(providers) {
|
|
259338
|
+
return [...providers].sort((a, b) => {
|
|
259339
|
+
const aUsable = canAccessProvider(a);
|
|
259340
|
+
const bUsable = canAccessProvider(b);
|
|
259341
|
+
if (aUsable !== bUsable)
|
|
259342
|
+
return aUsable ? -1 : 1;
|
|
259343
|
+
return compareLLMProvidersByDisplayName(a, b);
|
|
259344
|
+
});
|
|
259345
|
+
}
|
|
259346
|
+
function extractErrorMessage$1(error, fallback) {
|
|
259347
|
+
var _a, _b;
|
|
259348
|
+
const apiError = error;
|
|
259349
|
+
return ((_a = apiError === null || apiError === void 0 ? void 0 : apiError.data) === null || _a === void 0 ? void 0 : _a.error) || ((_b = apiError === null || apiError === void 0 ? void 0 : apiError.error) === null || _b === void 0 ? void 0 : _b.error) || fallback;
|
|
259350
|
+
}
|
|
259351
|
+
|
|
259380
259352
|
function OverlayModal({ open, onClose, title, description, className, children, }) {
|
|
259381
259353
|
const t = useT();
|
|
259382
259354
|
const [mounted, setMounted] = useState(false);
|
|
@@ -270957,7 +270929,7 @@ function resolveLLMTabLabels(override, t) {
|
|
|
270957
270929
|
* line beneath it. One click toggles download ⇄ cancel; once installed a click
|
|
270958
270930
|
* selects it.
|
|
270959
270931
|
*/
|
|
270960
|
-
function LocalModelRow({ name, size, logo, status, progress, disabled = false, disabledReason, errorMessage, onActivate, labels: labelsProp, }) {
|
|
270932
|
+
function LocalModelRow({ name, size, logo, providerLabel, status, progress, disabled = false, disabledReason, errorMessage, onActivate, labels: labelsProp, }) {
|
|
270961
270933
|
const t = useT();
|
|
270962
270934
|
const labels = useMemo(() => labelsProp !== null && labelsProp !== void 0 ? labelsProp : buildLLMTabLabels(t).providerModal.localModel, [labelsProp, t]);
|
|
270963
270935
|
const selected = status === 'selected';
|
|
@@ -270999,16 +270971,15 @@ function LocalModelRow({ name, size, logo, status, progress, disabled = false, d
|
|
|
270999
270971
|
: 'cursor-pointer border-gray-200 hover:border-blue-500 hover:bg-blue-50'), children: [downloading && (jsx("span", { "aria-hidden": "true", "data-testid": "llm-local-model-progress", className: "pointer-events-none absolute inset-y-0 left-0 z-0 bg-blue-500/40 motion-safe:transition-[width] motion-safe:duration-300",
|
|
271000
270972
|
// Minimum width so the bar is visible the moment a download starts
|
|
271001
270973
|
// (progress 0 / "starting"), then tracks real progress.
|
|
271002
|
-
style: { width: `${status === 'starting' ? 6 : Math.max(pct, 6)}%` } })), jsx("span", { className: "relative z-10 flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-lg", children: jsx(
|
|
271003
|
-
grayscale: isBusyDisabled,
|
|
271004
|
-
}), loading: "lazy" }) }), jsxs("span", { className: "relative z-10 flex min-w-0 flex-1 flex-col gap-1.5", children: [jsx("span", { className: "truncate text-sm font-medium text-[#646464] lowercase", children: name }), jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-sm text-gray-500", children: [jsx("span", { className: "flex-shrink-0 rounded bg-gray-100 px-2 py-0.5 text-sm font-medium text-gray-500", children: labels.onDevice }), status === 'not-installed' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { children: size }), jsx(Download, { className: "h-4 w-4", "aria-hidden": "true" })] })), status === 'starting' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { children: labels.starting })] })), status === 'downloading' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsxs("span", { className: "tabular-nums group-hover:hidden group-focus-visible:hidden", children: [pct, "%"] }), jsxs("span", { className: "hidden items-center gap-1 text-blue-600 group-hover:flex group-focus-visible:flex", children: [jsx(X$2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), labels.cancel] })] })), status === 'selected' && (jsxs("span", { className: "flex items-center gap-1 text-blue-600", children: [jsx(Check, { className: "h-4 w-4", "aria-hidden": "true" }), labels.inUse] })), status === 'error' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { className: "truncate text-red-500", children: errorMessage || labels.downloadFailedRetry }), jsx(RotateCcw, { className: "h-4 w-4 flex-shrink-0 text-red-500", "aria-hidden": "true" })] }))] })] })] }));
|
|
270974
|
+
style: { width: `${status === 'starting' ? 6 : Math.max(pct, 6)}%` } })), jsx("span", { "aria-hidden": "true", className: "relative z-10 flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-lg", children: jsx(LLMProviderLogo, { logo: logo, label: providerLabel !== null && providerLabel !== void 0 ? providerLabel : name, alt: "", className: cn({ grayscale: isBusyDisabled }) }) }), jsxs("span", { className: "relative z-10 flex min-w-0 flex-1 flex-col gap-1.5", children: [jsx("span", { className: "truncate text-sm font-medium text-[#646464] lowercase", children: name }), jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-sm text-gray-500", children: [jsx("span", { className: "flex-shrink-0 rounded bg-gray-100 px-2 py-0.5 text-sm font-medium text-gray-500", children: labels.onDevice }), status === 'not-installed' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { children: size }), jsx(Download, { className: "h-4 w-4", "aria-hidden": "true" })] })), status === 'starting' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { children: labels.starting })] })), status === 'downloading' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsxs("span", { className: "tabular-nums group-hover:hidden group-focus-visible:hidden", children: [pct, "%"] }), jsxs("span", { className: "hidden items-center gap-1 text-blue-600 group-hover:flex group-focus-visible:flex", children: [jsx(X$2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), labels.cancel] })] })), status === 'selected' && (jsxs("span", { className: "flex items-center gap-1 text-blue-600", children: [jsx(Check, { className: "h-4 w-4", "aria-hidden": "true" }), labels.inUse] })), status === 'error' && (jsxs(Fragment$1, { children: [jsx("span", { "aria-hidden": "true", children: "\u00B7" }), jsx("span", { className: "truncate text-red-500", children: errorMessage || labels.downloadFailedRetry }), jsx(RotateCcw, { className: "h-4 w-4 flex-shrink-0 text-red-500", "aria-hidden": "true" })] }))] })] })] }));
|
|
271005
270975
|
}
|
|
271006
270976
|
|
|
271007
|
-
function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting, mentorSettings, llms,
|
|
270977
|
+
function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting, mentorSettings, llms, labels: labelsProp, }) {
|
|
271008
270978
|
var _a;
|
|
271009
270979
|
const t = useT();
|
|
271010
270980
|
const labels = React__default.useMemo(() => labelsProp !== null && labelsProp !== void 0 ? labelsProp : buildLLMTabLabels(t).providerModal, [labelsProp, t]);
|
|
271011
270981
|
const [searchQuery, setSearchQuery] = React__default.useState('');
|
|
270982
|
+
const providerLabel = llmProviderLabel(llmProvider);
|
|
271012
270983
|
// On-device model download state (Tauri desktop only; `isAvailable` is false
|
|
271013
270984
|
// on web, which hides every local row below).
|
|
271014
270985
|
const { isAvailable, state: downloadState, ollamaStatus, systemMemory, startDownload, cancelDownload, } = useModelDownload();
|
|
@@ -271197,7 +271168,6 @@ function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting,
|
|
|
271197
271168
|
if (item.kind === 'cloud') {
|
|
271198
271169
|
const llm = item.llm;
|
|
271199
271170
|
const isActive = isCloudActive(llm);
|
|
271200
|
-
const providerDetails = getLLMProviderDetails$1(llmProvider.name, llm.llm_name);
|
|
271201
271171
|
const isDisabled = !switchLLMAllowed || isSelecting || isActive || !switchProviderAllowed;
|
|
271202
271172
|
return (jsxs("button", { "data-model": llm.llm_name, disabled: isDisabled, onClick: () => {
|
|
271203
271173
|
selectCloud(llm.llm_name);
|
|
@@ -271207,15 +271177,15 @@ function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting,
|
|
|
271207
271177
|
'cursor-not-allowed border-gray-100 bg-gray-50': isDisabled && !isActive,
|
|
271208
271178
|
'hover:border-blue-500 hover:bg-blue-50': !isDisabled,
|
|
271209
271179
|
'cursor-not-allowed border-blue-500 bg-blue-50': isActive,
|
|
271210
|
-
}), children: [jsx("span", { className: "flex h-8 w-8 items-center justify-center overflow-hidden rounded-lg", children: jsx(
|
|
271180
|
+
}), children: [jsx("span", { className: "flex h-8 w-8 items-center justify-center overflow-hidden rounded-lg", children: jsx(LLMProviderLogo, { logo: llmProvider.logo, label: providerLabel, alt: labels.providerIconAlt(providerLabel), className: cn({
|
|
271211
271181
|
// `grayscale` alone is a no-op on already-black marks,
|
|
271212
271182
|
// so fade them as well — same rule as the provider grid.
|
|
271213
271183
|
'opacity-40 grayscale': isDisabled && !isActive,
|
|
271214
|
-
})
|
|
271184
|
+
}) }) }), jsx("span", { className: "text-left text-sm font-medium text-gray-900", children: llmModelLabel(llm) })] }, `cloud-${llm.llm_name}`));
|
|
271215
271185
|
}
|
|
271216
271186
|
const m = item.model;
|
|
271217
271187
|
const status = statusFor(m);
|
|
271218
|
-
return (jsx(LocalModelRow, { name: m.name, size: localModelDisplaySize(m), logo:
|
|
271188
|
+
return (jsx(LocalModelRow, { name: m.name, size: localModelDisplaySize(m), logo: llmProvider.logo, providerLabel: providerLabel, status: status, progress: sameModel(downloadingModel, m.id) ? downloadState.progress : 0, onActivate: () => activateLocal(m, status), labels: labels.localModel }, `local-${m.id}`));
|
|
271219
271189
|
}) }), jsx(AlertDialog, { open: !!pendingModel, onOpenChange: (open) => {
|
|
271220
271190
|
if (!open)
|
|
271221
271191
|
setPendingModel(null);
|
|
@@ -271231,7 +271201,7 @@ function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting,
|
|
|
271231
271201
|
}, children: jsxs(AlertDialogContent, { children: [jsxs(AlertDialogHeader, { children: [jsx(AlertDialogTitle, { children: labels.alreadyDownloadingTitle }), jsx(AlertDialogDescription, { children: labels.alreadyDownloadingDescription(busyDownloadName !== null && busyDownloadName !== void 0 ? busyDownloadName : '') })] }), jsx(AlertDialogFooter, { children: jsx(AlertDialogAction, { onClick: () => setBusyDownloadName(null), children: labels.gotIt }) })] }) })] }) }));
|
|
271232
271202
|
}
|
|
271233
271203
|
|
|
271234
|
-
function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverride,
|
|
271204
|
+
function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverride, labels: labelsOverride, }) {
|
|
271235
271205
|
var _a;
|
|
271236
271206
|
const t = useT();
|
|
271237
271207
|
const { tenantKey, mentorId: contextMentorId, username, enableRBAC } = useAgentSettings();
|
|
@@ -271274,8 +271244,8 @@ function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverrid
|
|
|
271274
271244
|
}
|
|
271275
271245
|
// Alphabetical among themselves; the whole local-only block still renders
|
|
271276
271246
|
// after the API providers.
|
|
271277
|
-
return result.sort((a, b) => compareLLMProvidersByDisplayName(a.provider, b.provider
|
|
271278
|
-
}, [llmProviders
|
|
271247
|
+
return result.sort((a, b) => compareLLMProvidersByDisplayName({ name: a.provider }, { name: b.provider }));
|
|
271248
|
+
}, [llmProviders]);
|
|
271279
271249
|
// Providers this device can serve on-device models for, by normalized key.
|
|
271280
271250
|
// Empty off Tauri on purpose: the web has no local runtime, so a zero-model
|
|
271281
271251
|
// server provider must not stay visible just because its NAME happens to
|
|
@@ -271289,7 +271259,7 @@ function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverrid
|
|
|
271289
271259
|
// Two alphabetical groups: providers we have a usable LLM key for first, then
|
|
271290
271260
|
// the ones we don't. Ordering is independent of the search filter below, so it
|
|
271291
271261
|
// holds for whatever the filter leaves.
|
|
271292
|
-
const sortedLLMProviders = React__default.useMemo(() => sortLLMProvidersByCredentials(llmProviders !== null && llmProviders !== void 0 ? llmProviders : []
|
|
271262
|
+
const sortedLLMProviders = React__default.useMemo(() => sortLLMProvidersByCredentials(llmProviders !== null && llmProviders !== void 0 ? llmProviders : []), [llmProviders]);
|
|
271293
271263
|
const [editMentor, { isLoading: isEditingMentor }] = useEditMentorMutation();
|
|
271294
271264
|
const isDisabled = isMentorSettingsLoading || isLoadingLLMProviders || isEditingMentor;
|
|
271295
271265
|
const isLoading = isMentorSettingsLoading || isLoadingLLMProviders;
|
|
@@ -271344,7 +271314,7 @@ function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverrid
|
|
|
271344
271314
|
localProviderKeys.has(getProviderName(model.name));
|
|
271345
271315
|
})
|
|
271346
271316
|
.map((model) => {
|
|
271347
|
-
const
|
|
271317
|
+
const providerLabel = llmProviderLabel(model);
|
|
271348
271318
|
const isActive = !!activeProviderKey && getProviderName(model.name) === activeProviderKey;
|
|
271349
271319
|
// The generated LLM response type doesn't declare the
|
|
271350
271320
|
// credential flags the backend actually sends, so read them
|
|
@@ -271372,29 +271342,28 @@ function AgentLLMTab({ showConfigurationHeader = true, mentorId: mentorIdOverrid
|
|
|
271372
271342
|
// @ts-ignore - can_use_main_keys property does not exist on LLMResponse type
|
|
271373
271343
|
can_use_main_keys: model === null || model === void 0 ? void 0 : model.can_use_main_keys,
|
|
271374
271344
|
});
|
|
271375
|
-
}, children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children: jsx(
|
|
271345
|
+
}, children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children: jsx(LLMProviderLogo, { logo: model.logo, label: providerLabel, alt: labels.providerLogoAlt(providerLabel), className: cn({
|
|
271376
271346
|
// `grayscale` only desaturates, so already-black
|
|
271377
271347
|
// marks (OpenAI, xAI) looked untouched. Fading is
|
|
271378
271348
|
// what actually reads as inactive at any hue.
|
|
271379
271349
|
'opacity-40 grayscale': isGrayed,
|
|
271380
|
-
})
|
|
271350
|
+
}) }) }), jsx("span", { className: "text-sm font-medium text-gray-900", children: providerLabel })] }, model.id));
|
|
271381
271351
|
}), localOnlyProviders.map((lp) => {
|
|
271382
|
-
const details = getLLMProviderDetails$1(lp.provider);
|
|
271383
271352
|
return (jsxs("div", { "data-testid": "llm-provider-card", "data-provider": lp.provider, "data-disabled": "false", className: cn('flex cursor-pointer items-center gap-3 rounded-lg border border-gray-200 bg-white p-4 shadow-sm transition-shadow hover:shadow-md', { 'border-blue-500': lp.key === activeProviderKey }), onClick: () => {
|
|
271384
271353
|
if (isDisabled || disabled)
|
|
271385
271354
|
return;
|
|
271386
271355
|
setSelectedLLMProvider({
|
|
271387
271356
|
id: -1,
|
|
271388
271357
|
name: lp.provider,
|
|
271389
|
-
logo:
|
|
271358
|
+
logo: null,
|
|
271390
271359
|
description: null,
|
|
271391
271360
|
chat_models: [],
|
|
271392
271361
|
});
|
|
271393
|
-
}, children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children: jsx(
|
|
271362
|
+
}, children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children: jsx(LLMProviderLogo, { logo: null, label: lp.provider, alt: labels.providerLogoAlt(lp.provider) }) }), jsx("span", { className: "text-sm font-medium text-gray-900", children: lp.provider })] }, `local-${lp.key}`));
|
|
271394
271363
|
})] })) })), selectedLLMProvider && mentorSettings && (jsx(LLMProviderModal, { isOpen: true, onClose: () => setSelectedLLMProvider(null), onSelect: updateMentorLLM, llmProvider: selectedLLMProvider, isSelecting: isEditingMentor, mentorSettings: {
|
|
271395
271364
|
llm_name: mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.llm_name,
|
|
271396
271365
|
llm_provider: mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.llm_provider,
|
|
271397
|
-
}, llms: (llmProviders !== null && llmProviders !== void 0 ? llmProviders : []),
|
|
271366
|
+
}, llms: (llmProviders !== null && llmProviders !== void 0 ? llmProviders : []), labels: labels.providerModal }))] })] })] }));
|
|
271398
271367
|
}
|
|
271399
271368
|
|
|
271400
271369
|
function useTools({ labels }) {
|
|
@@ -275045,8 +275014,8 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
275045
275014
|
/**
|
|
275046
275015
|
* Provider chips, ordered by lowercasing each label and then sorting
|
|
275047
275016
|
* alphabetically, so a newly added provider slots itself in without a
|
|
275048
|
-
* hand-edit.
|
|
275049
|
-
*
|
|
275017
|
+
* hand-edit. The vendor logos are shipped under this package's `public/`
|
|
275018
|
+
* and must be copied into the host's static-root.
|
|
275050
275019
|
* Browser falls back to a Lucide globe — there's no vendor logo for
|
|
275051
275020
|
* "device speech engine".
|
|
275052
275021
|
*/
|
|
@@ -281151,8 +281120,8 @@ function StartExperimentModal({ isOpen, onClose, tenantKey, username, mentorUniq
|
|
|
281151
281120
|
return (jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: jsxs(DialogContent, { "aria-label": "start-evaluation", className: "w-full max-w-md", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: labels.title }), jsx(DialogDescription, { children: labels.description })] }), jsxs("div", { className: "grid gap-4 mt-3", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { children: labels.benchmarkLabel }), jsx("div", { className: "rounded-md border border-gray-200 bg-gray-50 px-3 py-2 text-sm font-medium text-gray-800", children: datasetName })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "experiment-name", children: labels.experimentNameLabel }), jsx(Input, { id: "experiment-name", value: runName, onChange: (event) => setRunName(event.target.value), placeholder: labels.experimentNamePlaceholder, maxLength: 255, disabled: isStarting })] })] }), jsxs(DialogFooter, { className: "mt-4", children: [jsx(Button$1, { variant: "outline", onClick: handleClose, disabled: isStarting, children: labels.cancel }), jsxs(Button$1, { onClick: handleStart, disabled: isStarting, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: [isStarting && jsx(LoaderCircle, { className: "h-4 w-4 mr-1 animate-spin" }), labels.start] })] })] }) }));
|
|
281152
281121
|
}
|
|
281153
281122
|
|
|
281154
|
-
function EvaluateLlmPicker({ tenantKey, username, mentorId, value, onChange,
|
|
281155
|
-
var _a, _b;
|
|
281123
|
+
function EvaluateLlmPicker({ tenantKey, username, mentorId, value, onChange, placeholder, pickerTitle, pickerDescription, selectorAriaLabel, searchPlaceholder, emptyMessage, logoAlt, disabled, }) {
|
|
281124
|
+
var _a, _b, _c;
|
|
281156
281125
|
const [showProviders, setShowProviders] = React__default.useState(false);
|
|
281157
281126
|
const [selectedProvider, setSelectedProvider] = React__default.useState(null);
|
|
281158
281127
|
const [providerSearch, setProviderSearch] = React__default.useState('');
|
|
@@ -281163,7 +281132,14 @@ function EvaluateLlmPicker({ tenantKey, username, mentorId, value, onChange, get
|
|
|
281163
281132
|
mentorId,
|
|
281164
281133
|
}, { skip: !tenantKey || !username || !mentorId });
|
|
281165
281134
|
const filteredProviders = React__default.useMemo(() => (llmProviders !== null && llmProviders !== void 0 ? llmProviders : []).filter((model) => model.name.toLowerCase().includes(providerSearch.toLowerCase())), [llmProviders, providerSearch]);
|
|
281166
|
-
|
|
281135
|
+
// The selected provider's backend row, for its logo and label; `undefined`
|
|
281136
|
+
// until the catalogue loads or when the stored key no longer matches one.
|
|
281137
|
+
const currentProvider = value
|
|
281138
|
+
? llmProviders === null || llmProviders === void 0 ? void 0 : llmProviders.find((model) => model.name === value.llm_provider)
|
|
281139
|
+
: undefined;
|
|
281140
|
+
const currentLabel = currentProvider
|
|
281141
|
+
? llmProviderLabel(currentProvider)
|
|
281142
|
+
: ((_a = value === null || value === void 0 ? void 0 : value.llm_provider) !== null && _a !== void 0 ? _a : '');
|
|
281167
281143
|
const handleProviderClick = (model) => {
|
|
281168
281144
|
setSelectedProvider({
|
|
281169
281145
|
id: model.id,
|
|
@@ -281184,17 +281160,17 @@ function EvaluateLlmPicker({ tenantKey, username, mentorId, value, onChange, get
|
|
|
281184
281160
|
setSelectedProvider(null);
|
|
281185
281161
|
setShowProviders(false);
|
|
281186
281162
|
};
|
|
281187
|
-
return (jsxs(Fragment$1, { children: [jsxs(Button$1, { type: "button", variant: "ghost", disabled: disabled, onClick: () => setShowProviders(true), "aria-label": selectorAriaLabel, className: "flex h-9 cursor-pointer items-center gap-2 px-2 text-sm font-medium text-[#646464] transition-colors hover:text-[#484848] disabled:opacity-50", children: [(
|
|
281188
|
-
const
|
|
281163
|
+
return (jsxs(Fragment$1, { children: [jsxs(Button$1, { type: "button", variant: "ghost", disabled: disabled, onClick: () => setShowProviders(true), "aria-label": selectorAriaLabel, className: "flex h-9 cursor-pointer items-center gap-2 px-2 text-sm font-medium text-[#646464] transition-colors hover:text-[#484848] disabled:opacity-50", children: [(currentProvider === null || currentProvider === void 0 ? void 0 : currentProvider.logo) ? (jsx(LLMProviderLogo, { logo: currentProvider.logo, label: currentLabel, alt: logoAlt.replace('{name}', currentLabel), size: 20, className: "h-5 w-5 flex-shrink-0" })) : (jsx(Bot, { className: "h-5 w-5 flex-shrink-0 text-gray-400" })), jsx("span", { className: "max-w-[220px] truncate", children: (value === null || value === void 0 ? void 0 : value.llm_name) || currentLabel || placeholder }), jsx(ChevronDown, { className: "h-4 w-4 text-gray-500" })] }), jsx(Dialog, { open: showProviders, onOpenChange: (open) => !open && setShowProviders(false), children: jsxs(DialogContent, { "aria-label": "evaluate-llm-picker", className: "max-h-[90vh] w-full max-w-3xl overflow-y-auto", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: pickerTitle }), jsx(DialogDescription, { children: pickerDescription })] }), jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" }), jsx(Input, { placeholder: searchPlaceholder, className: "pl-9", value: providerSearch, onChange: (event) => setProviderSearch(event.target.value) })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-10", children: jsx(Spinner, {}) })) : (jsxs("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3", children: [filteredProviders.map((model) => {
|
|
281164
|
+
const label = llmProviderLabel(model);
|
|
281189
281165
|
const isCurrent = (value === null || value === void 0 ? void 0 : value.llm_provider) === model.name;
|
|
281190
|
-
return (jsxs("button", { type: "button", onClick: () => handleProviderClick(model), className: cn('flex cursor-pointer items-center gap-3 rounded-lg border border-gray-200 bg-white p-3 text-left shadow-sm transition-shadow hover:shadow-md', isCurrent && 'border-blue-500'), children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children:
|
|
281166
|
+
return (jsxs("button", { type: "button", onClick: () => handleProviderClick(model), className: cn('flex cursor-pointer items-center gap-3 rounded-lg border border-gray-200 bg-white p-3 text-left shadow-sm transition-shadow hover:shadow-md', isCurrent && 'border-blue-500'), children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children: jsx(LLMProviderLogo, { logo: model.logo, label: label, alt: logoAlt.replace('{name}', label) }) }), jsx("span", { className: "truncate text-sm font-medium text-gray-900", children: label })] }, model.id));
|
|
281191
281167
|
}), filteredProviders.length === 0 && (jsx("p", { className: "col-span-full py-6 text-center text-sm text-gray-500", children: emptyMessage }))] }))] }) }), selectedProvider && (jsx(LLMProviderModal, { isOpen: true, onClose: () => setSelectedProvider(null), onSelect: handleSelect, llmProvider: selectedProvider, isSelecting: false, mentorSettings: {
|
|
281192
|
-
llm_name: (
|
|
281193
|
-
llm_provider: (
|
|
281194
|
-
}, llms: (llmProviders !== null && llmProviders !== void 0 ? llmProviders : [])
|
|
281168
|
+
llm_name: (_b = value === null || value === void 0 ? void 0 : value.llm_name) !== null && _b !== void 0 ? _b : '',
|
|
281169
|
+
llm_provider: (_c = value === null || value === void 0 ? void 0 : value.llm_provider) !== null && _c !== void 0 ? _c : '',
|
|
281170
|
+
}, llms: (llmProviders !== null && llmProviders !== void 0 ? llmProviders : []) }))] }));
|
|
281195
281171
|
}
|
|
281196
281172
|
|
|
281197
|
-
function LlmJudgeModal({ isOpen, onClose, tenantKey, username, mentorId, datasetName, runName, labels,
|
|
281173
|
+
function LlmJudgeModal({ isOpen, onClose, tenantKey, username, mentorId, datasetName, runName, labels, }) {
|
|
281198
281174
|
const [criteria, setCriteria] = React__default.useState('');
|
|
281199
281175
|
const [scoreName, setScoreName] = React__default.useState('');
|
|
281200
281176
|
const [llm, setLlm] = React__default.useState(null);
|
|
@@ -281246,7 +281222,7 @@ function LlmJudgeModal({ isOpen, onClose, tenantKey, username, mentorId, dataset
|
|
|
281246
281222
|
if (!Number.isNaN(parsed)) {
|
|
281247
281223
|
setMaxConcurrency(Math.min(20, Math.max(1, parsed)));
|
|
281248
281224
|
}
|
|
281249
|
-
}, disabled: isSubmitting, className: "mt-2" })] })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Label$1, { className: "m-0", children: labels.llmLabel }), jsx(EvaluateLlmPicker, { tenantKey: tenantKey, username: username, mentorId: mentorId, value: llm, onChange: setLlm,
|
|
281225
|
+
}, disabled: isSubmitting, className: "mt-2" })] })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Label$1, { className: "m-0", children: labels.llmLabel }), jsx(EvaluateLlmPicker, { tenantKey: tenantKey, username: username, mentorId: mentorId, value: llm, onChange: setLlm, placeholder: labels.selectLlmPlaceholder, pickerTitle: labels.pickerTitle, pickerDescription: labels.pickerDescription, selectorAriaLabel: labels.pickerSelectorAriaLabel, searchPlaceholder: labels.pickerSearchPlaceholder, emptyMessage: labels.pickerEmpty, logoAlt: labels.pickerLogoAlt, disabled: isSubmitting })] })] }), jsxs(DialogFooter, { className: "mt-4", children: [jsx(Button$1, { variant: "outline", onClick: handleClose, disabled: isSubmitting, children: labels.cancel }), jsxs(Button$1, { onClick: handleSubmit, disabled: isSubmitting || !criteria.trim() || !scoreName.trim() || !llm, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: [isSubmitting && jsx(LoaderCircle, { className: "h-4 w-4 mr-1 animate-spin" }), labels.submit] })] })] }) }));
|
|
281250
281226
|
}
|
|
281251
281227
|
|
|
281252
281228
|
function renderItemText(value) {
|
|
@@ -281366,7 +281342,7 @@ function ManualScoreRow({ tenantKey, username, datasetName, runName, traceId, ru
|
|
|
281366
281342
|
}
|
|
281367
281343
|
/** Poll cadence while the run (or one of its reviews) is still producing data. */
|
|
281368
281344
|
const ACTIVE_POLL_INTERVAL_MS = 10000;
|
|
281369
|
-
function ExperimentDetailModal({ isOpen, onClose, tenantKey, username, mentorId, datasetName, runName, labels,
|
|
281345
|
+
function ExperimentDetailModal({ isOpen, onClose, tenantKey, username, mentorId, datasetName, runName, labels, }) {
|
|
281370
281346
|
var _a;
|
|
281371
281347
|
const [showJudge, setShowJudge] = React__default.useState(false);
|
|
281372
281348
|
const [expandedTrace, setExpandedTrace] = React__default.useState(null);
|
|
@@ -281393,6 +281369,15 @@ function ExperimentDetailModal({ isOpen, onClose, tenantKey, username, mentorId,
|
|
|
281393
281369
|
page: 1,
|
|
281394
281370
|
limit: 50,
|
|
281395
281371
|
}, { refetchOnMountOrArgChange: true, pollingInterval });
|
|
281372
|
+
// Provider rows, for the logo/label next to each review's judging LLM. Same
|
|
281373
|
+
// args as the judge picker's query, so RTK Query serves both from one cache
|
|
281374
|
+
// entry.
|
|
281375
|
+
const { data: llmProviders } = useGetLlmsQuery({
|
|
281376
|
+
org: tenantKey,
|
|
281377
|
+
// @ts-ignore - userId not on generated signature
|
|
281378
|
+
userId: username,
|
|
281379
|
+
mentorId,
|
|
281380
|
+
}, { skip: !tenantKey || !username || !mentorId });
|
|
281396
281381
|
const runItems = (_a = run === null || run === void 0 ? void 0 : run.dataset_run_items) !== null && _a !== void 0 ? _a : [];
|
|
281397
281382
|
// The backend returns run items in nondeterministic order (the eval store
|
|
281398
281383
|
// is eventually consistent), so the raw order can shift between refetches.
|
|
@@ -281485,7 +281470,7 @@ function ExperimentDetailModal({ isOpen, onClose, tenantKey, username, mentorId,
|
|
|
281485
281470
|
: labels.detailModal.tracesSuffixPlural, reviewCounts.pending > 0 && (jsxs("span", { className: "ml-2 inline-flex items-center gap-1 text-xs text-blue-600", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), reviewCounts.pending, " ", labels.detailModal.reviewsRunningLabel] })), reviewCounts.completed > 0 && (jsxs("span", { className: "ml-2 text-xs text-gray-500", children: ["\u00B7 ", reviewCounts.completed, " ", labels.detailModal.reviewsCompletedLabel] })), reviewCounts.failed > 0 && (jsxs("span", { className: "ml-2 text-xs text-red-500", children: ["\u00B7 ", reviewCounts.failed, " ", labels.detailModal.reviewsFailedLabel] }))] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { size: "sm", variant: "outline", onClick: () => {
|
|
281486
281471
|
refetchRun();
|
|
281487
281472
|
refetchReviews();
|
|
281488
|
-
}, disabled: isRunFetching || isReviewsFetching, "aria-label": labels.detailModal.refresh, title: labels.detailModal.refresh, children: jsx(RefreshCw, { className: isRunFetching || isReviewsFetching ? 'h-4 w-4 animate-spin' : 'h-4 w-4' }) }), jsxs(Button$1, { size: "sm", onClick: () => setShowJudge(true), disabled: runItems.length === 0, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: [jsx(Sparkles, { className: "h-4 w-4 mr-1" }), labels.detailModal.newReview] })] })] }), jsx("p", { className: "text-xs text-gray-500", children: labels.detailModal.reviewsHint })] }), allReviews.length > 0 && (jsx(ReviewsList, { reviews: allReviews, runItems: runItems, labels: labels,
|
|
281473
|
+
}, disabled: isRunFetching || isReviewsFetching, "aria-label": labels.detailModal.refresh, title: labels.detailModal.refresh, children: jsx(RefreshCw, { className: isRunFetching || isReviewsFetching ? 'h-4 w-4 animate-spin' : 'h-4 w-4' }) }), jsxs(Button$1, { size: "sm", onClick: () => setShowJudge(true), disabled: runItems.length === 0, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: [jsx(Sparkles, { className: "h-4 w-4 mr-1" }), labels.detailModal.newReview] })] })] }), jsx("p", { className: "text-xs text-gray-500", children: labels.detailModal.reviewsHint })] }), allReviews.length > 0 && (jsx(ReviewsList, { reviews: allReviews, runItems: runItems, labels: labels, llmProviders: llmProviders !== null && llmProviders !== void 0 ? llmProviders : [] })), isRunLoading ? (jsx("div", { className: "flex justify-center items-center h-40", children: jsx(Spinner, {}) })) : (jsxs("div", { className: "space-y-3", children: [runItems.length === 0 && (jsx("div", { className: "rounded-md border border-gray-200 bg-gray-50 p-6 text-center text-sm text-gray-600", children: labels.detailModal.waitingHint })), sortedRunItems.map((item) => {
|
|
281489
281474
|
var _a;
|
|
281490
281475
|
// Sort scores by created_at so the order is stable across refetches.
|
|
281491
281476
|
const scores = [...((_a = item.scores) !== null && _a !== void 0 ? _a : [])].sort((a, b) => {
|
|
@@ -281502,7 +281487,7 @@ function ExperimentDetailModal({ isOpen, onClose, tenantKey, username, mentorId,
|
|
|
281502
281487
|
var _a, _b;
|
|
281503
281488
|
return (jsxs("div", { className: "group inline-flex items-center gap-1.5 rounded-full border border-gray-200 bg-gray-50 px-2 py-1 text-xs", title: (_a = score.comment) !== null && _a !== void 0 ? _a : undefined, children: [jsx("span", { className: "font-medium text-gray-700", children: score.name }), jsx("span", { className: "text-gray-600", children: (_b = score.string_value) !== null && _b !== void 0 ? _b : score.value }), jsx("button", { type: "button", "aria-label": labels.detailModal.removeScoreAriaLabel, onClick: () => handleDeleteScore(score.id), className: "opacity-50 transition-opacity group-hover:opacity-100", children: jsx(Trash2, { className: "h-3 w-3 text-red-500" }) })] }, score.id));
|
|
281504
281489
|
}) })) : (jsx("p", { className: "text-xs text-gray-500", children: labels.detailModal.noScoresHint }))] }), jsxs("div", { className: "space-y-1 pt-2 border-t border-gray-100", children: [jsx("p", { className: "text-xs font-medium text-gray-500", children: labels.detailModal.addScoreHeading }), jsx(ManualScoreRow, { tenantKey: tenantKey, username: username, datasetName: datasetName, runName: runName, traceId: item.trace_id, runId: (run === null || run === void 0 ? void 0 : run.id) || undefined, labels: labels.detailModal })] })] }))] }, item.id));
|
|
281505
|
-
})] })), showJudge && run && (jsx(LlmJudgeModal, { isOpen: showJudge, onClose: () => setShowJudge(false), tenantKey: tenantKey, username: username, mentorId: mentorId, datasetName: datasetName, runName: runName, labels: labels.evaluateModal
|
|
281490
|
+
})] })), showJudge && run && (jsx(LlmJudgeModal, { isOpen: showJudge, onClose: () => setShowJudge(false), tenantKey: tenantKey, username: username, mentorId: mentorId, datasetName: datasetName, runName: runName, labels: labels.evaluateModal }))] }) }));
|
|
281506
281491
|
}
|
|
281507
281492
|
/**
|
|
281508
281493
|
* Reviews list — surfaces every LLM-as-Judge task recorded against this
|
|
@@ -281514,14 +281499,14 @@ function ExperimentDetailModal({ isOpen, onClose, tenantKey, username, mentorId,
|
|
|
281514
281499
|
* Per row: status badge, the score this review is producing, the LLM
|
|
281515
281500
|
* doing the judging, when it started, and (on failure) the error.
|
|
281516
281501
|
*/
|
|
281517
|
-
function ReviewsList({ reviews, runItems, labels,
|
|
281502
|
+
function ReviewsList({ reviews, runItems, labels, llmProviders, }) {
|
|
281518
281503
|
const [expandedReview, setExpandedReview] = React__default.useState(null);
|
|
281519
281504
|
return (jsxs("div", { className: "mb-4 rounded-md border border-gray-200", children: [jsx("div", { className: "px-4 py-2 border-b border-gray-200 bg-gray-50", children: jsx("h4", { className: "text-xs font-semibold uppercase tracking-wide text-gray-600", children: labels.detailModal.reviewsHeading }) }), jsx("ul", { className: "divide-y divide-gray-100", children: reviews.map((review) => {
|
|
281520
|
-
var _a, _b, _c, _d
|
|
281505
|
+
var _a, _b, _c, _d;
|
|
281521
281506
|
const provider = (_a = review.request_metadata) === null || _a === void 0 ? void 0 : _a.llm_provider;
|
|
281522
281507
|
const llmName = (_b = review.request_metadata) === null || _b === void 0 ? void 0 : _b.llm_name;
|
|
281523
281508
|
const criteria = (_c = review.request_metadata) === null || _c === void 0 ? void 0 : _c.criteria;
|
|
281524
|
-
const
|
|
281509
|
+
const providerRow = provider ? llmProviders.find((p) => p.name === provider) : undefined;
|
|
281525
281510
|
const started = parseEvalDate((_d = review.started_at) !== null && _d !== void 0 ? _d : review.created_at);
|
|
281526
281511
|
const completed = parseEvalDate(review.completed_at);
|
|
281527
281512
|
const rowKey = review.task_id || `${review.id}`;
|
|
@@ -281538,7 +281523,7 @@ function ReviewsList({ reviews, runItems, labels, getLLMProviderDetails, }) {
|
|
|
281538
281523
|
.map((score) => ({ score, questionText }));
|
|
281539
281524
|
})
|
|
281540
281525
|
: [];
|
|
281541
|
-
return (jsxs("li", { children: [jsxs("button", { type: "button", onClick: () => setExpandedReview(isExpanded ? null : rowKey), "aria-expanded": isExpanded, "aria-label": labels.detailModal.reviewDetailsAriaLabel, className: "w-full px-4 py-3 flex flex-col gap-2 text-left hover:bg-gray-50 sm:flex-row sm:items-start sm:justify-between", children: [jsxs("div", { className: "min-w-0 flex-1", children: [jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [jsx(ChevronDown, { className: cn('h-4 w-4 flex-shrink-0 text-gray-400 transition-transform', isExpanded && 'rotate-180') }), jsx(ReviewStatusBadge, { status: review.status, labels: labels.detailModal.reviewStatus }), jsx("span", { className: "text-sm font-medium text-gray-900 truncate", children: review.score_name || labels.detailModal.reviewUnnamedScore })] }), criteria && !isExpanded && (jsx("p", { className: "text-xs text-gray-600 mt-1 line-clamp-2", children: criteria })), review.error_message && !isExpanded && (jsx("p", { className: "text-xs text-red-600 mt-1 line-clamp-2", children: review.error_message }))] }), jsxs("div", { className: "flex flex-col items-end gap-1 text-xs text-gray-500 sm:min-w-[12rem]", children: [(
|
|
281526
|
+
return (jsxs("li", { children: [jsxs("button", { type: "button", onClick: () => setExpandedReview(isExpanded ? null : rowKey), "aria-expanded": isExpanded, "aria-label": labels.detailModal.reviewDetailsAriaLabel, className: "w-full px-4 py-3 flex flex-col gap-2 text-left hover:bg-gray-50 sm:flex-row sm:items-start sm:justify-between", children: [jsxs("div", { className: "min-w-0 flex-1", children: [jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [jsx(ChevronDown, { className: cn('h-4 w-4 flex-shrink-0 text-gray-400 transition-transform', isExpanded && 'rotate-180') }), jsx(ReviewStatusBadge, { status: review.status, labels: labels.detailModal.reviewStatus }), jsx("span", { className: "text-sm font-medium text-gray-900 truncate", children: review.score_name || labels.detailModal.reviewUnnamedScore })] }), criteria && !isExpanded && (jsx("p", { className: "text-xs text-gray-600 mt-1 line-clamp-2", children: criteria })), review.error_message && !isExpanded && (jsx("p", { className: "text-xs text-red-600 mt-1 line-clamp-2", children: review.error_message }))] }), jsxs("div", { className: "flex flex-col items-end gap-1 text-xs text-gray-500 sm:min-w-[12rem]", children: [(providerRow === null || providerRow === void 0 ? void 0 : providerRow.logo) ? (jsxs("span", { className: "inline-flex items-center gap-1", children: [jsx("img", { src: providerRow.logo, alt: llmProviderLabel(providerRow), className: "h-3 w-3" }), llmName !== null && llmName !== void 0 ? llmName : provider] })) : llmName || provider ? (jsx("span", { children: llmName !== null && llmName !== void 0 ? llmName : provider })) : null, completed
|
|
281542
281527
|
? `${labels.detailModal.reviewFinishedPrefix} ${formatDistanceToNow(completed, { addSuffix: true })}`
|
|
281543
281528
|
: started
|
|
281544
281529
|
? `${labels.detailModal.reviewStartedPrefix} ${formatDistanceToNow(started, { addSuffix: true })}`
|
|
@@ -281900,7 +281885,7 @@ function AgentEvaluationTab({ userIsStudent: userIsStudentProp, ...props }) {
|
|
|
281900
281885
|
return null;
|
|
281901
281886
|
return jsx(AgentEvaluationTabContent, { ...props });
|
|
281902
281887
|
}
|
|
281903
|
-
function AgentEvaluationTabContent({
|
|
281888
|
+
function AgentEvaluationTabContent({ labels: labelsOverride, PaginationComponent, }) {
|
|
281904
281889
|
var _a, _b;
|
|
281905
281890
|
const { tenantKey, mentorId, username } = useAgentSettings();
|
|
281906
281891
|
const dispatch = useDispatch();
|
|
@@ -282051,7 +282036,7 @@ function AgentEvaluationTabContent({ getLLMProviderDetails, labels: labelsOverri
|
|
|
282051
282036
|
}), children: [jsx(Trash2, { className: "mr-2 h-4 w-4" }), labels.actions.delete] })] })] }) })] }, (_b = (_a = run.task_record_id) !== null && _a !== void 0 ? _a : run.id) !== null && _b !== void 0 ? _b : run.name));
|
|
282052
282037
|
}), runs.length === 0 && (jsx(TableRow$1, { children: jsx(TableCell$1, { colSpan: 5, className: "p-6 text-center text-sm text-gray-500", children: labels.table.emptyState.replace('{dataset}', selectedBenchmark) }) }))] })] })) }) })), selectedBenchmark &&
|
|
282053
282038
|
totalPages > 1 &&
|
|
282054
|
-
(PaginationComponent ? (jsx(PaginationComponent, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isRunsLoading })) : (jsx(AdvancedPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage }))), showManageBenchmarks && (jsx(Dialog, { open: showManageBenchmarks, onOpenChange: setShowManageBenchmarks, children: jsxs(DialogContent, { "aria-label": "manage-benchmarks", className: "max-w-4xl max-h-[85vh] overflow-y-auto", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: labels.manageBenchmarksModal.title }), jsx(DialogDescription, { children: labels.manageBenchmarksModal.description })] }), jsx(BenchmarksTab, { tenantKey: tenantKey, username: username })] }) })), showStart && (jsx(StartExperimentModal, { isOpen: showStart, onClose: () => setShowStart(false), tenantKey: tenantKey, username: username, mentorUniqueId: mentorId, datasetName: selectedBenchmark, onStarted: () => setPage(1), labels: labels.startExperimentModal })), selectedRun && (jsx(ExperimentDetailModal, { isOpen: !!selectedRun, onClose: () => setSelectedRun(null), tenantKey: tenantKey, username: username, mentorId: mentorId, datasetName: selectedRun.datasetName, runName: selectedRun.runName, labels: labels
|
|
282039
|
+
(PaginationComponent ? (jsx(PaginationComponent, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isRunsLoading })) : (jsx(AdvancedPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage }))), showManageBenchmarks && (jsx(Dialog, { open: showManageBenchmarks, onOpenChange: setShowManageBenchmarks, children: jsxs(DialogContent, { "aria-label": "manage-benchmarks", className: "max-w-4xl max-h-[85vh] overflow-y-auto", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: labels.manageBenchmarksModal.title }), jsx(DialogDescription, { children: labels.manageBenchmarksModal.description })] }), jsx(BenchmarksTab, { tenantKey: tenantKey, username: username })] }) })), showStart && (jsx(StartExperimentModal, { isOpen: showStart, onClose: () => setShowStart(false), tenantKey: tenantKey, username: username, mentorUniqueId: mentorId, datasetName: selectedBenchmark, onStarted: () => setPage(1), labels: labels.startExperimentModal })), selectedRun && (jsx(ExperimentDetailModal, { isOpen: !!selectedRun, onClose: () => setSelectedRun(null), tenantKey: tenantKey, username: username, mentorId: mentorId, datasetName: selectedRun.datasetName, runName: selectedRun.runName, labels: labels })), judgeRun && (jsx(LlmJudgeModal, { isOpen: !!judgeRun, onClose: () => setJudgeRun(null), tenantKey: tenantKey, username: username, mentorId: mentorId, datasetName: judgeRun.datasetName, runName: judgeRun.runName, labels: labels.evaluateModal })), deleteRun && (jsx(DeleteExperimentModal, { isOpen: !!deleteRun, onClose: () => setDeleteRun(null), tenantKey: tenantKey, username: username, datasetName: deleteRun.datasetName, runName: deleteRun.runName, labels: labels.deleteModal }))] })] }));
|
|
282055
282040
|
}
|
|
282056
282041
|
|
|
282057
282042
|
const CUSTOM_AGENTS_LIMIT = 6;
|
|
@@ -338443,5 +338428,5 @@ var index_es = /*#__PURE__*/Object.freeze({
|
|
|
338443
338428
|
vectorsRatio: vectorsRatio
|
|
338444
338429
|
});
|
|
338445
338430
|
|
|
338446
|
-
export { AGENT_ACCESS_TAB_LABELS, AGENT_ANALYTICS_TAB_LABELS, AGENT_API_TAB_LABELS, AGENT_DATASETS_TAB_LABELS, AGENT_DISCLAIMERS_TAB_LABELS, AGENT_EMBED_TAB_LABELS, AGENT_EVALUATION_TAB_LABELS, AGENT_GRADER_TAB_LABELS, AGENT_HISTORY_TAB_LABELS, AGENT_HUMAN_SUPPORT_TAB_LABELS, AGENT_LLM_TAB_LABELS, AGENT_LTI_TAB_LABELS, AGENT_MEMORY_TAB_LABELS, AGENT_PICKER_LABELS, AGENT_PRIVACY_TAB_LABELS, AGENT_PROMPTS_TAB_LABELS, AGENT_SAFETY_TAB_LABELS, AGENT_SCREENSHARE_TAB_LABELS, AGENT_SEARCH_LABELS, AGENT_SETTINGS_TAB_LABELS, AGENT_SKILLS_TAB_LABELS, AGENT_SPEND_CAPS_TAB_LABELS, AGENT_TASKS_TAB_LABELS, AGENT_TOOLS_TAB_LABELS, AGENT_VOICE_TAB_LABELS, Account, AgentAccessTab, AgentAnalyticsTab, AgentApiTab, AgentCard, AgentDatasetsTab, AgentDisclaimersTab, AgentEmbedTab, AgentEmptyState, AgentEvaluationTab, AgentGraderTab, AgentHistoryTab, AgentHumanSupportTab, AgentLLMTab, AgentLtiTab, AgentMemoryTab, AgentPrivacyTab, AgentPromptsTab, AgentSafetyTab, AgentScreenShareTab, AgentSearch, AgentSearchFilters, AgentSearchInput, AgentSettingsProvider, AgentSettingsTab, AgentSkillsTab, AgentSpendCapsTab, AgentTasksTab, AgentToolsTab, AgentVoiceTab, AppSidebar, CATALOGS, Chat, ClientErrorPage, ConversationStarters$1 as ConversationStarters, CopyButton, CopyMentorModal, CourseBox, CourseContentLayout, CourseContentTabPage, CreatePathwayModal, CredentialDetailModal, CredentialMiniBox, DEFAULT_ANALYTICS_HUB_TABS, DEFAULT_LOCALE, DeleteMentorModal, EMPTY_PROGRAM_SETTINGS_FORM, EdxIframe, ErrorPage, GRADING_TOOL_NAME, GreetingMethod, LLMProviderModal, LocalModelRow, McpTab, MediaBox, MentorSelectionGrid, NavBar, OrganizationTab, PLATFORM_SIDEBAR_FLYOUT_ITEM_COLOR, PLATFORM_SIDEBAR_FLYOUT_TITLE_COLOR, PLATFORM_SIDEBAR_NAV_ACTIVE_BG_OPEN, PLATFORM_SIDEBAR_NAV_MUTED, PathwayDetailModal, PlatformAccountSheet, PlatformSidebar, PlatformSidebarCollapsedLabelFlyout, PlatformSidebarCollapsedNavFlyout, PlatformSidebarFooter, PlatformSidebarNavDivider, PlatformSidebarNavSection, PlatformSidebarSubNavItem, ProfileInfoCards, ProfileTabs, ProgramDetailModal, ProjectsSidebarDropdown, SPEND_CAPS_SUB_TABS, SUPPORTED_LOCALES, SidebarInset, SidebarProvider, SidebarTrigger, SpendCapUsage, SsoLogin, StarButton, UserProfileDropdown, UserProfileModal, WebContainersI18nProvider, formatDateString, getCatalog,
|
|
338431
|
+
export { AGENT_ACCESS_TAB_LABELS, AGENT_ANALYTICS_TAB_LABELS, AGENT_API_TAB_LABELS, AGENT_DATASETS_TAB_LABELS, AGENT_DISCLAIMERS_TAB_LABELS, AGENT_EMBED_TAB_LABELS, AGENT_EVALUATION_TAB_LABELS, AGENT_GRADER_TAB_LABELS, AGENT_HISTORY_TAB_LABELS, AGENT_HUMAN_SUPPORT_TAB_LABELS, AGENT_LLM_TAB_LABELS, AGENT_LTI_TAB_LABELS, AGENT_MEMORY_TAB_LABELS, AGENT_PICKER_LABELS, AGENT_PRIVACY_TAB_LABELS, AGENT_PROMPTS_TAB_LABELS, AGENT_SAFETY_TAB_LABELS, AGENT_SCREENSHARE_TAB_LABELS, AGENT_SEARCH_LABELS, AGENT_SETTINGS_TAB_LABELS, AGENT_SKILLS_TAB_LABELS, AGENT_SPEND_CAPS_TAB_LABELS, AGENT_TASKS_TAB_LABELS, AGENT_TOOLS_TAB_LABELS, AGENT_VOICE_TAB_LABELS, Account, AgentAccessTab, AgentAnalyticsTab, AgentApiTab, AgentCard, AgentDatasetsTab, AgentDisclaimersTab, AgentEmbedTab, AgentEmptyState, AgentEvaluationTab, AgentGraderTab, AgentHistoryTab, AgentHumanSupportTab, AgentLLMTab, AgentLtiTab, AgentMemoryTab, AgentPrivacyTab, AgentPromptsTab, AgentSafetyTab, AgentScreenShareTab, AgentSearch, AgentSearchFilters, AgentSearchInput, AgentSettingsProvider, AgentSettingsTab, AgentSkillsTab, AgentSpendCapsTab, AgentTasksTab, AgentToolsTab, AgentVoiceTab, AppSidebar, CATALOGS, Chat, ClientErrorPage, ConversationStarters$1 as ConversationStarters, CopyButton, CopyMentorModal, CourseBox, CourseContentLayout, CourseContentTabPage, CreatePathwayModal, CredentialDetailModal, CredentialMiniBox, DEFAULT_ANALYTICS_HUB_TABS, DEFAULT_LOCALE, DeleteMentorModal, EMPTY_PROGRAM_SETTINGS_FORM, EdxIframe, ErrorPage, GRADING_TOOL_NAME, GreetingMethod, LLMProviderModal, LocalModelRow, McpTab, MediaBox, MentorSelectionGrid, NavBar, OrganizationTab, PLATFORM_SIDEBAR_FLYOUT_ITEM_COLOR, PLATFORM_SIDEBAR_FLYOUT_TITLE_COLOR, PLATFORM_SIDEBAR_NAV_ACTIVE_BG_OPEN, PLATFORM_SIDEBAR_NAV_MUTED, PathwayDetailModal, PlatformAccountSheet, PlatformSidebar, PlatformSidebarCollapsedLabelFlyout, PlatformSidebarCollapsedNavFlyout, PlatformSidebarFooter, PlatformSidebarNavDivider, PlatformSidebarNavSection, PlatformSidebarSubNavItem, ProfileInfoCards, ProfileTabs, ProgramDetailModal, ProjectsSidebarDropdown, SPEND_CAPS_SUB_TABS, SUPPORTED_LOCALES, SidebarInset, SidebarProvider, SidebarTrigger, SpendCapUsage, SsoLogin, StarButton, UserProfileDropdown, UserProfileModal, WebContainersI18nProvider, formatDateString, getCatalog, getProviderName, initializeLocalStorageWithObject, isValidLocale, resolveAgentPickerLabels, resolveAgentSearchLabels, resolveLLMTabLabels, resolveSettingsTabLabels, useAgentSearch, useAgentSearchWithPagination, useAgentSettings, useAgentStar, useGetChatDetails, usePlatformSidebarFooterActions, usePlatformSidebarNavCallback, useSidebar, useT, useTimeTracker, useWebContainersI18n, useWebContainersLocale };
|
|
338447
338432
|
//# sourceMappingURL=index.esm.js.map
|