@burdenoff/microfe-botmanor 2026.1106.1 โ 2026.1108.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botlit/BotlitRoutes.js +34 -30
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/components/AiOperationsPanel.js +254 -0
- package/dist/botlit/components/AiOperationsPanel.js.map +1 -0
- package/dist/botlit/components/Input.js +1 -1
- package/dist/botlit/hooks/index.js +1 -0
- package/dist/botlit/hooks/useAiOperations.js +153 -0
- package/dist/botlit/hooks/useAiOperations.js.map +1 -0
- package/dist/botlit/pages/AgentDetailPage.js +198 -185
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AiOperationsPage.js +166 -0
- package/dist/botlit/pages/AiOperationsPage.js.map +1 -0
- package/dist/botlit/pages/BotDetailPage.js +282 -268
- package/dist/botlit/pages/BotDetailPage.js.map +1 -1
- package/dist/generated/wspace-operations.js +159 -66
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js +5 -3
- package/dist/generated/wspace-types.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentDetailPage.js","names":[],"sources":["../../../src/botlit/pages/AgentDetailPage.tsx"],"sourcesContent":["/**\n * Agent Detail Page\n * @module botlit/pages\n *\n * Displays agent details using flat API fields from the real GraphQL backend.\n * Maps flat fields (systemPrompt, llmModelId, mcpConnectionIds, knowledgeBaseIds, capabilities[])\n * to a rich detail view with tabs.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport {\n ArrowLeft,\n Play,\n Settings,\n BarChart3,\n BookOpen,\n Wrench,\n Shield,\n Brain,\n MessageSquare,\n Edit,\n Share2,\n FileText,\n Trash2,\n History,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { toast } from 'sonner';\nimport { PagePurpose, NextSteps, GlassCard } 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 { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { VersionHistoryPanel } from '../components/VersionHistoryPanel';\nimport { AgentApprovalPanel } from '../components/AgentApprovalPanel';\nimport { useAgentApprovalSettings } from '../hooks/useAgentApprovals';\nimport { AssistantRuntimeSetupPanel } from '../components/AssistantRuntimeSetupPanel';\nimport { AssistantChannelPanel } from '../components/AssistantChannelPanel';\nimport { AssistantWebsitePanel } from '../components/AssistantWebsitePanel';\nimport { useAgent, useUpdateAgent, useDeleteAgent } from '../hooks/useAgents';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { cn } from '../utils/cn';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate, useBotmanorCan } from '../permissions';\n\ntype TabType =\n | 'overview'\n | 'prompt'\n | 'llm'\n | 'tools'\n | 'knowledge'\n | 'guardrails'\n | 'a2a'\n | 'versions'\n | 'assistant';\n\nexport const AgentDetailPage: FC = () => {\n const t = useTr();\n const { agentId } = useParams();\n const { navigateTo } = useBotlit();\n const can = useBotmanorCan();\n const { data: agent, loading, refetch: refetchAgent } = useAgent(agentId);\n const [updateAgent, updateAgentResult] = useUpdateAgent();\n const [deleteAgent, deleteAgentResult] = useDeleteAgent();\n const [activeTab, setActiveTab] = useState<TabType>('overview');\n // BOFF-9682: when the workspace requires activation approval, an agent that\n // has never been published goes live through a reviewer, not this button.\n const approvalSettings = useAgentApprovalSettings();\n\n if (loading) {\n return (\n <PageLayout title={t('botlit.common.loading', 'Loading...')}>\n <div className=\"h-96 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n </PageLayout>\n );\n }\n\n if (!agent) {\n return (\n <PageLayout title={t('botlit.agentDetail.notFound.title', 'Agent Not Found')}>\n <EmptyState\n illustration=\"empty-agents\"\n title={t('botlit.agentDetail.notFound.title', 'Agent Not Found')}\n description={t(\n 'botlit.agentDetail.notFound.description',\n \"The agent you're looking for doesn't exist.\"\n )}\n action={\n <Button onClick={() => navigateTo('agents')}>\n {t('botlit.agentDetail.notFound.backAction', 'Back to Agents')}\n </Button>\n }\n />\n </PageLayout>\n );\n }\n\n // `AgentRecord` declares every field the agent query selects โ read directly.\n const systemPrompt = agent.systemPrompt || '';\n const llmModelId = agent.llmModelId || '';\n const temperature = agent.temperature;\n const maxTokens = agent.maxTokens;\n const mcpConnectionIds = agent.mcpConnectionIds ?? [];\n const knowledgeBaseIds = agent.knowledgeBaseIds ?? [];\n const workflowIds = agent.workflowIds ?? [];\n const capabilities = agent.capabilities ?? [];\n const tagIds = agent.tagIds ?? [];\n const maxConcurrentExecutions = agent.maxConcurrentExecutions || 10;\n const metadata = agent.metadata ?? null;\n\n const tabs: { id: TabType; label: string; icon: ReactNode }[] = [\n { id: 'assistant', label: 'Assistant setup', icon: <Settings size={16} /> },\n {\n id: 'overview',\n label: t('botlit.agentDetail.tabs.overview', 'Overview'),\n icon: <BarChart3 size={16} />,\n },\n {\n id: 'prompt',\n label: t('botlit.agentDetail.tabs.prompt', 'Prompt'),\n icon: <FileText size={16} />,\n },\n {\n id: 'llm',\n label: t('botlit.agentDetail.tabs.llmConfig', 'LLM Config'),\n icon: <Brain size={16} />,\n },\n { id: 'tools', label: t('botlit.agentDetail.tabs.tools', 'Tools'), icon: <Wrench size={16} /> },\n {\n id: 'knowledge',\n label: t('botlit.agentDetail.tabs.knowledge', 'Knowledge'),\n icon: <BookOpen size={16} />,\n },\n {\n id: 'guardrails',\n label: t('botlit.agentDetail.tabs.guardrails', 'Guardrails'),\n icon: <Shield size={16} />,\n },\n { id: 'a2a', label: t('botlit.agentDetail.tabs.a2a', 'A2A'), icon: <Share2 size={16} /> },\n {\n id: 'versions',\n label: t('botlit.agentDetail.tabs.versions', 'Versions'),\n icon: <History size={16} />,\n },\n ];\n\n return (\n <PageLayout\n title={\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigateTo('agents')}>\n <ArrowLeft size={20} />\n </Button>\n <span className=\"text-3xl\">{'๐ค'}</span>\n <div>\n <div className=\"flex items-center gap-2\">\n <span>{agent.name}</span>\n <StatusBadge status={agent.status} />\n <Badge variant=\"outline\">{agent.slug}</Badge>\n </div>\n <p className=\"text-sm font-normal text-text-secondary\">{agent.description}</p>\n </div>\n </div>\n }\n actions={\n <div className=\"flex gap-2\">\n {approvalSettings.data?.requireActivationApproval &&\n (agent.status === 'DRAFT' || agent.status === 'ARCHIVED') &&\n !agent.currentVersionId ? (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"default\"\n onClick={() => {\n setActiveTab('overview');\n requestAnimationFrame(() =>\n document\n .querySelector('[data-testid=\"agent-approval-panel\"]')\n ?.scrollIntoView({ behavior: 'smooth', block: 'start' })\n );\n }}\n >\n {t('botlit.agentApproval.requestAction', 'Request activation')}\n </Button>\n </BotmanorPermissionGate>\n ) : agent.status === 'DRAFT' || agent.status === 'ARCHIVED' ? (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"default\"\n isLoading={updateAgentResult.loading}\n onClick={async () => {\n try {\n if (!agentId) return;\n await updateAgent({ agentId, input: { status: 'ACTIVE' } });\n await refetchAgent();\n toast.success(\n `${t('botlit.agentDetail.activate.successPrefix', 'Agent')} \"${agent.name}\" ${t('botlit.agentDetail.activate.successSuffix', 'activated')}`\n );\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentDetail.activate.error', 'Failed to activate agent')\n );\n }\n }}\n >\n {t('botlit.agentDetail.actions.activate', 'Activate')}\n </Button>\n </BotmanorPermissionGate>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"outline\"\n isLoading={updateAgentResult.loading}\n onClick={async () => {\n try {\n if (!agentId) return;\n await updateAgent({ agentId, input: { status: 'DRAFT' } });\n await refetchAgent();\n toast.success(\n `${t('botlit.agentDetail.deactivate.successPrefix', 'Agent')} \"${agent.name}\" ${t('botlit.agentDetail.deactivate.successSuffix', 'deactivated')}`\n );\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentDetail.deactivate.error', 'Failed to deactivate agent')\n );\n }\n }}\n >\n {t('botlit.agentDetail.actions.deactivate', 'Deactivate')}\n </Button>\n </BotmanorPermissionGate>\n )}\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"outline\"\n leftIcon={<Edit size={16} />}\n onClick={() => navigateTo(`agents/${agentId}/edit`)}\n >\n {t('botlit.agentDetail.actions.editAgent', 'Edit Agent')}\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_EXECUTE}>\n <Button leftIcon={<Play size={16} />} onClick={() => navigateTo(`chat/${agentId}`)}>\n {t('botlit.agentDetail.actions.testAgent', 'Test Agent')}\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_DELETE}>\n <Button\n variant=\"destructive\"\n leftIcon={<Trash2 size={16} />}\n isLoading={deleteAgentResult.loading}\n onClick={async () => {\n if (!agentId) return;\n if (\n !confirm(\n `${t('botlit.agentDetail.delete.confirmPrefix', 'Are you sure you want to delete')} \"${agent.name}\"? ${t('botlit.agentDetail.delete.confirmSuffix', 'This action cannot be undone.')}`\n )\n )\n return;\n try {\n await deleteAgent(agentId);\n toast.success(\n `${t('botlit.agentDetail.delete.successPrefix', 'Agent')} \"${agent.name}\" ${t('botlit.agentDetail.delete.successSuffix', 'deleted successfully')}`\n );\n navigateTo('agents');\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentDetail.delete.error', 'Failed to delete agent')\n );\n }\n }}\n >\n {t('botlit.common.delete', 'Delete')}\n </Button>\n </BotmanorPermissionGate>\n </div>\n }\n >\n <div className=\"space-y-6\">\n {activeTab === 'assistant' && agentId && (\n <div className=\"space-y-5\">\n {/* Each panel is setup work: runtime configuration needs update, and\n publishing (whose listings are publish-gated too) needs publish. */}\n {can(BOTMANOR_PERMISSIONS.AGENT_UPDATE) && (\n <AssistantRuntimeSetupPanel\n agentId={agentId}\n onConfigured={() => void refetchAgent()}\n />\n )}\n {can(BOTMANOR_PERMISSIONS.AGENT_PUBLISH) && (\n <>\n <AssistantWebsitePanel agentId={agentId} knowledgeBaseIds={knowledgeBaseIds} />\n <AssistantChannelPanel agentId={agentId} />\n </>\n )}\n {!can(BOTMANOR_PERMISSIONS.AGENT_UPDATE) &&\n !can(BOTMANOR_PERMISSIONS.AGENT_PUBLISH) && (\n <p role=\"status\" className=\"text-sm text-text-secondary\">\n {t(\n 'botlit.agentDetail.assistant.readOnly',\n 'Assistant setup and publishing are available to members who can edit or publish agents in this workspace.'\n )}\n </p>\n )}\n </div>\n )}\n <PagePurpose icon={<Brain size={18} />}>\n {t(\n 'botlit.agentDetail.purpose',\n 'This is the full configuration for a single agent โ its prompt, model settings, the tools and knowledge it can use, its guardrails and how it talks to other agents. Use the tabs to inspect or change any part, and test the agent in chat to confirm it behaves the way you expect before going live.'\n )}\n </PagePurpose>\n\n {/* Tabs */}\n <div className=\"flex gap-1 border-b border-border-subtle overflow-x-auto\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex items-center gap-2 px-4 py-2 text-sm font-medium border-b-2 transition-colors whitespace-nowrap',\n activeTab === tab.id\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.icon}\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"space-y-6\">\n <NextSteps\n storageKey={`botlit-agent-${agentId}`}\n steps={[\n {\n id: 'test',\n label: t('botlit.agentDetail.nextSteps.test', 'Test the agent in chat'),\n description: t(\n 'botlit.agentDetail.nextSteps.testDesc',\n 'Send it a few real prompts to see how it responds.'\n ),\n icon: <Play size={16} />,\n onClick: () => navigateTo(`chat/${agentId}`),\n },\n {\n id: 'prompt',\n label: t('botlit.agentDetail.nextSteps.prompt', 'Refine the system prompt'),\n description: t(\n 'botlit.agentDetail.nextSteps.promptDesc',\n 'Tune its instructions and behaviour.'\n ),\n icon: <FileText size={16} />,\n onClick: () => setActiveTab('prompt'),\n },\n {\n id: 'tools',\n label: t('botlit.agentDetail.nextSteps.tools', 'Connect tools & knowledge'),\n description: t(\n 'botlit.agentDetail.nextSteps.toolsDesc',\n 'Give it MCP tools and knowledge bases to work with.'\n ),\n icon: <Wrench size={16} />,\n onClick: () => setActiveTab('tools'),\n },\n {\n id: 'activate',\n label: t('botlit.agentDetail.nextSteps.activate', 'Activate and attach to a bot'),\n description: t(\n 'botlit.agentDetail.nextSteps.activateDesc',\n 'Put it live so a bot can route conversations to it.'\n ),\n icon: <Share2 size={16} />,\n onClick: () => navigateTo(`agents/${agentId}/edit`),\n done: agent.status === 'ACTIVE',\n },\n ]}\n />\n {agentId && (\n <AgentApprovalPanel\n agentId={agentId}\n agentStatus={agent.status}\n onChanged={() => void refetchAgent()}\n />\n )}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Quick Info */}\n <Card className=\"lg:col-span-1\">\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Status</p>\n <StatusBadge status={agent.status} />\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Type</p>\n <Badge variant=\"outline\">{agent.type}</Badge>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Visibility</p>\n <Badge variant=\"outline\">{agent.visibility}</Badge>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">LLM Model</p>\n <p className=\"font-medium font-mono text-sm\">\n {llmModelId || 'Not configured'}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">MCP Connections</p>\n <p className=\"font-medium\">{mcpConnectionIds.length} servers</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Knowledge Bases</p>\n <p className=\"font-medium\">{knowledgeBaseIds.length} KBs</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Max Concurrent</p>\n <p className=\"font-medium\">{maxConcurrentExecutions}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Executions</p>\n <p className=\"font-medium\">{agent.executionCount ?? 0}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Created</p>\n <p className=\"font-medium\">{formatRelativeTime(agent.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Updated</p>\n <p className=\"font-medium\">{formatRelativeTime(agent.updatedAt)}</p>\n </div>\n </CardContent>\n </Card>\n\n {/* Capabilities */}\n <GlassCard treatment=\"glass\" glow className=\"lg:col-span-2 p-6\">\n <h3 className=\"mb-4 text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.agentDetail.capabilities.title', 'Capabilities')}\n </h3>\n <div>\n {capabilities.length > 0 ? (\n <div className=\"grid grid-cols-2 md:grid-cols-3 gap-4\">\n {capabilities.map((cap: string) => (\n <div\n key={cap}\n className=\"p-3 rounded-lg border border-green-500 bg-green-500/10\"\n >\n <p className=\"font-medium\">{cap}</p>\n <Badge variant=\"success\">\n {t('botlit.agentDetail.capabilities.enabled', 'Enabled')}\n </Badge>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">\n {t('botlit.agentDetail.capabilities.empty', 'No capabilities configured')}\n </p>\n )}\n </div>\n </GlassCard>\n\n {/* Tags */}\n {tagIds.length > 0 && (\n <Card className=\"lg:col-span-3\">\n <CardHeader>\n <CardTitle>{t('botlit.agentDetail.tags.title', 'Tags')}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap gap-2\">\n {tagIds.map((tag: string) => (\n <Badge key={tag} variant=\"outline\">\n {tag}\n </Badge>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n </div>\n )}\n\n {/* Prompt Tab */}\n {activeTab === 'prompt' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <FileText size={18} />\n {t('botlit.agentDetail.prompt.title', 'System Prompt')}\n </CardTitle>\n <CardDescription>\n {t(\n 'botlit.agentDetail.prompt.description',\n \"The system prompt that defines this agent's behavior\"\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {systemPrompt ? (\n <pre className=\"p-4 bg-bg-sunken rounded-lg text-sm whitespace-pre-wrap font-mono\">\n {systemPrompt}\n </pre>\n ) : (\n <p className=\"text-text-secondary\">\n {t('botlit.agentDetail.prompt.empty', 'No system prompt configured')}\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* LLM Config Tab */}\n {activeTab === 'llm' && (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Brain size={18} />\n {t('botlit.agentDetail.llm.title', 'Model Configuration')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">LLM Model ID</p>\n <p className=\"font-medium font-mono\">{llmModelId || 'Not configured'}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Temperature</p>\n <p className=\"font-medium\">{temperature != null ? temperature : 'Default'}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Max Tokens</p>\n <p className=\"font-medium\">{maxTokens != null ? maxTokens : 'Default'}</p>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <MessageSquare size={18} />\n {t('botlit.agentDetail.executionLimits.title', 'Execution Limits')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Max Concurrent Executions</p>\n <p className=\"font-medium\">{maxConcurrentExecutions}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Total Executions</p>\n <p className=\"font-medium\">{agent.executionCount ?? 0}</p>\n </div>\n {agent.lastExecutedAt && (\n <div>\n <p className=\"text-sm text-text-secondary\">Last Executed</p>\n <p className=\"font-medium\">{formatRelativeTime(agent.lastExecutedAt)}</p>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Tools Tab */}\n {activeTab === 'tools' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wrench size={18} />\n MCP Server Connections\n </CardTitle>\n <CardDescription>Connected MCP servers providing tools</CardDescription>\n </CardHeader>\n <CardContent>\n {mcpConnectionIds.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {mcpConnectionIds.map((mcpId: string) => (\n <div\n key={mcpId}\n className=\"flex items-center gap-3 p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <Wrench size={18} className=\"text-primary\" />\n </div>\n <div>\n <p className=\"font-medium\">MCP Server</p>\n <p className=\"text-sm text-text-secondary font-mono\">{mcpId}</p>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">No MCP servers connected</p>\n )}\n </CardContent>\n </Card>\n\n {workflowIds.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Settings size={18} />\n Workflows\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {workflowIds.map((wfId: string) => (\n <div key={wfId} className=\"p-4 border border-border-subtle rounded-lg\">\n <p className=\"font-mono text-sm\">{wfId}</p>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n )}\n\n {/* Knowledge Tab */}\n {activeTab === 'knowledge' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <BookOpen size={18} />\n Knowledge Bases\n </CardTitle>\n <CardDescription>Connected knowledge bases for RAG</CardDescription>\n </CardHeader>\n <CardContent>\n {knowledgeBaseIds.length > 0 ? (\n <div className=\"space-y-4\">\n {knowledgeBaseIds.map((kbId: string, index: number) => (\n <div\n key={index}\n className=\"p-4 border border-border-subtle rounded-lg space-y-2\"\n >\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium\">Knowledge Base</p>\n <Badge variant=\"outline\">#{index + 1}</Badge>\n </div>\n <p className=\"font-mono text-sm\">{kbId}</p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">No knowledge bases connected</p>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* Guardrails Tab */}\n {activeTab === 'guardrails' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Shield size={18} />\n Guardrails & Policies\n </CardTitle>\n <CardDescription>Security and policy configurations</CardDescription>\n </CardHeader>\n <CardContent>\n {metadata ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {Object.entries(metadata)\n .filter(([_, value]) => value)\n .map(([key, value]) => (\n <div key={key} className=\"p-4 border border-border-subtle rounded-lg\">\n <p className=\"text-sm text-text-secondary capitalize\">\n {key\n .replace('Id', '')\n .replace(/([A-Z])/g, ' $1')\n .trim()}\n </p>\n <p className=\"font-mono text-sm\">{String(value)}</p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">No policy bindings configured</p>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* A2A Tab */}\n {activeTab === 'a2a' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Share2 size={18} />\n A2A Configuration\n </CardTitle>\n <CardDescription>Agent-to-Agent communication settings</CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-text-secondary\">A2A is not enabled for this agent</p>\n </CardContent>\n </Card>\n )}\n\n {/* Versions Tab (BOFF-4381) */}\n {activeTab === 'versions' && agentId && (\n <VersionHistoryPanel\n agentId={agentId}\n draftVersionId={agent.draftVersionId}\n currentVersionId={agent.currentVersionId}\n onChanged={() => void refetchAgent()}\n />\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentDetailPage.js","names":[],"sources":["../../../src/botlit/pages/AgentDetailPage.tsx"],"sourcesContent":["/**\n * Agent Detail Page\n * @module botlit/pages\n *\n * Displays agent details using flat API fields from the real GraphQL backend.\n * Maps flat fields (systemPrompt, llmModelId, mcpConnectionIds, knowledgeBaseIds, capabilities[])\n * to a rich detail view with tabs.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport {\n ArrowLeft,\n Play,\n Settings,\n BarChart3,\n BookOpen,\n Wrench,\n Shield,\n Brain,\n MessageSquare,\n Edit,\n Share2,\n FileText,\n Trash2,\n History,\n ShieldCheck,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { toast } from 'sonner';\nimport { PagePurpose, NextSteps, GlassCard } 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 { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { VersionHistoryPanel } from '../components/VersionHistoryPanel';\nimport { AgentApprovalPanel } from '../components/AgentApprovalPanel';\nimport { useAgentApprovalSettings } from '../hooks/useAgentApprovals';\nimport { AssistantRuntimeSetupPanel } from '../components/AssistantRuntimeSetupPanel';\nimport { AssistantChannelPanel } from '../components/AssistantChannelPanel';\nimport { AssistantWebsitePanel } from '../components/AssistantWebsitePanel';\nimport { AiOperationsPanel } from '../components/AiOperationsPanel';\nimport { useAgent, useUpdateAgent, useDeleteAgent } from '../hooks/useAgents';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { cn } from '../utils/cn';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate, useBotmanorCan } from '../permissions';\n\ntype TabType =\n | 'overview'\n | 'prompt'\n | 'llm'\n | 'tools'\n | 'knowledge'\n | 'guardrails'\n | 'aiOperations'\n | 'a2a'\n | 'versions'\n | 'assistant';\n\nexport const AgentDetailPage: FC = () => {\n const t = useTr();\n const { agentId } = useParams();\n const { navigateTo } = useBotlit();\n const can = useBotmanorCan();\n const { data: agent, loading, refetch: refetchAgent } = useAgent(agentId);\n const [updateAgent, updateAgentResult] = useUpdateAgent();\n const [deleteAgent, deleteAgentResult] = useDeleteAgent();\n const [activeTab, setActiveTab] = useState<TabType>('overview');\n // BOFF-9682: when the workspace requires activation approval, an agent that\n // has never been published goes live through a reviewer, not this button.\n const approvalSettings = useAgentApprovalSettings();\n\n if (loading) {\n return (\n <PageLayout title={t('botlit.common.loading', 'Loading...')}>\n <div className=\"h-96 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n </PageLayout>\n );\n }\n\n if (!agent) {\n return (\n <PageLayout title={t('botlit.agentDetail.notFound.title', 'Agent Not Found')}>\n <EmptyState\n illustration=\"empty-agents\"\n title={t('botlit.agentDetail.notFound.title', 'Agent Not Found')}\n description={t(\n 'botlit.agentDetail.notFound.description',\n \"The agent you're looking for doesn't exist.\"\n )}\n action={\n <Button onClick={() => navigateTo('agents')}>\n {t('botlit.agentDetail.notFound.backAction', 'Back to Agents')}\n </Button>\n }\n />\n </PageLayout>\n );\n }\n\n // `AgentRecord` declares every field the agent query selects โ read directly.\n const systemPrompt = agent.systemPrompt || '';\n const llmModelId = agent.llmModelId || '';\n const temperature = agent.temperature;\n const maxTokens = agent.maxTokens;\n const mcpConnectionIds = agent.mcpConnectionIds ?? [];\n const knowledgeBaseIds = agent.knowledgeBaseIds ?? [];\n const workflowIds = agent.workflowIds ?? [];\n const capabilities = agent.capabilities ?? [];\n const tagIds = agent.tagIds ?? [];\n const maxConcurrentExecutions = agent.maxConcurrentExecutions || 10;\n const metadata = agent.metadata ?? null;\n\n const tabs: { id: TabType; label: string; icon: ReactNode }[] = [\n { id: 'assistant', label: 'Assistant setup', icon: <Settings size={16} /> },\n {\n id: 'overview',\n label: t('botlit.agentDetail.tabs.overview', 'Overview'),\n icon: <BarChart3 size={16} />,\n },\n {\n id: 'prompt',\n label: t('botlit.agentDetail.tabs.prompt', 'Prompt'),\n icon: <FileText size={16} />,\n },\n {\n id: 'llm',\n label: t('botlit.agentDetail.tabs.llmConfig', 'LLM Config'),\n icon: <Brain size={16} />,\n },\n { id: 'tools', label: t('botlit.agentDetail.tabs.tools', 'Tools'), icon: <Wrench size={16} /> },\n {\n id: 'knowledge',\n label: t('botlit.agentDetail.tabs.knowledge', 'Knowledge'),\n icon: <BookOpen size={16} />,\n },\n {\n id: 'guardrails',\n label: t('botlit.agentDetail.tabs.guardrails', 'Guardrails'),\n icon: <Shield size={16} />,\n },\n {\n id: 'aiOperations',\n label: t('botlit.agentDetail.tabs.aiOperations', 'AI Operations'),\n icon: <ShieldCheck size={16} />,\n },\n { id: 'a2a', label: t('botlit.agentDetail.tabs.a2a', 'A2A'), icon: <Share2 size={16} /> },\n {\n id: 'versions',\n label: t('botlit.agentDetail.tabs.versions', 'Versions'),\n icon: <History size={16} />,\n },\n ];\n\n return (\n <PageLayout\n title={\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigateTo('agents')}>\n <ArrowLeft size={20} />\n </Button>\n <span className=\"text-3xl\">{'๐ค'}</span>\n <div>\n <div className=\"flex items-center gap-2\">\n <span>{agent.name}</span>\n <StatusBadge status={agent.status} />\n <Badge variant=\"outline\">{agent.slug}</Badge>\n </div>\n <p className=\"text-sm font-normal text-text-secondary\">{agent.description}</p>\n </div>\n </div>\n }\n actions={\n <div className=\"flex gap-2\">\n {approvalSettings.data?.requireActivationApproval &&\n (agent.status === 'DRAFT' || agent.status === 'ARCHIVED') &&\n !agent.currentVersionId ? (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"default\"\n onClick={() => {\n setActiveTab('overview');\n requestAnimationFrame(() =>\n document\n .querySelector('[data-testid=\"agent-approval-panel\"]')\n ?.scrollIntoView({ behavior: 'smooth', block: 'start' })\n );\n }}\n >\n {t('botlit.agentApproval.requestAction', 'Request activation')}\n </Button>\n </BotmanorPermissionGate>\n ) : agent.status === 'DRAFT' || agent.status === 'ARCHIVED' ? (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"default\"\n isLoading={updateAgentResult.loading}\n onClick={async () => {\n try {\n if (!agentId) return;\n await updateAgent({ agentId, input: { status: 'ACTIVE' } });\n await refetchAgent();\n toast.success(\n `${t('botlit.agentDetail.activate.successPrefix', 'Agent')} \"${agent.name}\" ${t('botlit.agentDetail.activate.successSuffix', 'activated')}`\n );\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentDetail.activate.error', 'Failed to activate agent')\n );\n }\n }}\n >\n {t('botlit.agentDetail.actions.activate', 'Activate')}\n </Button>\n </BotmanorPermissionGate>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"outline\"\n isLoading={updateAgentResult.loading}\n onClick={async () => {\n try {\n if (!agentId) return;\n await updateAgent({ agentId, input: { status: 'DRAFT' } });\n await refetchAgent();\n toast.success(\n `${t('botlit.agentDetail.deactivate.successPrefix', 'Agent')} \"${agent.name}\" ${t('botlit.agentDetail.deactivate.successSuffix', 'deactivated')}`\n );\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentDetail.deactivate.error', 'Failed to deactivate agent')\n );\n }\n }}\n >\n {t('botlit.agentDetail.actions.deactivate', 'Deactivate')}\n </Button>\n </BotmanorPermissionGate>\n )}\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_UPDATE}>\n <Button\n variant=\"outline\"\n leftIcon={<Edit size={16} />}\n onClick={() => navigateTo(`agents/${agentId}/edit`)}\n >\n {t('botlit.agentDetail.actions.editAgent', 'Edit Agent')}\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_EXECUTE}>\n <Button leftIcon={<Play size={16} />} onClick={() => navigateTo(`chat/${agentId}`)}>\n {t('botlit.agentDetail.actions.testAgent', 'Test Agent')}\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.AGENT_DELETE}>\n <Button\n variant=\"destructive\"\n leftIcon={<Trash2 size={16} />}\n isLoading={deleteAgentResult.loading}\n onClick={async () => {\n if (!agentId) return;\n if (\n !confirm(\n `${t('botlit.agentDetail.delete.confirmPrefix', 'Are you sure you want to delete')} \"${agent.name}\"? ${t('botlit.agentDetail.delete.confirmSuffix', 'This action cannot be undone.')}`\n )\n )\n return;\n try {\n await deleteAgent(agentId);\n toast.success(\n `${t('botlit.agentDetail.delete.successPrefix', 'Agent')} \"${agent.name}\" ${t('botlit.agentDetail.delete.successSuffix', 'deleted successfully')}`\n );\n navigateTo('agents');\n } catch (err: unknown) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.agentDetail.delete.error', 'Failed to delete agent')\n );\n }\n }}\n >\n {t('botlit.common.delete', 'Delete')}\n </Button>\n </BotmanorPermissionGate>\n </div>\n }\n >\n <div className=\"space-y-6\">\n {activeTab === 'assistant' && agentId && (\n <div className=\"space-y-5\">\n {/* Each panel is setup work: runtime configuration needs update, and\n publishing (whose listings are publish-gated too) needs publish. */}\n {can(BOTMANOR_PERMISSIONS.AGENT_UPDATE) && (\n <AssistantRuntimeSetupPanel\n agentId={agentId}\n onConfigured={() => void refetchAgent()}\n />\n )}\n {can(BOTMANOR_PERMISSIONS.AGENT_PUBLISH) && (\n <>\n <AssistantWebsitePanel agentId={agentId} knowledgeBaseIds={knowledgeBaseIds} />\n <AssistantChannelPanel agentId={agentId} />\n </>\n )}\n {!can(BOTMANOR_PERMISSIONS.AGENT_UPDATE) &&\n !can(BOTMANOR_PERMISSIONS.AGENT_PUBLISH) && (\n <p role=\"status\" className=\"text-sm text-text-secondary\">\n {t(\n 'botlit.agentDetail.assistant.readOnly',\n 'Assistant setup and publishing are available to members who can edit or publish agents in this workspace.'\n )}\n </p>\n )}\n </div>\n )}\n <PagePurpose icon={<Brain size={18} />}>\n {t(\n 'botlit.agentDetail.purpose',\n 'This is the full configuration for a single agent โ its prompt, model settings, the tools and knowledge it can use, its guardrails and how it talks to other agents. Use the tabs to inspect or change any part, and test the agent in chat to confirm it behaves the way you expect before going live.'\n )}\n </PagePurpose>\n\n {/* Tabs */}\n <div className=\"flex gap-1 border-b border-border-subtle overflow-x-auto\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex items-center gap-2 px-4 py-2 text-sm font-medium border-b-2 transition-colors whitespace-nowrap',\n activeTab === tab.id\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.icon}\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Overview Tab */}\n {activeTab === 'overview' && (\n <div className=\"space-y-6\">\n <NextSteps\n storageKey={`botlit-agent-${agentId}`}\n steps={[\n {\n id: 'test',\n label: t('botlit.agentDetail.nextSteps.test', 'Test the agent in chat'),\n description: t(\n 'botlit.agentDetail.nextSteps.testDesc',\n 'Send it a few real prompts to see how it responds.'\n ),\n icon: <Play size={16} />,\n onClick: () => navigateTo(`chat/${agentId}`),\n },\n {\n id: 'prompt',\n label: t('botlit.agentDetail.nextSteps.prompt', 'Refine the system prompt'),\n description: t(\n 'botlit.agentDetail.nextSteps.promptDesc',\n 'Tune its instructions and behaviour.'\n ),\n icon: <FileText size={16} />,\n onClick: () => setActiveTab('prompt'),\n },\n {\n id: 'tools',\n label: t('botlit.agentDetail.nextSteps.tools', 'Connect tools & knowledge'),\n description: t(\n 'botlit.agentDetail.nextSteps.toolsDesc',\n 'Give it MCP tools and knowledge bases to work with.'\n ),\n icon: <Wrench size={16} />,\n onClick: () => setActiveTab('tools'),\n },\n {\n id: 'activate',\n label: t('botlit.agentDetail.nextSteps.activate', 'Activate and attach to a bot'),\n description: t(\n 'botlit.agentDetail.nextSteps.activateDesc',\n 'Put it live so a bot can route conversations to it.'\n ),\n icon: <Share2 size={16} />,\n onClick: () => navigateTo(`agents/${agentId}/edit`),\n done: agent.status === 'ACTIVE',\n },\n ]}\n />\n {agentId && (\n <AgentApprovalPanel\n agentId={agentId}\n agentStatus={agent.status}\n onChanged={() => void refetchAgent()}\n />\n )}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Quick Info */}\n <Card className=\"lg:col-span-1\">\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Status</p>\n <StatusBadge status={agent.status} />\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Type</p>\n <Badge variant=\"outline\">{agent.type}</Badge>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Visibility</p>\n <Badge variant=\"outline\">{agent.visibility}</Badge>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">LLM Model</p>\n <p className=\"font-medium font-mono text-sm\">\n {llmModelId || 'Not configured'}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">MCP Connections</p>\n <p className=\"font-medium\">{mcpConnectionIds.length} servers</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Knowledge Bases</p>\n <p className=\"font-medium\">{knowledgeBaseIds.length} KBs</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Max Concurrent</p>\n <p className=\"font-medium\">{maxConcurrentExecutions}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Executions</p>\n <p className=\"font-medium\">{agent.executionCount ?? 0}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Created</p>\n <p className=\"font-medium\">{formatRelativeTime(agent.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Updated</p>\n <p className=\"font-medium\">{formatRelativeTime(agent.updatedAt)}</p>\n </div>\n </CardContent>\n </Card>\n\n {/* Capabilities */}\n <GlassCard treatment=\"glass\" glow className=\"lg:col-span-2 p-6\">\n <h3 className=\"mb-4 text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.agentDetail.capabilities.title', 'Capabilities')}\n </h3>\n <div>\n {capabilities.length > 0 ? (\n <div className=\"grid grid-cols-2 md:grid-cols-3 gap-4\">\n {capabilities.map((cap: string) => (\n <div\n key={cap}\n className=\"p-3 rounded-lg border border-green-500 bg-green-500/10\"\n >\n <p className=\"font-medium\">{cap}</p>\n <Badge variant=\"success\">\n {t('botlit.agentDetail.capabilities.enabled', 'Enabled')}\n </Badge>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">\n {t('botlit.agentDetail.capabilities.empty', 'No capabilities configured')}\n </p>\n )}\n </div>\n </GlassCard>\n\n {/* Tags */}\n {tagIds.length > 0 && (\n <Card className=\"lg:col-span-3\">\n <CardHeader>\n <CardTitle>{t('botlit.agentDetail.tags.title', 'Tags')}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap gap-2\">\n {tagIds.map((tag: string) => (\n <Badge key={tag} variant=\"outline\">\n {tag}\n </Badge>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n </div>\n )}\n\n {/* Prompt Tab */}\n {activeTab === 'prompt' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <FileText size={18} />\n {t('botlit.agentDetail.prompt.title', 'System Prompt')}\n </CardTitle>\n <CardDescription>\n {t(\n 'botlit.agentDetail.prompt.description',\n \"The system prompt that defines this agent's behavior\"\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {systemPrompt ? (\n <pre className=\"p-4 bg-bg-sunken rounded-lg text-sm whitespace-pre-wrap font-mono\">\n {systemPrompt}\n </pre>\n ) : (\n <p className=\"text-text-secondary\">\n {t('botlit.agentDetail.prompt.empty', 'No system prompt configured')}\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* LLM Config Tab */}\n {activeTab === 'llm' && (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Brain size={18} />\n {t('botlit.agentDetail.llm.title', 'Model Configuration')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">LLM Model ID</p>\n <p className=\"font-medium font-mono\">{llmModelId || 'Not configured'}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Temperature</p>\n <p className=\"font-medium\">{temperature != null ? temperature : 'Default'}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Max Tokens</p>\n <p className=\"font-medium\">{maxTokens != null ? maxTokens : 'Default'}</p>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <MessageSquare size={18} />\n {t('botlit.agentDetail.executionLimits.title', 'Execution Limits')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Max Concurrent Executions</p>\n <p className=\"font-medium\">{maxConcurrentExecutions}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Total Executions</p>\n <p className=\"font-medium\">{agent.executionCount ?? 0}</p>\n </div>\n {agent.lastExecutedAt && (\n <div>\n <p className=\"text-sm text-text-secondary\">Last Executed</p>\n <p className=\"font-medium\">{formatRelativeTime(agent.lastExecutedAt)}</p>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Tools Tab */}\n {activeTab === 'tools' && (\n <div className=\"space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wrench size={18} />\n MCP Server Connections\n </CardTitle>\n <CardDescription>Connected MCP servers providing tools</CardDescription>\n </CardHeader>\n <CardContent>\n {mcpConnectionIds.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {mcpConnectionIds.map((mcpId: string) => (\n <div\n key={mcpId}\n className=\"flex items-center gap-3 p-4 border border-border-subtle rounded-lg\"\n >\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <Wrench size={18} className=\"text-primary\" />\n </div>\n <div>\n <p className=\"font-medium\">MCP Server</p>\n <p className=\"text-sm text-text-secondary font-mono\">{mcpId}</p>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">No MCP servers connected</p>\n )}\n </CardContent>\n </Card>\n\n {workflowIds.length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Settings size={18} />\n Workflows\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {workflowIds.map((wfId: string) => (\n <div key={wfId} className=\"p-4 border border-border-subtle rounded-lg\">\n <p className=\"font-mono text-sm\">{wfId}</p>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n )}\n\n {/* Knowledge Tab */}\n {activeTab === 'knowledge' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <BookOpen size={18} />\n Knowledge Bases\n </CardTitle>\n <CardDescription>Connected knowledge bases for RAG</CardDescription>\n </CardHeader>\n <CardContent>\n {knowledgeBaseIds.length > 0 ? (\n <div className=\"space-y-4\">\n {knowledgeBaseIds.map((kbId: string, index: number) => (\n <div\n key={index}\n className=\"p-4 border border-border-subtle rounded-lg space-y-2\"\n >\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium\">Knowledge Base</p>\n <Badge variant=\"outline\">#{index + 1}</Badge>\n </div>\n <p className=\"font-mono text-sm\">{kbId}</p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">No knowledge bases connected</p>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* Guardrails Tab */}\n {activeTab === 'guardrails' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Shield size={18} />\n Guardrails & Policies\n </CardTitle>\n <CardDescription>Security and policy configurations</CardDescription>\n </CardHeader>\n <CardContent>\n {metadata ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {Object.entries(metadata)\n .filter(([_, value]) => value)\n .map(([key, value]) => (\n <div key={key} className=\"p-4 border border-border-subtle rounded-lg\">\n <p className=\"text-sm text-text-secondary capitalize\">\n {key\n .replace('Id', '')\n .replace(/([A-Z])/g, ' $1')\n .trim()}\n </p>\n <p className=\"font-mono text-sm\">{String(value)}</p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-text-secondary\">No policy bindings configured</p>\n )}\n </CardContent>\n </Card>\n )}\n\n {/* AI Operations Tab (supervisor findings for this agent, BOFF-3839) */}\n {activeTab === 'aiOperations' && agentId && (\n <AiOperationsPanel\n filter={{ subjectType: 'AGENT', subjectId: agentId }}\n description={t(\n 'botlit.agentDetail.aiOperationsDescription',\n 'What the supervisor flagged for this agent โ drift, evidence and the recommended action.'\n )}\n />\n )}\n\n {/* A2A Tab */}\n {activeTab === 'a2a' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Share2 size={18} />\n A2A Configuration\n </CardTitle>\n <CardDescription>Agent-to-Agent communication settings</CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"text-text-secondary\">A2A is not enabled for this agent</p>\n </CardContent>\n </Card>\n )}\n\n {/* Versions Tab (BOFF-4381) */}\n {activeTab === 'versions' && agentId && (\n <VersionHistoryPanel\n agentId={agentId}\n draftVersionId={agent.draftVersionId}\n currentVersionId={agent.currentVersionId}\n onChanged={() => void refetchAgent()}\n />\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
|
+
import { formatRelativeTime as t } from "../utils/formatters.js";
|
|
3
|
+
import { PageLayout as n } from "../components/PageLayout.js";
|
|
4
|
+
import { Button as r } from "../components/Button.js";
|
|
5
|
+
import { Card as i, CardContent as a, CardHeader as o, CardTitle as s } from "../components/Card.js";
|
|
6
|
+
import { Badge as c } from "../components/Badge.js";
|
|
7
|
+
import { Input as l, Label as u } from "../components/Input.js";
|
|
8
|
+
import { ErrorState as d } from "../components/ErrorState.js";
|
|
9
|
+
import { useConfigureSupervisor as f, useRunSupervisorNow as p, useSupervisorConfig as m, useSupervisorRuns as h } from "../hooks/useAiOperations.js";
|
|
10
|
+
import "../hooks/index.js";
|
|
11
|
+
import { AiOperationsPanel as g } from "../components/AiOperationsPanel.js";
|
|
12
|
+
import { useState as _ } from "react";
|
|
13
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
14
|
+
import { Play as b, ShieldCheck as x } from "lucide-react";
|
|
15
|
+
//#region src/botlit/pages/AiOperationsPage.tsx
|
|
16
|
+
var S = "0 9 * * *", C = "UTC", w = () => {
|
|
17
|
+
let n = e(), { data: r, loading: c, error: p, refetch: h } = m(), [g, b] = f(), [w, T] = _(null), [E, D] = _(null), [O, k] = _(null), A = r?.enabled ?? !1, j = w ?? r?.cron ?? S, M = E ?? r?.timezone ?? C, N = b.loading || c, P = async (e) => {
|
|
18
|
+
k(null);
|
|
19
|
+
try {
|
|
20
|
+
await g(e), await h();
|
|
21
|
+
} catch (e) {
|
|
22
|
+
k(e instanceof Error ? e.message : String(e));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
return p ? /* @__PURE__ */ v(d, {
|
|
26
|
+
resource: n("botlit.aiOperations.configErrorTitle", "Supervisor configuration"),
|
|
27
|
+
error: p,
|
|
28
|
+
onRetry: () => void h()
|
|
29
|
+
}) : /* @__PURE__ */ y(i, { children: [/* @__PURE__ */ v(o, { children: /* @__PURE__ */ y(s, {
|
|
30
|
+
className: "flex items-center gap-2 text-base",
|
|
31
|
+
children: [/* @__PURE__ */ v(x, { className: "h-4 w-4" }), n("botlit.aiOperations.configTitle", "Scheduled fleet review")]
|
|
32
|
+
}) }), /* @__PURE__ */ y(a, {
|
|
33
|
+
className: "space-y-4",
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ y("label", {
|
|
36
|
+
className: "flex items-center gap-2 text-sm text-text-primary",
|
|
37
|
+
children: [/* @__PURE__ */ v("input", {
|
|
38
|
+
type: "checkbox",
|
|
39
|
+
className: "h-4 w-4",
|
|
40
|
+
checked: A,
|
|
41
|
+
disabled: N,
|
|
42
|
+
onChange: (e) => void P({
|
|
43
|
+
enabled: e.target.checked,
|
|
44
|
+
cron: j,
|
|
45
|
+
timezone: M
|
|
46
|
+
})
|
|
47
|
+
}), n("botlit.aiOperations.configEnable", "Run the supervisor automatically every day")]
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ y("div", {
|
|
50
|
+
className: "grid gap-4 sm:grid-cols-2",
|
|
51
|
+
children: [/* @__PURE__ */ y("div", {
|
|
52
|
+
className: "space-y-1.5",
|
|
53
|
+
children: [/* @__PURE__ */ v(u, {
|
|
54
|
+
htmlFor: "supervisor-cron",
|
|
55
|
+
children: n("botlit.aiOperations.cronLabel", "Cron (FluidGrids schedule)")
|
|
56
|
+
}), /* @__PURE__ */ v(l, {
|
|
57
|
+
id: "supervisor-cron",
|
|
58
|
+
value: j,
|
|
59
|
+
disabled: N,
|
|
60
|
+
onChange: (e) => T(e.target.value),
|
|
61
|
+
onBlur: () => void P({
|
|
62
|
+
enabled: A,
|
|
63
|
+
cron: j,
|
|
64
|
+
timezone: M
|
|
65
|
+
}),
|
|
66
|
+
placeholder: S
|
|
67
|
+
})]
|
|
68
|
+
}), /* @__PURE__ */ y("div", {
|
|
69
|
+
className: "space-y-1.5",
|
|
70
|
+
children: [/* @__PURE__ */ v(u, {
|
|
71
|
+
htmlFor: "supervisor-timezone",
|
|
72
|
+
children: n("botlit.aiOperations.timezoneLabel", "Timezone")
|
|
73
|
+
}), /* @__PURE__ */ v(l, {
|
|
74
|
+
id: "supervisor-timezone",
|
|
75
|
+
value: M,
|
|
76
|
+
disabled: N,
|
|
77
|
+
onChange: (e) => D(e.target.value),
|
|
78
|
+
onBlur: () => void P({
|
|
79
|
+
enabled: A,
|
|
80
|
+
cron: j,
|
|
81
|
+
timezone: M
|
|
82
|
+
}),
|
|
83
|
+
placeholder: C
|
|
84
|
+
})]
|
|
85
|
+
})]
|
|
86
|
+
}),
|
|
87
|
+
r?.lastRunAt && /* @__PURE__ */ v("p", {
|
|
88
|
+
className: "text-xs text-text-tertiary",
|
|
89
|
+
children: n("botlit.aiOperations.lastRun", "Last review: {{time}}", { time: t(r.lastRunAt) })
|
|
90
|
+
}),
|
|
91
|
+
O && /* @__PURE__ */ v("p", {
|
|
92
|
+
className: "text-sm text-status-error-text",
|
|
93
|
+
role: "alert",
|
|
94
|
+
children: O
|
|
95
|
+
})
|
|
96
|
+
]
|
|
97
|
+
})] });
|
|
98
|
+
}, T = () => {
|
|
99
|
+
let n = e(), { data: r, loading: l, error: u } = h();
|
|
100
|
+
return u || !l && r.length === 0 ? null : /* @__PURE__ */ y(i, { children: [/* @__PURE__ */ v(o, { children: /* @__PURE__ */ v(s, {
|
|
101
|
+
className: "text-base",
|
|
102
|
+
children: n("botlit.aiOperations.runHistoryTitle", "Review history")
|
|
103
|
+
}) }), /* @__PURE__ */ v(a, { children: /* @__PURE__ */ v("ul", {
|
|
104
|
+
className: "divide-y divide-border-subtle",
|
|
105
|
+
children: r.map((e) => /* @__PURE__ */ y("li", {
|
|
106
|
+
className: "flex items-center justify-between gap-3 py-2 text-sm",
|
|
107
|
+
children: [/* @__PURE__ */ y("div", {
|
|
108
|
+
className: "flex items-center gap-2",
|
|
109
|
+
children: [/* @__PURE__ */ v(c, {
|
|
110
|
+
variant: e.status === "COMPLETED" ? "success" : e.status === "FAILED" ? "destructive" : "secondary",
|
|
111
|
+
children: e.status
|
|
112
|
+
}), /* @__PURE__ */ v("span", {
|
|
113
|
+
className: "text-text-secondary",
|
|
114
|
+
children: n("botlit.aiOperations.runMeta", "{{trigger}} ยท {{findings}} findings ยท {{notified}} notified", {
|
|
115
|
+
trigger: e.trigger,
|
|
116
|
+
findings: e.findings,
|
|
117
|
+
notified: e.notified
|
|
118
|
+
})
|
|
119
|
+
})]
|
|
120
|
+
}), /* @__PURE__ */ v("span", {
|
|
121
|
+
className: "text-xs text-text-tertiary whitespace-nowrap",
|
|
122
|
+
children: t(e.startedAt)
|
|
123
|
+
})]
|
|
124
|
+
}, e.id))
|
|
125
|
+
}) })] });
|
|
126
|
+
}, E = () => {
|
|
127
|
+
let t = e(), [i, a] = p(), [o, s] = _(null), [c, l] = _(null), u = a.loading, d = async () => {
|
|
128
|
+
s(null), l(null);
|
|
129
|
+
try {
|
|
130
|
+
let e = await i();
|
|
131
|
+
l(e.run ? t("botlit.aiOperations.runNowSummary", "Review finished: {{status}}, {{findings}} new findings.", {
|
|
132
|
+
status: e.run.status,
|
|
133
|
+
findings: e.findings
|
|
134
|
+
}) : t("botlit.aiOperations.runNowSkipped", "Nothing to run โ enable the scheduled review first."));
|
|
135
|
+
} catch (e) {
|
|
136
|
+
s(e instanceof Error ? e.message : String(e));
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
return /* @__PURE__ */ v(n, {
|
|
140
|
+
title: t("botlit.aiOperations.title", "AI Operations"),
|
|
141
|
+
description: t("botlit.aiOperations.description", "Supervisor findings across your agent fleet โ what drifted, the evidence, and the recommended action."),
|
|
142
|
+
actions: /* @__PURE__ */ y(r, {
|
|
143
|
+
variant: "outline",
|
|
144
|
+
onClick: () => void d(),
|
|
145
|
+
disabled: u,
|
|
146
|
+
children: [/* @__PURE__ */ v(b, { className: "h-4 w-4" }), t("botlit.aiOperations.runNow", "Run review now")]
|
|
147
|
+
}),
|
|
148
|
+
children: /* @__PURE__ */ y("div", {
|
|
149
|
+
className: "space-y-6",
|
|
150
|
+
children: [
|
|
151
|
+
(o || c) && /* @__PURE__ */ v("p", {
|
|
152
|
+
className: o ? "text-sm text-status-error-text" : "text-sm text-status-success-text",
|
|
153
|
+
role: "status",
|
|
154
|
+
children: o ?? c
|
|
155
|
+
}),
|
|
156
|
+
/* @__PURE__ */ v(g, {}),
|
|
157
|
+
/* @__PURE__ */ v(w, {}),
|
|
158
|
+
/* @__PURE__ */ v(T, {})
|
|
159
|
+
]
|
|
160
|
+
})
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
//#endregion
|
|
164
|
+
export { E as AiOperationsPage };
|
|
165
|
+
|
|
166
|
+
//# sourceMappingURL=AiOperationsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AiOperationsPage.js","names":[],"sources":["../../../src/botlit/pages/AiOperationsPage.tsx"],"sourcesContent":["/**\n * AI Operations Page (BOFF-3839)\n * @module botlit/pages\n *\n * The workspace-wide supervisor feed at /botmanor/ai: decision cards, the\n * supervisor schedule configuration (FluidGrids owns the cron โ enabling\n * provisions it, disabling removes it), a run-now action and the run\n * history. The same decision-card panel renders narrowed on the agent and\n * bot detail pages.\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Play, ShieldCheck } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PageLayout } from '../components/PageLayout';\nimport { AiOperationsPanel } from '../components/AiOperationsPanel';\nimport { Badge } from '../components/Badge';\nimport { Button } from '../components/Button';\nimport { Card, CardContent, CardHeader, CardTitle } from '../components/Card';\nimport { ErrorState } from '../components/ErrorState';\nimport { Input, Label } from '../components/Input';\nimport {\n useConfigureSupervisor,\n useRunSupervisorNow,\n useSupervisorConfig,\n useSupervisorRuns,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\n\nconst DEFAULT_CRON = '0 9 * * *';\nconst DEFAULT_TIMEZONE = 'UTC';\n\n/** Schedule configuration: enable switch + cadence, provisioned in FluidGrids. */\nconst SupervisorConfigSection: FC = () => {\n const t = useTr();\n const { data: config, loading, error, refetch } = useSupervisorConfig();\n const [configure, configureState] = useConfigureSupervisor();\n const [cron, setCron] = useState<string | null>(null);\n const [timezone, setTimezone] = useState<string | null>(null);\n const [saveError, setSaveError] = useState<string | null>(null);\n\n const enabled = config?.enabled ?? false;\n const effectiveCron = cron ?? config?.cron ?? DEFAULT_CRON;\n const effectiveTimezone = timezone ?? config?.timezone ?? DEFAULT_TIMEZONE;\n const busy = configureState.loading || loading;\n\n const save = async (next: { enabled: boolean; cron: string; timezone: string }) => {\n setSaveError(null);\n try {\n await configure(next);\n await refetch();\n } catch (configureError) {\n setSaveError(\n configureError instanceof Error ? configureError.message : String(configureError)\n );\n }\n };\n\n if (error) {\n return (\n <ErrorState\n resource={t('botlit.aiOperations.configErrorTitle', 'Supervisor configuration')}\n error={error}\n onRetry={() => void refetch()}\n />\n );\n }\n\n return (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <ShieldCheck className=\"h-4 w-4\" />\n {t('botlit.aiOperations.configTitle', 'Scheduled fleet review')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <label className=\"flex items-center gap-2 text-sm text-text-primary\">\n <input\n type=\"checkbox\"\n className=\"h-4 w-4\"\n checked={enabled}\n disabled={busy}\n onChange={(event) =>\n void save({\n enabled: event.target.checked,\n cron: effectiveCron,\n timezone: effectiveTimezone,\n })\n }\n />\n {t('botlit.aiOperations.configEnable', 'Run the supervisor automatically every day')}\n </label>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"supervisor-cron\">\n {t('botlit.aiOperations.cronLabel', 'Cron (FluidGrids schedule)')}\n </Label>\n <Input\n id=\"supervisor-cron\"\n value={effectiveCron}\n disabled={busy}\n onChange={(event) => setCron(event.target.value)}\n onBlur={() =>\n void save({ enabled, cron: effectiveCron, timezone: effectiveTimezone })\n }\n placeholder={DEFAULT_CRON}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"supervisor-timezone\">\n {t('botlit.aiOperations.timezoneLabel', 'Timezone')}\n </Label>\n <Input\n id=\"supervisor-timezone\"\n value={effectiveTimezone}\n disabled={busy}\n onChange={(event) => setTimezone(event.target.value)}\n onBlur={() =>\n void save({ enabled, cron: effectiveCron, timezone: effectiveTimezone })\n }\n placeholder={DEFAULT_TIMEZONE}\n />\n </div>\n </div>\n {config?.lastRunAt && (\n <p className=\"text-xs text-text-tertiary\">\n {t('botlit.aiOperations.lastRun', 'Last review: {{time}}', {\n time: formatRelativeTime(config.lastRunAt),\n })}\n </p>\n )}\n {saveError && (\n <p className=\"text-sm text-status-error-text\" role=\"alert\">\n {saveError}\n </p>\n )}\n </CardContent>\n </Card>\n );\n};\n\n/** Recent supervisor runs (both triggers), newest first. */\nconst RunHistorySection: FC = () => {\n const t = useTr();\n const { data: runs, loading, error } = useSupervisorRuns();\n\n if (error || (!loading && runs.length === 0)) return null;\n\n return (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('botlit.aiOperations.runHistoryTitle', 'Review history')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <ul className=\"divide-y divide-border-subtle\">\n {runs.map((run) => (\n <li key={run.id} className=\"flex items-center justify-between gap-3 py-2 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Badge\n variant={\n run.status === 'COMPLETED'\n ? 'success'\n : run.status === 'FAILED'\n ? 'destructive'\n : 'secondary'\n }\n >\n {run.status}\n </Badge>\n <span className=\"text-text-secondary\">\n {t(\n 'botlit.aiOperations.runMeta',\n '{{trigger}} ยท {{findings}} findings ยท {{notified}} notified',\n {\n trigger: run.trigger,\n findings: run.findings,\n notified: run.notified,\n }\n )}\n </span>\n </div>\n <span className=\"text-xs text-text-tertiary whitespace-nowrap\">\n {formatRelativeTime(run.startedAt)}\n </span>\n </li>\n ))}\n </ul>\n </CardContent>\n </Card>\n );\n};\n\nexport const AiOperationsPage: FC = () => {\n const t = useTr();\n const [runNow, runNowState] = useRunSupervisorNow();\n const [runError, setRunError] = useState<string | null>(null);\n const [runSummary, setRunSummary] = useState<string | null>(null);\n const busy = runNowState.loading;\n\n const onRunNow = async () => {\n setRunError(null);\n setRunSummary(null);\n try {\n const result = await runNow();\n setRunSummary(\n result.run\n ? t(\n 'botlit.aiOperations.runNowSummary',\n 'Review finished: {{status}}, {{findings}} new findings.',\n {\n status: result.run.status,\n findings: result.findings,\n }\n )\n : t(\n 'botlit.aiOperations.runNowSkipped',\n 'Nothing to run โ enable the scheduled review first.'\n )\n );\n } catch (error) {\n setRunError(error instanceof Error ? error.message : String(error));\n }\n };\n\n return (\n <PageLayout\n title={t('botlit.aiOperations.title', 'AI Operations')}\n description={t(\n 'botlit.aiOperations.description',\n 'Supervisor findings across your agent fleet โ what drifted, the evidence, and the recommended action.'\n )}\n actions={\n <Button variant=\"outline\" onClick={() => void onRunNow()} disabled={busy}>\n <Play className=\"h-4 w-4\" />\n {t('botlit.aiOperations.runNow', 'Run review now')}\n </Button>\n }\n >\n <div className=\"space-y-6\">\n {(runError || runSummary) && (\n <p\n className={\n runError ? 'text-sm text-status-error-text' : 'text-sm text-status-success-text'\n }\n role=\"status\"\n >\n {runError ?? runSummary}\n </p>\n )}\n <AiOperationsPanel />\n <SupervisorConfigSection />\n <RunHistorySection />\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|