@iblai/iblai-js 2.3.6 → 2.3.7

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.
@@ -65834,11 +65834,12 @@ var graderTabLabels$3 = {
65834
65834
  offHint: "Turn it on to write grading instructions and build your rubric. Anything you set up here is kept safe if you later turn it off."
65835
65835
  },
65836
65836
  subTabs: {
65837
- setup: "Grading setup",
65838
- rubric: "Rubric"
65837
+ setup: "Grading Setup",
65838
+ rubric: "Rubric",
65839
+ results: "Results"
65839
65840
  },
65840
65841
  denied: {
65841
- title: "No access to grading settings",
65842
+ title: "No Access to Grading Settings",
65842
65843
  description: "You don't have permission to view this agent's grading setup. Ask an administrator for access."
65843
65844
  },
65844
65845
  warnings: {
@@ -65846,12 +65847,12 @@ var graderTabLabels$3 = {
65846
65847
  noCriteria: "Grading is on but the rubric is empty — the agent will fail when asked to grade. Add at least one criterion in the Rubric tab."
65847
65848
  },
65848
65849
  config: {
65849
- sectionTitle: "Grading setup",
65850
+ sectionTitle: "Grading Setup",
65850
65851
  gradingMode: {
65851
- label: "What gets graded",
65852
+ label: "What Gets Graded",
65852
65853
  options: {
65853
- submission: "A submission",
65854
- conversation: "The conversation"
65854
+ submission: "A Submission",
65855
+ conversation: "The Conversation"
65855
65856
  },
65856
65857
  help: {
65857
65858
  submission: "The agent grades a piece of work the person hands in, like an essay or answer.",
@@ -65859,16 +65860,16 @@ var graderTabLabels$3 = {
65859
65860
  }
65860
65861
  },
65861
65862
  feedbackMode: {
65862
- label: "Feedback shared with the person",
65863
+ label: "Feedback Shared with the Person",
65863
65864
  options: {
65864
- overall: "Overall feedback only",
65865
- perCriteria: "Feedback per criterion",
65866
- both: "Overall + per criterion"
65865
+ overall: "Overall Feedback Only",
65866
+ perCriteria: "Feedback per Criterion",
65867
+ both: "Overall + per Criterion"
65867
65868
  },
65868
65869
  help: "The overall score is always calculated — this only controls how much detail is shared back."
65869
65870
  },
65870
65871
  instructions: {
65871
- label: "Grading instructions",
65872
+ label: "Grading Instructions",
65872
65873
  placeholder: "Describe what's being graded and anything the grader should know beyond the rubric. E.g. 'You are grading a 500-word persuasive essay on climate policy written by a high-school student. Be encouraging but honest.'",
65873
65874
  help: "Required. This is the context the agent uses every time it grades."
65874
65875
  },
@@ -65880,7 +65881,7 @@ var graderTabLabels$3 = {
65880
65881
  description: "Each row is one thing the agent looks for and how many points it is worth. The overall score is points earned out of the total.",
65881
65882
  needsConfigHint: "Save your grading setup first, then add rubric criteria here.",
65882
65883
  emptyState: "No criteria yet. Add your first one — for example \"Clarity\", 10 points.",
65883
- addButton: "Add criterion",
65884
+ addButton: "Add Criterion",
65884
65885
  columns: {
65885
65886
  name: "Name",
65886
65887
  criteria: "Criteria",
@@ -65889,12 +65890,12 @@ var graderTabLabels$3 = {
65889
65890
  actionsAria: "Actions for {name}",
65890
65891
  edit: "Edit",
65891
65892
  "delete": "Delete",
65892
- totalPoints: "Total possible points: {total}",
65893
+ totalPoints: "Total Possible Points: {total}",
65893
65894
  scoreHint: "Overall score = points earned ÷ {total}.",
65894
65895
  lastCriterionHint: "A rubric needs at least one criterion — add another before removing this one.",
65895
65896
  modal: {
65896
- addTitle: "Add criterion",
65897
- editTitle: "Edit criterion",
65897
+ addTitle: "Add Criterion",
65898
+ editTitle: "Edit Criterion",
65898
65899
  name: {
65899
65900
  label: "Name",
65900
65901
  placeholder: "e.g. Clarity",
@@ -65915,7 +65916,7 @@ var graderTabLabels$3 = {
65915
65916
  cancel: "Cancel"
65916
65917
  },
65917
65918
  deleteModal: {
65918
- title: "Delete criterion",
65919
+ title: "Delete Criterion",
65919
65920
  confirmationPrefix: "Are you sure you want to remove",
65920
65921
  confirmationSuffix: " from the rubric?",
65921
65922
  cancel: "Cancel",
@@ -65933,6 +65934,59 @@ var graderTabLabels$3 = {
65933
65934
  criterionUpdated: "Criterion updated",
65934
65935
  criterionDeleted: "Criterion deleted",
65935
65936
  criterionError: "Couldn't update the rubric"
65937
+ },
65938
+ results: {
65939
+ sectionTitle: "Grade Results",
65940
+ description: "Every grade this agent has issued. Override a score to correct it — the change is pushed back to the LMS the grade came from.",
65941
+ filters: {
65942
+ searchUser: "Search for User",
65943
+ searchUsersPlaceholder: "Search users...",
65944
+ noUsersFound: "No users found.",
65945
+ allUsers: "All Users",
65946
+ statusLabel: "Score Status",
65947
+ allStatuses: "All Statuses",
65948
+ dateRangeLabel: "Pick a Date Range"
65949
+ },
65950
+ statusValues: {
65951
+ pending: "Pending",
65952
+ published: "Published",
65953
+ failed: "Failed"
65954
+ },
65955
+ columns: {
65956
+ learner: "Learner",
65957
+ score: "Score",
65958
+ status: "Status",
65959
+ override: "Override",
65960
+ gradedAt: "Graded"
65961
+ },
65962
+ emptyState: "No grades yet. They will appear here once the agent starts grading.",
65963
+ emptyFiltered: "No grades match the current filters.",
65964
+ overriddenBadge: "Overridden",
65965
+ overrideModal: {
65966
+ title: "Override Grade",
65967
+ learnerLabel: "Learner",
65968
+ aiScoreLabel: "AI Score",
65969
+ currentOverrideLabel: "Current Override",
65970
+ noOverride: "None",
65971
+ pointsLabel: "Override Points",
65972
+ pointsHelp: "Between 0 and {total}. The score pushed to the LMS becomes points ÷ {total}.",
65973
+ pointsRange: "Points must be between 0 and {total}",
65974
+ feedbackLabel: "Override Feedback",
65975
+ feedbackPlaceholder: "Explain the change for the learner (optional).",
65976
+ clearHelp: "Clearing the override restores the AI score and pushes it back to the LMS.",
65977
+ save: "Save",
65978
+ saving: "Saving…",
65979
+ clear: "Clear",
65980
+ clearing: "Clearing…",
65981
+ cancel: "Cancel"
65982
+ },
65983
+ toasts: {
65984
+ overrideSaved: "Override saved and pushed to the LMS",
65985
+ overrideCleared: "Override cleared — the AI score was restored",
65986
+ overrideError: "Couldn't save the override"
65987
+ },
65988
+ overrideButton: "Override",
65989
+ overrideButtonAria: "Override grade for {email}"
65936
65990
  }
65937
65991
  };
65938
65992
  var en = {
@@ -67515,7 +67569,8 @@ var graderTabLabels$2 = {
67515
67569
  },
67516
67570
  subTabs: {
67517
67571
  setup: "Configuration de la notation",
67518
- rubric: "Grille d'évaluation"
67572
+ rubric: "Grille d'évaluation",
67573
+ results: "Résultats"
67519
67574
  },
67520
67575
  denied: {
67521
67576
  title: "Pas d'accès aux paramètres de notation",
@@ -67603,6 +67658,59 @@ var graderTabLabels$2 = {
67603
67658
  deleting: "Suppression…"
67604
67659
  }
67605
67660
  },
67661
+ results: {
67662
+ sectionTitle: "Résultats de notation",
67663
+ description: "Toutes les notes émises par cet agent. Remplacez une note pour la corriger — la modification est renvoyée au LMS d'où provient la note.",
67664
+ filters: {
67665
+ searchUser: "Rechercher un utilisateur",
67666
+ searchUsersPlaceholder: "Rechercher des utilisateurs...",
67667
+ noUsersFound: "Aucun utilisateur trouvé.",
67668
+ allUsers: "Tous les utilisateurs",
67669
+ statusLabel: "Statut de la note",
67670
+ allStatuses: "Tous les statuts",
67671
+ dateRangeLabel: "Choisir une plage de dates"
67672
+ },
67673
+ statusValues: {
67674
+ pending: "En attente",
67675
+ published: "Publié",
67676
+ failed: "Échoué"
67677
+ },
67678
+ columns: {
67679
+ learner: "Apprenant",
67680
+ score: "Note",
67681
+ status: "Statut",
67682
+ override: "Remplacement",
67683
+ gradedAt: "Noté"
67684
+ },
67685
+ emptyState: "Aucune note pour l'instant. Elles apparaîtront ici dès que l'agent commencera à noter.",
67686
+ emptyFiltered: "Aucune note ne correspond aux filtres actuels.",
67687
+ overriddenBadge: "Remplacée",
67688
+ overrideModal: {
67689
+ title: "Remplacer la note",
67690
+ learnerLabel: "Apprenant",
67691
+ aiScoreLabel: "Note de l'IA",
67692
+ currentOverrideLabel: "Remplacement actuel",
67693
+ noOverride: "Aucun",
67694
+ pointsLabel: "Points de remplacement",
67695
+ pointsHelp: "Entre 0 et {total}. La note envoyée au LMS devient points ÷ {total}.",
67696
+ pointsRange: "Les points doivent être compris entre 0 et {total}",
67697
+ feedbackLabel: "Retour sur le remplacement",
67698
+ feedbackPlaceholder: "Expliquez le changement à l'apprenant (facultatif).",
67699
+ clearHelp: "Supprimer le remplacement restaure la note de l'IA et la renvoie au LMS.",
67700
+ save: "Enregistrer",
67701
+ saving: "Enregistrement…",
67702
+ clear: "Supprimer",
67703
+ clearing: "Suppression…",
67704
+ cancel: "Annuler"
67705
+ },
67706
+ toasts: {
67707
+ overrideSaved: "Remplacement enregistré et envoyé au LMS",
67708
+ overrideCleared: "Remplacement supprimé — la note de l'IA a été restaurée",
67709
+ overrideError: "Impossible d'enregistrer le remplacement"
67710
+ },
67711
+ overrideButton: "Remplacer",
67712
+ overrideButtonAria: "Remplacer la note de {email}"
67713
+ },
67606
67714
  toasts: {
67607
67715
  toggleOn: "Notation activée",
67608
67716
  toggleOff: "Notation désactivée — votre grille est conservée pour la prochaine fois",
@@ -73781,7 +73889,8 @@ var graderTabLabels$1 = {
73781
73889
  },
73782
73890
  subTabs: {
73783
73891
  setup: "Configuración de calificación",
73784
- rubric: "Rúbrica"
73892
+ rubric: "Rúbrica",
73893
+ results: "Resultados"
73785
73894
  },
73786
73895
  denied: {
73787
73896
  title: "Sin acceso a la configuración de calificación",
@@ -73869,6 +73978,59 @@ var graderTabLabels$1 = {
73869
73978
  deleting: "Eliminando…"
73870
73979
  }
73871
73980
  },
73981
+ results: {
73982
+ sectionTitle: "Resultados de calificación",
73983
+ description: "Todas las calificaciones que este agente ha emitido. Anula una puntuación para corregirla — el cambio se envía de vuelta al LMS del que proviene la calificación.",
73984
+ filters: {
73985
+ searchUser: "Buscar usuario",
73986
+ searchUsersPlaceholder: "Buscar usuarios...",
73987
+ noUsersFound: "No se encontraron usuarios.",
73988
+ allUsers: "Todos los usuarios",
73989
+ statusLabel: "Estado de la puntuación",
73990
+ allStatuses: "Todos los estados",
73991
+ dateRangeLabel: "Selecciona un rango de fechas"
73992
+ },
73993
+ statusValues: {
73994
+ pending: "Pendiente",
73995
+ published: "Publicado",
73996
+ failed: "Fallido"
73997
+ },
73998
+ columns: {
73999
+ learner: "Estudiante",
74000
+ score: "Puntuación",
74001
+ status: "Estado",
74002
+ override: "Anulación",
74003
+ gradedAt: "Calificado"
74004
+ },
74005
+ emptyState: "Aún no hay calificaciones. Aparecerán aquí cuando el agente comience a calificar.",
74006
+ emptyFiltered: "Ninguna calificación coincide con los filtros actuales.",
74007
+ overriddenBadge: "Anulada",
74008
+ overrideModal: {
74009
+ title: "Anular calificación",
74010
+ learnerLabel: "Estudiante",
74011
+ aiScoreLabel: "Puntuación de la IA",
74012
+ currentOverrideLabel: "Anulación actual",
74013
+ noOverride: "Ninguna",
74014
+ pointsLabel: "Puntos de anulación",
74015
+ pointsHelp: "Entre 0 y {total}. La puntuación enviada al LMS es puntos ÷ {total}.",
74016
+ pointsRange: "Los puntos deben estar entre 0 y {total}",
74017
+ feedbackLabel: "Retroalimentación de la anulación",
74018
+ feedbackPlaceholder: "Explica el cambio al estudiante (opcional).",
74019
+ clearHelp: "Quitar la anulación restaura la puntuación de la IA y la envía de vuelta al LMS.",
74020
+ save: "Guardar",
74021
+ saving: "Guardando…",
74022
+ clear: "Quitar",
74023
+ clearing: "Quitando…",
74024
+ cancel: "Cancelar"
74025
+ },
74026
+ toasts: {
74027
+ overrideSaved: "Anulación guardada y enviada al LMS",
74028
+ overrideCleared: "Anulación quitada — se restauró la puntuación de la IA",
74029
+ overrideError: "No se pudo guardar la anulación"
74030
+ },
74031
+ overrideButton: "Anular",
74032
+ overrideButtonAria: "Anular la calificación de {email}"
74033
+ },
73872
74034
  toasts: {
73873
74035
  toggleOn: "Calificación activada",
73874
74036
  toggleOff: "Calificación desactivada — tu rúbrica se conserva para la próxima vez",
@@ -80047,7 +80209,8 @@ var graderTabLabels = {
80047
80209
  },
80048
80210
  subTabs: {
80049
80211
  setup: "评分设置",
80050
- rubric: "评分标准"
80212
+ rubric: "评分标准",
80213
+ results: "结果"
80051
80214
  },
80052
80215
  denied: {
80053
80216
  title: "无权访问评分设置",
@@ -80135,6 +80298,59 @@ var graderTabLabels = {
80135
80298
  deleting: "删除中…"
80136
80299
  }
80137
80300
  },
80301
+ results: {
80302
+ sectionTitle: "评分结果",
80303
+ description: "此智能体发出的所有评分。覆盖分数即可更正 — 更改会推送回评分来源的 LMS。",
80304
+ filters: {
80305
+ searchUser: "搜索用户",
80306
+ searchUsersPlaceholder: "搜索用户...",
80307
+ noUsersFound: "未找到用户。",
80308
+ allUsers: "所有用户",
80309
+ statusLabel: "分数状态",
80310
+ allStatuses: "全部状态",
80311
+ dateRangeLabel: "选择日期范围"
80312
+ },
80313
+ statusValues: {
80314
+ pending: "待处理",
80315
+ published: "已发布",
80316
+ failed: "失败"
80317
+ },
80318
+ columns: {
80319
+ learner: "学员",
80320
+ score: "分数",
80321
+ status: "状态",
80322
+ override: "覆盖",
80323
+ gradedAt: "评分时间"
80324
+ },
80325
+ emptyState: "还没有评分。智能体开始评分后将显示在这里。",
80326
+ emptyFiltered: "没有符合当前筛选条件的评分。",
80327
+ overriddenBadge: "已覆盖",
80328
+ overrideModal: {
80329
+ title: "覆盖评分",
80330
+ learnerLabel: "学员",
80331
+ aiScoreLabel: "AI 分数",
80332
+ currentOverrideLabel: "当前覆盖",
80333
+ noOverride: "无",
80334
+ pointsLabel: "覆盖分数",
80335
+ pointsHelp: "介于 0 和 {total} 之间。推送到 LMS 的分数为 分数 ÷ {total}。",
80336
+ pointsRange: "分数必须介于 0 和 {total} 之间",
80337
+ feedbackLabel: "覆盖反馈",
80338
+ feedbackPlaceholder: "向学员说明此更改(可选)。",
80339
+ clearHelp: "清除覆盖会恢复 AI 分数并推送回 LMS。",
80340
+ save: "保存",
80341
+ saving: "保存中…",
80342
+ clear: "清除",
80343
+ clearing: "清除中…",
80344
+ cancel: "取消"
80345
+ },
80346
+ toasts: {
80347
+ overrideSaved: "覆盖已保存并推送到 LMS",
80348
+ overrideCleared: "覆盖已清除 — AI 分数已恢复",
80349
+ overrideError: "无法保存覆盖"
80350
+ },
80351
+ overrideButton: "覆盖",
80352
+ overrideButtonAria: "覆盖 {email} 的评分"
80353
+ },
80138
80354
  toasts: {
80139
80355
  toggleOn: "评分已开启",
80140
80356
  toggleOff: "评分已关闭 — 您的评分标准已保留,下次可继续使用",
@@ -152431,6 +152647,64 @@ function CreateApiModal({ isOpen, onClose, tenantKey, username }) {
152431
152647
  : t('apiTabLabels.createModal.submit') })) }) })] })] }) }), apiKey && jsx(ApiKeyModal, { isOpen: true, onClose: () => setApiKey(null), apiKey: apiKey })] }));
152432
152648
  }
152433
152649
 
152650
+ /**
152651
+ * Returns the canonical logo path and display name for an LLM provider.
152652
+ * `logo` is a static-root path (e.g. `/llm-amazon-provider.png`); the package
152653
+ * ships the canonical assets under `@iblai/web-containers/public/` — copy them
152654
+ * into your app's static-root (`public/` for Next.js) so the paths resolve.
152655
+ */
152656
+ function getLLMProviderDetails(llmProvider, llmName) {
152657
+ switch (llmProvider) {
152658
+ case 'groq':
152659
+ return { logo: '/llm-groq-provider.png', name: 'Groq' };
152660
+ case 'azure_openai':
152661
+ return { logo: '/llm-microsoft-provider.png', name: 'Microsoft' };
152662
+ case 'openai':
152663
+ if (llmName)
152664
+ return { logo: '/llm-openai-provider.jpg', name: 'OpenAI' };
152665
+ return { logo: '/llm-openai-provider-2.svg', name: 'OpenAI' };
152666
+ case 'mistral':
152667
+ return { logo: '/llm-mistral-provider.jpeg', name: 'Mistral' };
152668
+ case 'google':
152669
+ if (llmName)
152670
+ return { logo: '/llm-gemini-provider.png', name: 'Google' };
152671
+ return { logo: '/llm-google-provider.svg', name: 'Google' };
152672
+ case 'llama':
152673
+ return { logo: '/llm-llama-provider.jpeg', name: 'Meta' };
152674
+ case 'perplexity':
152675
+ return { logo: '/llm-perplexity-provider.webp', name: 'Perplexity' };
152676
+ case 'deepseek':
152677
+ return { logo: '/llm-deepseek-provider.png', name: 'DeepSeek' };
152678
+ case 'xai':
152679
+ return { logo: '/llm-xai-provider.jpg', name: 'xAI' };
152680
+ case 'IBLChatAnthropic':
152681
+ case 'anthropic':
152682
+ return { logo: '/llm-claude-provider.png', name: 'Anthropic' };
152683
+ case 'IBLChatNvidia':
152684
+ case 'nvidia':
152685
+ return { logo: '/llm-nvidia-provider.webp', name: 'NVIDIA' };
152686
+ case 'bedrock':
152687
+ case 'amazon-bedrock':
152688
+ case 'amazon_bedrock':
152689
+ case 'IBLChatBedrock':
152690
+ return { logo: '/llm-amazon-provider.png', name: 'Amazon' };
152691
+ // ibl.ai's own hosted provider. The backend key is `iblai` (NameEnum.IBLAI);
152692
+ // the other cases cover the `IBLChat<Vendor>` house spelling and the
152693
+ // dotted/dashed/underscored brand forms seen in labels and older payloads.
152694
+ case 'iblai':
152695
+ case 'IBLAI':
152696
+ case 'ibl.ai':
152697
+ case 'ibl_ai':
152698
+ case 'ibl-ai':
152699
+ case 'ibl':
152700
+ case 'IBLChatIBL':
152701
+ case 'IBLChatIBLAI':
152702
+ return { logo: '/llm-iblai-provider.png', name: 'ibl.ai' };
152703
+ default:
152704
+ return { logo: '/llm-generic-provider.png', name: llmProvider };
152705
+ }
152706
+ }
152707
+
152434
152708
  // Dynamic schema based on selected provider
152435
152709
  const createDynamicSchema$1 = (schemaFields) => {
152436
152710
  const schemaObj = {
@@ -152659,10 +152933,14 @@ function CreateLLMModal({ isOpen, onClose, tenantKey, onSuccess }) {
152659
152933
  }
152660
152934
  }, children: [jsx(SelectTrigger, { children: jsx(SelectValue, { placeholder: t('llmsTabCreateLlmModal.selectProviderPlaceholder') }) }), jsx(SelectContent, { children: availableProviders.map((provider) => {
152661
152935
  var _a, _b;
152662
- const providerLogo = (_a = provider === null || provider === void 0 ? void 0 : provider.service_info) === null || _a === void 0 ? void 0 : _a.logo;
152936
+ // Prefer the logo the API ships; fall back to the
152937
+ // bundled provider artwork so known providers (ibl.ai
152938
+ // included) never degrade to a generic key emoji.
152939
+ const providerLogo = ((_a = provider === null || provider === void 0 ? void 0 : provider.service_info) === null || _a === void 0 ? void 0 : _a.logo) ||
152940
+ getLLMProviderDetails(provider.name).logo;
152663
152941
  const providerName = ((_b = provider === null || provider === void 0 ? void 0 : provider.service_info) === null || _b === void 0 ? void 0 : _b.display_name) ||
152664
152942
  provider.name;
152665
- return (jsx(SelectItem, { value: provider.name, children: jsxs("div", { className: "flex items-center gap-2", children: [providerLogo ? (jsx("img", { src: providerLogo, alt: provider.name, className: "w-4 h-4 rounded-sm object-contain" })) : (jsx("span", { children: "\uD83D\uDD11" })), providerName || provider.name] }) }, provider.name));
152943
+ 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));
152666
152944
  }) })] }), shouldShowError && (jsx("p", { className: "text-red-500 text-xs", children: (_b = field.state.meta.errors[0]) === null || _b === void 0 ? void 0 : _b.message }))] }));
152667
152945
  } })), 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) => {
152668
152946
  var _a, _b;
@@ -152751,17 +153029,22 @@ function IntegrationLLMsTab({ tenantKey }) {
152751
153029
  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) => {
152752
153030
  var _a, _b, _c;
152753
153031
  const provider = ((_a = cred.service_info) === null || _a === void 0 ? void 0 : _a.display_name) || cred.name;
152754
- // Use logo from service_info only
153032
+ // Prefer the logo the API ships; fall back to the bundled
153033
+ // provider artwork so known providers (ibl.ai included) never
153034
+ // degrade to a generic key emoji.
152755
153035
  let logoUrl;
152756
153036
  let logoAlt;
152757
153037
  if ((_b = cred.service_info) === null || _b === void 0 ? void 0 : _b.logo) {
152758
153038
  logoUrl = cred.service_info.logo;
152759
153039
  logoAlt = cred.service_info.display_name || cred.service_info.name;
152760
153040
  }
153041
+ else {
153042
+ logoUrl = getLLMProviderDetails(cred.name).logo;
153043
+ }
152761
153044
  const isAzure = isAzureOpenAI(cred);
152762
153045
  const azureModels = isAzure ? getAzureModels(cred) : [];
152763
153046
  const isExpanded = expandedRows.has(cred.name);
152764
- 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: logoAlt || provider || 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', {
153047
+ 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: logoAlt || provider || cred.name, className: "w-6 h-6 rounded-sm object-contain" }), 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', {
152765
153048
  count: azureModels.length,
152766
153049
  }) })) : (String((_c = cred === null || cred === void 0 ? void 0 : cred.value) === null || _c === void 0 ? void 0 : _c.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 &&
152767
153050
  isExpanded &&
@@ -228133,52 +228416,6 @@ function SignupButton({ authUrl, tenantKey, redirectTo, label = 'Sign Up', onCli
228133
228416
  }
228134
228417
  SignupButton.displayName = 'SignupButton';
228135
228418
 
228136
- /**
228137
- * Returns the canonical logo path and display name for an LLM provider.
228138
- * `logo` is a static-root path (e.g. `/llm-amazon-provider.png`); the package
228139
- * ships the canonical assets under `@iblai/web-containers/public/` — copy them
228140
- * into your app's static-root (`public/` for Next.js) so the paths resolve.
228141
- */
228142
- function getLLMProviderDetails(llmProvider, llmName) {
228143
- switch (llmProvider) {
228144
- case 'groq':
228145
- return { logo: '/llm-groq-provider.png', name: 'Groq' };
228146
- case 'azure_openai':
228147
- return { logo: '/llm-microsoft-provider.png', name: 'Microsoft' };
228148
- case 'openai':
228149
- if (llmName)
228150
- return { logo: '/llm-openai-provider.jpg', name: 'OpenAI' };
228151
- return { logo: '/llm-openai-provider-2.svg', name: 'OpenAI' };
228152
- case 'mistral':
228153
- return { logo: '/llm-mistral-provider.jpeg', name: 'Mistral' };
228154
- case 'google':
228155
- if (llmName)
228156
- return { logo: '/llm-gemini-provider.png', name: 'Google' };
228157
- return { logo: '/llm-google-provider.svg', name: 'Google' };
228158
- case 'llama':
228159
- return { logo: '/llm-llama-provider.jpeg', name: 'Meta' };
228160
- case 'perplexity':
228161
- return { logo: '/llm-perplexity-provider.webp', name: 'Perplexity' };
228162
- case 'deepseek':
228163
- return { logo: '/llm-deepseek-provider.png', name: 'DeepSeek' };
228164
- case 'xai':
228165
- return { logo: '/llm-xai-provider.jpg', name: 'xAI' };
228166
- case 'IBLChatAnthropic':
228167
- case 'anthropic':
228168
- return { logo: '/llm-claude-provider.png', name: 'Anthropic' };
228169
- case 'IBLChatNvidia':
228170
- case 'nvidia':
228171
- return { logo: '/llm-nvidia-provider.webp', name: 'NVIDIA' };
228172
- case 'bedrock':
228173
- case 'amazon-bedrock':
228174
- case 'amazon_bedrock':
228175
- case 'IBLChatBedrock':
228176
- return { logo: '/llm-amazon-provider.png', name: 'Amazon' };
228177
- default:
228178
- return { logo: '/llm-generic-provider.png', name: llmProvider };
228179
- }
228180
- }
228181
-
228182
228419
  function OverlayModal({ open, onClose, title, description, className, children, }) {
228183
228420
  const t = useT();
228184
228421
  const [mounted, setMounted] = useState(false);