@burdenoff/microfe-botmanor 2026.1027.2 → 2026.1027.3

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.
Files changed (80) hide show
  1. package/dist/botlit/BotlitRoutes.js +142 -132
  2. package/dist/botlit/BotlitRoutes.js.map +1 -1
  3. package/dist/botlit/components/AgentApprovalPanel.js +144 -126
  4. package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
  5. package/dist/botlit/components/ModelRegistrationPanel.js +4 -4
  6. package/dist/botlit/components/VersionHistoryPanel.js +92 -83
  7. package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
  8. package/dist/botlit/pages/A2AAgentDetailPage.js +212 -203
  9. package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
  10. package/dist/botlit/pages/A2ARegistryPage.js +129 -117
  11. package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
  12. package/dist/botlit/pages/AgentApprovalsPage.js +122 -110
  13. package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
  14. package/dist/botlit/pages/AgentBuilderPage.js +18 -18
  15. package/dist/botlit/pages/AgentDetailPage.js +298 -273
  16. package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
  17. package/dist/botlit/pages/AgentsListPage.js +145 -121
  18. package/dist/botlit/pages/AgentsListPage.js.map +1 -1
  19. package/dist/botlit/pages/BotChannelsTab.js +238 -226
  20. package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
  21. package/dist/botlit/pages/BotDetailPage.js +307 -288
  22. package/dist/botlit/pages/BotDetailPage.js.map +1 -1
  23. package/dist/botlit/pages/BotWorkflowTab.js +125 -116
  24. package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
  25. package/dist/botlit/pages/BotsListPage.js +159 -144
  26. package/dist/botlit/pages/BotsListPage.js.map +1 -1
  27. package/dist/botlit/pages/BucketsPage.js +279 -258
  28. package/dist/botlit/pages/BucketsPage.js.map +1 -1
  29. package/dist/botlit/pages/ChannelDetailPage.js +346 -328
  30. package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
  31. package/dist/botlit/pages/ChannelRoutesPage.js +10 -10
  32. package/dist/botlit/pages/ChannelsPage.js +163 -148
  33. package/dist/botlit/pages/ChannelsPage.js.map +1 -1
  34. package/dist/botlit/pages/DashboardPage.js +129 -114
  35. package/dist/botlit/pages/DashboardPage.js.map +1 -1
  36. package/dist/botlit/pages/ExecutionDetailPage.js +145 -139
  37. package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
  38. package/dist/botlit/pages/ExecutionsPage.js +14 -14
  39. package/dist/botlit/pages/InstalledPackagesPage.js +245 -227
  40. package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
  41. package/dist/botlit/pages/KnowledgeBaseDetailPage.js +168 -156
  42. package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
  43. package/dist/botlit/pages/KnowledgeBasesPage.js +91 -79
  44. package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
  45. package/dist/botlit/pages/MCPServerDetailPage.js +200 -188
  46. package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
  47. package/dist/botlit/pages/MCPServersPage.js +170 -155
  48. package/dist/botlit/pages/MCPServersPage.js.map +1 -1
  49. package/dist/botlit/pages/PoliciesPage.js +113 -104
  50. package/dist/botlit/pages/PoliciesPage.js.map +1 -1
  51. package/dist/botlit/pages/PolicyDetailPage.js +145 -133
  52. package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
  53. package/dist/botlit/pages/PromptStudioPage.js +106 -97
  54. package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
  55. package/dist/botlit/pages/PromptTemplateDetailPage.js +359 -347
  56. package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
  57. package/dist/botlit/pages/PromptTemplatesPage.js +127 -112
  58. package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
  59. package/dist/botlit/pages/RetrievalProfileDetailPage.js +219 -210
  60. package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
  61. package/dist/botlit/pages/RetrievalProfilesPage.js +112 -103
  62. package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
  63. package/dist/botlit/pages/SettingsPage.js +264 -252
  64. package/dist/botlit/pages/SettingsPage.js.map +1 -1
  65. package/dist/botlit/pages/SkillDetailPage.js +235 -226
  66. package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
  67. package/dist/botlit/pages/SkillsPage.js +115 -106
  68. package/dist/botlit/pages/SkillsPage.js.map +1 -1
  69. package/dist/botlit/pages/StorePackageDetailPage.js +194 -188
  70. package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
  71. package/dist/botlit/pages/StorePage.js +161 -155
  72. package/dist/botlit/pages/StorePage.js.map +1 -1
  73. package/dist/botlit/permissions/PermissionRequired.js +45 -0
  74. package/dist/botlit/permissions/PermissionRequired.js.map +1 -0
  75. package/dist/botlit/permissions/botmanorPermissions.js +72 -0
  76. package/dist/botlit/permissions/botmanorPermissions.js.map +1 -0
  77. package/dist/botlit/permissions/index.js +3 -0
  78. package/dist/botlit/permissions/useBotmanorPermissions.js +19 -0
  79. package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -0
  80. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsPage.js","names":[],"sources":["../../../src/botlit/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * Settings Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Key, Save, Brain, Link2, ExternalLink } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, FormField } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { ModelRegistrationPanel } from '../components/ModelRegistrationPanel';\nimport { useLLMProviders, useConfigureLLMProvider, useLLMModels } from '../hooks/useLLMProviders';\nimport { cn } from '../utils/cn';\nimport { toUnion } from '../utils/unions';\n\n/** Provider kinds the form offers, in the casing the service stores. */\nconst PROVIDER_TYPES = [\n 'OPENAI',\n 'ANTHROPIC',\n 'GOOGLE',\n 'AZURE_OPENAI',\n 'AWS_BEDROCK',\n 'CUSTOM',\n] as const;\n\n/** The `<option>` values are lowercase; the column is the uppercase enum. */\nfunction toProviderType(value: string): (typeof PROVIDER_TYPES)[number] {\n return toUnion(value.toUpperCase(), PROVIDER_TYPES, 'CUSTOM');\n}\n\nexport const SettingsPage: FC = () => {\n const t = useTr();\n const {\n data: providers,\n refetch: refetchProviders,\n loading: providersLoading,\n error: providersError,\n } = useLLMProviders();\n const { configureProvider, isConfiguring } = useConfigureLLMProvider();\n const {\n data: llmModels,\n refetch: refetchModels,\n loading: modelsLoading,\n error: modelsError,\n } = useLLMModels();\n const catalogLoading = providersLoading || modelsLoading;\n const catalogError = providersError || modelsError;\n const [apiKey, setApiKey] = useState('');\n const [providerEnabled, setProviderEnabled] = useState(true);\n const [selectedProviderType, setSelectedProviderType] = useState('openai');\n const [editingProviderId, setEditingProviderId] = useState<string | null>(null);\n // Credential method: 'integration' (preferred) or 'apikey' (legacy)\n const [credentialMethod, setCredentialMethod] = useState<'integration' | 'apikey' | 'iam'>(\n 'apikey'\n );\n const [connectionId, setConnectionId] = useState('');\n const [region, setRegion] = useState('ap-south-1');\n const isBedrock = selectedProviderType === 'aws_bedrock';\n const usesIam = isBedrock && credentialMethod === 'iam';\n const regionValid = /^[a-z]{2}(?:-[a-z]+)+-\\d+$/.test(region.trim());\n\n return (\n <PageLayout\n title={t('botlit.settings.title', 'Settings')}\n description={t('botlit.settings.description', 'Configure your BotManor workspace settings')}\n >\n <div className=\"space-y-6\">\n {catalogLoading && <p role=\"status\">Loading providers and models…</p>}\n {catalogError && (\n <div role=\"alert\">\n <p>Could not load providers and models. Try loading the catalog again.</p>\n <Button\n variant=\"secondary\"\n onClick={() => {\n void refetchProviders();\n void refetchModels();\n }}\n >\n Retry model catalog\n </Button>\n </div>\n )}\n <PagePurpose icon={<Key size={18} />}>\n {t(\n 'botlit.settings.purpose',\n 'Workspace-wide settings for LLM Providers — connect at least one model provider (OpenAI, Anthropic, Google and others) so your agents have a brain to think with.'\n )}\n </PagePurpose>\n\n <Card treatment=\"glass\" glow>\n <CardHeader>\n <CardTitle>{t('botlit.settings.providers.title', 'LLM Providers')}</CardTitle>\n <CardDescription>\n {t(\n 'botlit.settings.providers.description',\n 'Configure API keys for AI model providers'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {providers?.map(\n (provider: {\n id: string;\n name: string;\n type: string;\n isActive: boolean;\n connectionId?: string | null;\n credentialsHash?: string | null;\n metadata?: Record<string, unknown> | null;\n }) => (\n <div\n key={provider.id}\n className=\"flex items-center justify-between p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n {provider.connectionId ? (\n <Link2 className=\"h-5 w-5 text-primary\" />\n ) : (\n <Key className=\"h-5 w-5 text-primary\" />\n )}\n </div>\n <div>\n <p className=\"font-medium\">{provider.name}</p>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.settings.providers.type', 'Type: {{type}}', {\n type: provider.type,\n })}\n </p>\n {provider.connectionId && (\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {t(\n 'botlit.settings.providers.connectedViaIntegrations',\n 'Connected via Integrations'\n )}\n </p>\n )}\n {!provider.connectionId && provider.credentialsHash && (\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {t('botlit.settings.providers.apiKeyStored', 'API key stored locally')}\n </p>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n {provider.connectionId && (\n <Badge variant=\"default\">\n {t('botlit.settings.providers.integrationBadge', 'Integration')}\n </Badge>\n )}\n <Badge variant={provider.isActive ? 'success' : 'secondary'}>\n {provider.isActive\n ? t('botlit.settings.providers.active', 'Active')\n : t('botlit.settings.providers.inactive', 'Inactive')}\n </Badge>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setEditingProviderId(provider.id);\n setProviderEnabled(provider.isActive);\n setSelectedProviderType(provider.type.toLowerCase());\n setApiKey('');\n setConnectionId(provider.connectionId || '');\n setCredentialMethod(\n provider.type === 'AWS_BEDROCK' &&\n provider.metadata?.awsAuthentication === 'iam'\n ? 'iam'\n : provider.connectionId\n ? 'integration'\n : 'apikey'\n );\n setRegion(\n typeof provider.metadata?.region === 'string'\n ? provider.metadata.region\n : 'ap-south-1'\n );\n // Scroll to the Add Provider form\n document\n .getElementById('provider-form')\n ?.scrollIntoView({ behavior: 'smooth' });\n }}\n >\n {t('botlit.settings.actions.configure', 'Configure')}\n </Button>\n </div>\n </div>\n )\n )}\n </CardContent>\n </Card>\n\n {/* LLM Models List */}\n <Card>\n <CardHeader>\n <CardTitle>{t('botlit.settings.models.title', 'LLM Models')}</CardTitle>\n <CardDescription>\n {t('botlit.settings.models.description', 'Registered models across your providers')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {llmModels && llmModels.length > 0 ? (\n llmModels.map(\n (model: {\n id: string;\n name: string;\n modelId: string;\n providerId: string;\n isActive: boolean;\n contextWindow?: number;\n maxOutputTokens?: number;\n inputPricePerMToken?: number;\n outputPricePerMToken?: number;\n }) => {\n const providerName = providers?.find(\n (p: { id: string; name: string }) => p.id === model.providerId\n )?.name;\n return (\n <div\n key={model.id}\n className=\"flex items-center justify-between p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"p-2 bg-purple-500/10 rounded-lg\">\n <Brain className=\"h-5 w-5 text-purple-500\" />\n </div>\n <div>\n <p className=\"font-medium\">{model.name}</p>\n <p className=\"text-sm text-text-secondary\">\n {model.modelId}\n {providerName && ` · ${providerName}`}\n </p>\n <div className=\"flex gap-3 mt-1 text-xs text-text-secondary\">\n {model.contextWindow != null && (\n <span>\n {t('botlit.settings.models.context', 'Context: {{value}}K', {\n value: (model.contextWindow / 1000).toFixed(0),\n })}\n </span>\n )}\n {model.maxOutputTokens != null && (\n <span>\n {t('botlit.settings.models.maxOut', 'Max out: {{value}}K', {\n value: (model.maxOutputTokens / 1000).toFixed(0),\n })}\n </span>\n )}\n {model.inputPricePerMToken != null && (\n <span>\n {t('botlit.settings.models.priceIn', '${{value}}/M in', {\n value: model.inputPricePerMToken,\n })}\n </span>\n )}\n {model.outputPricePerMToken != null && (\n <span>\n {t('botlit.settings.models.priceOut', '${{value}}/M out', {\n value: model.outputPricePerMToken,\n })}\n </span>\n )}\n </div>\n </div>\n </div>\n <Badge variant={model.isActive ? 'success' : 'secondary'}>\n {model.isActive\n ? t('botlit.settings.providers.active', 'Active')\n : t('botlit.settings.providers.inactive', 'Inactive')}\n </Badge>\n </div>\n );\n }\n )\n ) : !catalogLoading && !catalogError ? (\n <p className=\"text-sm text-text-secondary text-center py-4\">\n {t('botlit.settings.models.empty', 'No models registered yet.')}\n </p>\n ) : null}\n </CardContent>\n </Card>\n\n {!catalogLoading && !catalogError && (\n <ModelRegistrationPanel\n providers={providers ?? []}\n onCreated={() => void refetchModels()}\n />\n )}\n\n <Card id=\"provider-form\">\n <CardHeader>\n <CardTitle>\n {editingProviderId\n ? t('botlit.settings.form.updateTitle', 'Update Provider')\n : t('botlit.settings.form.addTitle', 'Add Provider')}\n </CardTitle>\n <CardDescription>\n {editingProviderId\n ? t(\n 'botlit.settings.form.updateDescription',\n 'Update credentials for this provider'\n )\n : t('botlit.settings.form.addDescription', 'Configure a new LLM provider')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label={t('botlit.settings.form.providerLabel', 'Provider')}>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={selectedProviderType}\n disabled={Boolean(editingProviderId)}\n onChange={(e) => {\n setSelectedProviderType(e.target.value);\n setCredentialMethod(e.target.value === 'aws_bedrock' ? 'iam' : 'apikey');\n setApiKey('');\n setConnectionId('');\n }}\n >\n <option value=\"openai\">OpenAI</option>\n <option value=\"anthropic\">Anthropic</option>\n <option value=\"google\">Google AI</option>\n <option value=\"azure_openai\">Azure OpenAI</option>\n <option value=\"aws_bedrock\">AWS Bedrock</option>\n <option value=\"custom\">Custom</option>\n </select>\n </FormField>\n\n {editingProviderId && (\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={providerEnabled}\n onChange={(event) => setProviderEnabled(event.target.checked)}\n />\n Provider enabled\n </label>\n )}\n {isBedrock && (\n <FormField label=\"AWS region\">\n <Input\n aria-label=\"AWS region\"\n value={region}\n onChange={(event) => setRegion(event.target.value)}\n />\n <p className=\"text-sm text-text-secondary\">\n Managed AWS IAM requires model access enabled for this workspace by your platform\n administrator.\n </p>\n </FormField>\n )}\n\n {/* Credential method selector */}\n <FormField label={t('botlit.settings.form.credentialMethod', 'Credential Method')}>\n <div className=\"flex flex-wrap gap-3\">\n {isBedrock && (\n <label\n className={cn(\n 'flex items-center gap-2 px-4 py-3 border rounded-lg cursor-pointer flex-1',\n usesIam\n ? 'border-primary bg-action-primary-bg/5'\n : 'border-border-subtle hover:border-primary/50'\n )}\n >\n <input\n type=\"radio\"\n name=\"credentialMethod\"\n value=\"iam\"\n checked={usesIam}\n onChange={() => {\n setCredentialMethod('iam');\n setApiKey('');\n setConnectionId('');\n }}\n />\n Managed AWS IAM\n </label>\n )}\n <label\n className={cn(\n 'flex items-center gap-2 px-4 py-3 border rounded-lg cursor-pointer transition-colors flex-1',\n credentialMethod === 'integration'\n ? 'border-primary bg-action-primary-bg/5'\n : 'border-border-subtle hover:border-primary/50'\n )}\n >\n <input\n type=\"radio\"\n name=\"credentialMethod\"\n value=\"integration\"\n checked={credentialMethod === 'integration'}\n onChange={() => setCredentialMethod('integration')}\n className=\"h-4 w-4\"\n />\n <div>\n <p className=\"font-medium text-sm\">\n {t('botlit.settings.form.integrationOption', 'Connect via Integrations')}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t(\n 'botlit.settings.form.integrationHint',\n 'Managed credentials (recommended)'\n )}\n </p>\n </div>\n </label>\n <label\n className={cn(\n 'flex items-center gap-2 px-4 py-3 border rounded-lg cursor-pointer transition-colors flex-1',\n credentialMethod === 'apikey'\n ? 'border-primary bg-action-primary-bg/5'\n : 'border-border-subtle hover:border-primary/50'\n )}\n >\n <input\n type=\"radio\"\n name=\"credentialMethod\"\n value=\"apikey\"\n checked={credentialMethod === 'apikey'}\n onChange={() => setCredentialMethod('apikey')}\n className=\"h-4 w-4\"\n />\n <div>\n <p className=\"font-medium text-sm\">\n {t('botlit.settings.form.apiKeyOption', 'Enter API Key')}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t('botlit.settings.form.apiKeyHint', 'Paste key directly (legacy)')}\n </p>\n </div>\n </label>\n </div>\n </FormField>\n\n {/* Integration connection method */}\n {credentialMethod === 'integration' && (\n <div className=\"space-y-3\">\n <div className=\"p-4 bg-bg-sunken/50 border border-border-subtle rounded-lg\">\n <div className=\"flex items-start gap-3\">\n <Link2 className=\"h-5 w-5 text-primary mt-0.5 flex-shrink-0\" />\n <div className=\"space-y-2 flex-1\">\n <p className=\"text-sm font-medium\">\n {t('botlit.settings.form.integrationTitle', 'Integration Connection')}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t(\n 'botlit.settings.form.integrationDescription',\n 'Create a connection in the Integrations module, then paste the Connection ID here. This stores your API key securely in the Integrations vault.'\n )}\n </p>\n <div className=\"flex gap-2 mt-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n window.open('/integrations/connections', '_blank');\n }}\n >\n <ExternalLink size={14} className=\"mr-1.5\" />\n {t('botlit.settings.form.openIntegrations', 'Open Integrations')}\n </Button>\n </div>\n </div>\n </div>\n </div>\n <FormField\n label={t('botlit.settings.form.connectionIdPlaceholder', 'Connection ID')}\n >\n <Input\n placeholder={t(\n 'botlit.settings.form.connectionIdPlaceholder',\n 'Paste connection ID from Integrations...'\n )}\n value={connectionId}\n onChange={(e) => setConnectionId(e.target.value)}\n />\n </FormField>\n </div>\n )}\n\n {/* Legacy API key method */}\n {credentialMethod === 'apikey' && (\n <FormField label={t('botlit.settings.form.apiKeyLabel', 'API Key')}>\n <Input\n type=\"password\"\n placeholder={t('botlit.settings.form.apiKeyPlaceholder', 'sk-...')}\n value={apiKey}\n onChange={(e) => setApiKey(e.target.value)}\n />\n </FormField>\n )}\n\n <div className=\"flex gap-2\">\n <Button\n leftIcon={<Save size={16} />}\n isLoading={isConfiguring}\n disabled={\n (isBedrock && !regionValid) ||\n (usesIam\n ? false\n : credentialMethod === 'apikey'\n ? !apiKey.trim()\n : !connectionId.trim())\n }\n onClick={async () => {\n try {\n const providerName =\n selectedProviderType.charAt(0).toUpperCase() + selectedProviderType.slice(1);\n\n // `useConfigureLLMProvider` projects each payload\n // onto the fields its input type declares and adds\n // the workspace id, so only real fields go here.\n const credentials =\n credentialMethod !== 'apikey' ? undefined : apiKey ? { apiKey } : undefined;\n const linkedConnectionId =\n credentialMethod === 'integration' ? connectionId : null;\n const previousMetadata =\n providers?.find((provider) => provider.id === editingProviderId)?.metadata ??\n {};\n const metadata = isBedrock\n ? {\n ...previousMetadata,\n region: region.trim(),\n awsAuthentication: usesIam ? 'iam' : 'credentials',\n }\n : previousMetadata;\n\n if (editingProviderId) {\n await configureProvider(\n {\n name: providerName,\n type: toProviderType(selectedProviderType),\n connectionId: linkedConnectionId,\n credentials,\n metadata,\n isActive: providerEnabled,\n },\n editingProviderId\n );\n } else {\n await configureProvider({\n name: providerName,\n type: toProviderType(selectedProviderType),\n connectionId: linkedConnectionId,\n credentials,\n metadata,\n });\n }\n\n setApiKey('');\n setConnectionId('');\n setEditingProviderId(null);\n await refetchProviders();\n const providerLabel =\n selectedProviderType.charAt(0).toUpperCase() + selectedProviderType.slice(1);\n toast.success(\n editingProviderId\n ? t(\n 'botlit.settings.form.updateSuccess',\n '{{provider}} provider updated successfully',\n { provider: providerLabel }\n )\n : t(\n 'botlit.settings.form.addSuccess',\n '{{provider}} provider added successfully',\n { provider: providerLabel }\n )\n );\n } catch (err: unknown) {\n const message =\n err instanceof Error\n ? err.message\n : t('botlit.settings.form.saveError', 'Failed to save provider');\n toast.error(message);\n }\n }}\n >\n {editingProviderId\n ? t('botlit.settings.form.updateProvider', 'Update Provider')\n : t('botlit.settings.form.saveProvider', 'Save Provider')}\n </Button>\n {editingProviderId && (\n <Button\n variant=\"outline\"\n onClick={() => {\n setEditingProviderId(null);\n setApiKey('');\n setConnectionId('');\n setCredentialMethod('apikey');\n setSelectedProviderType('openai');\n }}\n >\n {t('botlit.settings.form.cancel', 'Cancel')}\n </Button>\n )}\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"SettingsPage.js","names":[],"sources":["../../../src/botlit/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * Settings Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Key, Save, Brain, Link2, ExternalLink } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, FormField } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\nimport { ModelRegistrationPanel } from '../components/ModelRegistrationPanel';\nimport { useLLMProviders, useConfigureLLMProvider, useLLMModels } from '../hooks/useLLMProviders';\nimport { cn } from '../utils/cn';\nimport { toUnion } from '../utils/unions';\n\n/** Provider kinds the form offers, in the casing the service stores. */\nconst PROVIDER_TYPES = [\n 'OPENAI',\n 'ANTHROPIC',\n 'GOOGLE',\n 'AZURE_OPENAI',\n 'AWS_BEDROCK',\n 'CUSTOM',\n] as const;\n\n/** The `<option>` values are lowercase; the column is the uppercase enum. */\nfunction toProviderType(value: string): (typeof PROVIDER_TYPES)[number] {\n return toUnion(value.toUpperCase(), PROVIDER_TYPES, 'CUSTOM');\n}\n\nexport const SettingsPage: FC = () => {\n const t = useTr();\n const {\n data: providers,\n refetch: refetchProviders,\n loading: providersLoading,\n error: providersError,\n } = useLLMProviders();\n const { configureProvider, isConfiguring } = useConfigureLLMProvider();\n const {\n data: llmModels,\n refetch: refetchModels,\n loading: modelsLoading,\n error: modelsError,\n } = useLLMModels();\n const catalogLoading = providersLoading || modelsLoading;\n const catalogError = providersError || modelsError;\n const [apiKey, setApiKey] = useState('');\n const [providerEnabled, setProviderEnabled] = useState(true);\n const [selectedProviderType, setSelectedProviderType] = useState('openai');\n const [editingProviderId, setEditingProviderId] = useState<string | null>(null);\n // Credential method: 'integration' (preferred) or 'apikey' (legacy)\n const [credentialMethod, setCredentialMethod] = useState<'integration' | 'apikey' | 'iam'>(\n 'apikey'\n );\n const [connectionId, setConnectionId] = useState('');\n const [region, setRegion] = useState('ap-south-1');\n const isBedrock = selectedProviderType === 'aws_bedrock';\n const usesIam = isBedrock && credentialMethod === 'iam';\n const regionValid = /^[a-z]{2}(?:-[a-z]+)+-\\d+$/.test(region.trim());\n\n return (\n <PageLayout\n title={t('botlit.settings.title', 'Settings')}\n description={t('botlit.settings.description', 'Configure your BotManor workspace settings')}\n >\n <div className=\"space-y-6\">\n {catalogLoading && <p role=\"status\">Loading providers and models…</p>}\n {catalogError && (\n <div role=\"alert\">\n <p>Could not load providers and models. Try loading the catalog again.</p>\n <Button\n variant=\"secondary\"\n onClick={() => {\n void refetchProviders();\n void refetchModels();\n }}\n >\n Retry model catalog\n </Button>\n </div>\n )}\n <PagePurpose icon={<Key size={18} />}>\n {t(\n 'botlit.settings.purpose',\n 'Workspace-wide settings for LLM Providers — connect at least one model provider (OpenAI, Anthropic, Google and others) so your agents have a brain to think with.'\n )}\n </PagePurpose>\n\n <Card treatment=\"glass\" glow>\n <CardHeader>\n <CardTitle>{t('botlit.settings.providers.title', 'LLM Providers')}</CardTitle>\n <CardDescription>\n {t(\n 'botlit.settings.providers.description',\n 'Configure API keys for AI model providers'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {providers?.map(\n (provider: {\n id: string;\n name: string;\n type: string;\n isActive: boolean;\n connectionId?: string | null;\n credentialsHash?: string | null;\n metadata?: Record<string, unknown> | null;\n }) => (\n <div\n key={provider.id}\n className=\"flex items-center justify-between p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n {provider.connectionId ? (\n <Link2 className=\"h-5 w-5 text-primary\" />\n ) : (\n <Key className=\"h-5 w-5 text-primary\" />\n )}\n </div>\n <div>\n <p className=\"font-medium\">{provider.name}</p>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.settings.providers.type', 'Type: {{type}}', {\n type: provider.type,\n })}\n </p>\n {provider.connectionId && (\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {t(\n 'botlit.settings.providers.connectedViaIntegrations',\n 'Connected via Integrations'\n )}\n </p>\n )}\n {!provider.connectionId && provider.credentialsHash && (\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {t('botlit.settings.providers.apiKeyStored', 'API key stored locally')}\n </p>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n {provider.connectionId && (\n <Badge variant=\"default\">\n {t('botlit.settings.providers.integrationBadge', 'Integration')}\n </Badge>\n )}\n <Badge variant={provider.isActive ? 'success' : 'secondary'}>\n {provider.isActive\n ? t('botlit.settings.providers.active', 'Active')\n : t('botlit.settings.providers.inactive', 'Inactive')}\n </Badge>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.LLM_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setEditingProviderId(provider.id);\n setProviderEnabled(provider.isActive);\n setSelectedProviderType(provider.type.toLowerCase());\n setApiKey('');\n setConnectionId(provider.connectionId || '');\n setCredentialMethod(\n provider.type === 'AWS_BEDROCK' &&\n provider.metadata?.awsAuthentication === 'iam'\n ? 'iam'\n : provider.connectionId\n ? 'integration'\n : 'apikey'\n );\n setRegion(\n typeof provider.metadata?.region === 'string'\n ? provider.metadata.region\n : 'ap-south-1'\n );\n // Scroll to the Add Provider form\n document\n .getElementById('provider-form')\n ?.scrollIntoView({ behavior: 'smooth' });\n }}\n >\n {t('botlit.settings.actions.configure', 'Configure')}\n </Button>\n </BotmanorPermissionGate>\n </div>\n </div>\n )\n )}\n </CardContent>\n </Card>\n\n {/* LLM Models List */}\n <Card>\n <CardHeader>\n <CardTitle>{t('botlit.settings.models.title', 'LLM Models')}</CardTitle>\n <CardDescription>\n {t('botlit.settings.models.description', 'Registered models across your providers')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {llmModels && llmModels.length > 0 ? (\n llmModels.map(\n (model: {\n id: string;\n name: string;\n modelId: string;\n providerId: string;\n isActive: boolean;\n contextWindow?: number;\n maxOutputTokens?: number;\n inputPricePerMToken?: number;\n outputPricePerMToken?: number;\n }) => {\n const providerName = providers?.find(\n (p: { id: string; name: string }) => p.id === model.providerId\n )?.name;\n return (\n <div\n key={model.id}\n className=\"flex items-center justify-between p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"flex items-center gap-4\">\n <div className=\"p-2 bg-purple-500/10 rounded-lg\">\n <Brain className=\"h-5 w-5 text-purple-500\" />\n </div>\n <div>\n <p className=\"font-medium\">{model.name}</p>\n <p className=\"text-sm text-text-secondary\">\n {model.modelId}\n {providerName && ` · ${providerName}`}\n </p>\n <div className=\"flex gap-3 mt-1 text-xs text-text-secondary\">\n {model.contextWindow != null && (\n <span>\n {t('botlit.settings.models.context', 'Context: {{value}}K', {\n value: (model.contextWindow / 1000).toFixed(0),\n })}\n </span>\n )}\n {model.maxOutputTokens != null && (\n <span>\n {t('botlit.settings.models.maxOut', 'Max out: {{value}}K', {\n value: (model.maxOutputTokens / 1000).toFixed(0),\n })}\n </span>\n )}\n {model.inputPricePerMToken != null && (\n <span>\n {t('botlit.settings.models.priceIn', '${{value}}/M in', {\n value: model.inputPricePerMToken,\n })}\n </span>\n )}\n {model.outputPricePerMToken != null && (\n <span>\n {t('botlit.settings.models.priceOut', '${{value}}/M out', {\n value: model.outputPricePerMToken,\n })}\n </span>\n )}\n </div>\n </div>\n </div>\n <Badge variant={model.isActive ? 'success' : 'secondary'}>\n {model.isActive\n ? t('botlit.settings.providers.active', 'Active')\n : t('botlit.settings.providers.inactive', 'Inactive')}\n </Badge>\n </div>\n );\n }\n )\n ) : !catalogLoading && !catalogError ? (\n <p className=\"text-sm text-text-secondary text-center py-4\">\n {t('botlit.settings.models.empty', 'No models registered yet.')}\n </p>\n ) : null}\n </CardContent>\n </Card>\n\n {!catalogLoading && !catalogError && (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.LLM_CREATE}>\n <ModelRegistrationPanel\n providers={providers ?? []}\n onCreated={() => void refetchModels()}\n />\n </BotmanorPermissionGate>\n )}\n\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.LLM_CREATE}>\n <Card id=\"provider-form\">\n <CardHeader>\n <CardTitle>\n {editingProviderId\n ? t('botlit.settings.form.updateTitle', 'Update Provider')\n : t('botlit.settings.form.addTitle', 'Add Provider')}\n </CardTitle>\n <CardDescription>\n {editingProviderId\n ? t(\n 'botlit.settings.form.updateDescription',\n 'Update credentials for this provider'\n )\n : t('botlit.settings.form.addDescription', 'Configure a new LLM provider')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label={t('botlit.settings.form.providerLabel', 'Provider')}>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={selectedProviderType}\n disabled={Boolean(editingProviderId)}\n onChange={(e) => {\n setSelectedProviderType(e.target.value);\n setCredentialMethod(e.target.value === 'aws_bedrock' ? 'iam' : 'apikey');\n setApiKey('');\n setConnectionId('');\n }}\n >\n <option value=\"openai\">OpenAI</option>\n <option value=\"anthropic\">Anthropic</option>\n <option value=\"google\">Google AI</option>\n <option value=\"azure_openai\">Azure OpenAI</option>\n <option value=\"aws_bedrock\">AWS Bedrock</option>\n <option value=\"custom\">Custom</option>\n </select>\n </FormField>\n\n {editingProviderId && (\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={providerEnabled}\n onChange={(event) => setProviderEnabled(event.target.checked)}\n />\n Provider enabled\n </label>\n )}\n {isBedrock && (\n <FormField label=\"AWS region\">\n <Input\n aria-label=\"AWS region\"\n value={region}\n onChange={(event) => setRegion(event.target.value)}\n />\n <p className=\"text-sm text-text-secondary\">\n Managed AWS IAM requires model access enabled for this workspace by your\n platform administrator.\n </p>\n </FormField>\n )}\n\n {/* Credential method selector */}\n <FormField label={t('botlit.settings.form.credentialMethod', 'Credential Method')}>\n <div className=\"flex flex-wrap gap-3\">\n {isBedrock && (\n <label\n className={cn(\n 'flex items-center gap-2 px-4 py-3 border rounded-lg cursor-pointer flex-1',\n usesIam\n ? 'border-primary bg-action-primary-bg/5'\n : 'border-border-subtle hover:border-primary/50'\n )}\n >\n <input\n type=\"radio\"\n name=\"credentialMethod\"\n value=\"iam\"\n checked={usesIam}\n onChange={() => {\n setCredentialMethod('iam');\n setApiKey('');\n setConnectionId('');\n }}\n />\n Managed AWS IAM\n </label>\n )}\n <label\n className={cn(\n 'flex items-center gap-2 px-4 py-3 border rounded-lg cursor-pointer transition-colors flex-1',\n credentialMethod === 'integration'\n ? 'border-primary bg-action-primary-bg/5'\n : 'border-border-subtle hover:border-primary/50'\n )}\n >\n <input\n type=\"radio\"\n name=\"credentialMethod\"\n value=\"integration\"\n checked={credentialMethod === 'integration'}\n onChange={() => setCredentialMethod('integration')}\n className=\"h-4 w-4\"\n />\n <div>\n <p className=\"font-medium text-sm\">\n {t('botlit.settings.form.integrationOption', 'Connect via Integrations')}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t(\n 'botlit.settings.form.integrationHint',\n 'Managed credentials (recommended)'\n )}\n </p>\n </div>\n </label>\n <label\n className={cn(\n 'flex items-center gap-2 px-4 py-3 border rounded-lg cursor-pointer transition-colors flex-1',\n credentialMethod === 'apikey'\n ? 'border-primary bg-action-primary-bg/5'\n : 'border-border-subtle hover:border-primary/50'\n )}\n >\n <input\n type=\"radio\"\n name=\"credentialMethod\"\n value=\"apikey\"\n checked={credentialMethod === 'apikey'}\n onChange={() => setCredentialMethod('apikey')}\n className=\"h-4 w-4\"\n />\n <div>\n <p className=\"font-medium text-sm\">\n {t('botlit.settings.form.apiKeyOption', 'Enter API Key')}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t('botlit.settings.form.apiKeyHint', 'Paste key directly (legacy)')}\n </p>\n </div>\n </label>\n </div>\n </FormField>\n\n {/* Integration connection method */}\n {credentialMethod === 'integration' && (\n <div className=\"space-y-3\">\n <div className=\"p-4 bg-bg-sunken/50 border border-border-subtle rounded-lg\">\n <div className=\"flex items-start gap-3\">\n <Link2 className=\"h-5 w-5 text-primary mt-0.5 flex-shrink-0\" />\n <div className=\"space-y-2 flex-1\">\n <p className=\"text-sm font-medium\">\n {t('botlit.settings.form.integrationTitle', 'Integration Connection')}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {t(\n 'botlit.settings.form.integrationDescription',\n 'Create a connection in the Integrations module, then paste the Connection ID here. This stores your API key securely in the Integrations vault.'\n )}\n </p>\n <div className=\"flex gap-2 mt-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n window.open('/integrations/connections', '_blank');\n }}\n >\n <ExternalLink size={14} className=\"mr-1.5\" />\n {t('botlit.settings.form.openIntegrations', 'Open Integrations')}\n </Button>\n </div>\n </div>\n </div>\n </div>\n <FormField\n label={t('botlit.settings.form.connectionIdPlaceholder', 'Connection ID')}\n >\n <Input\n placeholder={t(\n 'botlit.settings.form.connectionIdPlaceholder',\n 'Paste connection ID from Integrations...'\n )}\n value={connectionId}\n onChange={(e) => setConnectionId(e.target.value)}\n />\n </FormField>\n </div>\n )}\n\n {/* Legacy API key method */}\n {credentialMethod === 'apikey' && (\n <FormField label={t('botlit.settings.form.apiKeyLabel', 'API Key')}>\n <Input\n type=\"password\"\n placeholder={t('botlit.settings.form.apiKeyPlaceholder', 'sk-...')}\n value={apiKey}\n onChange={(e) => setApiKey(e.target.value)}\n />\n </FormField>\n )}\n\n <div className=\"flex gap-2\">\n <Button\n leftIcon={<Save size={16} />}\n isLoading={isConfiguring}\n disabled={\n (isBedrock && !regionValid) ||\n (usesIam\n ? false\n : credentialMethod === 'apikey'\n ? !apiKey.trim()\n : !connectionId.trim())\n }\n onClick={async () => {\n try {\n const providerName =\n selectedProviderType.charAt(0).toUpperCase() +\n selectedProviderType.slice(1);\n\n // `useConfigureLLMProvider` projects each payload\n // onto the fields its input type declares and adds\n // the workspace id, so only real fields go here.\n const credentials =\n credentialMethod !== 'apikey' ? undefined : apiKey ? { apiKey } : undefined;\n const linkedConnectionId =\n credentialMethod === 'integration' ? connectionId : null;\n const previousMetadata =\n providers?.find((provider) => provider.id === editingProviderId)\n ?.metadata ?? {};\n const metadata = isBedrock\n ? {\n ...previousMetadata,\n region: region.trim(),\n awsAuthentication: usesIam ? 'iam' : 'credentials',\n }\n : previousMetadata;\n\n if (editingProviderId) {\n await configureProvider(\n {\n name: providerName,\n type: toProviderType(selectedProviderType),\n connectionId: linkedConnectionId,\n credentials,\n metadata,\n isActive: providerEnabled,\n },\n editingProviderId\n );\n } else {\n await configureProvider({\n name: providerName,\n type: toProviderType(selectedProviderType),\n connectionId: linkedConnectionId,\n credentials,\n metadata,\n });\n }\n\n setApiKey('');\n setConnectionId('');\n setEditingProviderId(null);\n await refetchProviders();\n const providerLabel =\n selectedProviderType.charAt(0).toUpperCase() +\n selectedProviderType.slice(1);\n toast.success(\n editingProviderId\n ? t(\n 'botlit.settings.form.updateSuccess',\n '{{provider}} provider updated successfully',\n { provider: providerLabel }\n )\n : t(\n 'botlit.settings.form.addSuccess',\n '{{provider}} provider added successfully',\n { provider: providerLabel }\n )\n );\n } catch (err: unknown) {\n const message =\n err instanceof Error\n ? err.message\n : t('botlit.settings.form.saveError', 'Failed to save provider');\n toast.error(message);\n }\n }}\n >\n {editingProviderId\n ? t('botlit.settings.form.updateProvider', 'Update Provider')\n : t('botlit.settings.form.saveProvider', 'Save Provider')}\n </Button>\n {editingProviderId && (\n <Button\n variant=\"outline\"\n onClick={() => {\n setEditingProviderId(null);\n setApiKey('');\n setConnectionId('');\n setCredentialMethod('apikey');\n setSelectedProviderType('openai');\n }}\n >\n {t('botlit.settings.form.cancel', 'Cancel')}\n </Button>\n )}\n </div>\n </CardContent>\n </Card>\n </BotmanorPermissionGate>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}