@burdenoff/microfe-botmanor 2026.813.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/README.md +12 -0
- package/dist/botlit/BotlitRoutes.js +357 -0
- package/dist/botlit/BotlitRoutes.js.map +1 -0
- package/dist/botlit/BotmanorRoot.js +12 -0
- package/dist/botlit/BotmanorRoot.js.map +1 -0
- package/dist/botlit/BotmanorRootInner.js +101 -0
- package/dist/botlit/BotmanorRootInner.js.map +1 -0
- package/dist/botlit/components/Badge.js +39 -0
- package/dist/botlit/components/Badge.js.map +1 -0
- package/dist/botlit/components/Button.js +46 -0
- package/dist/botlit/components/Button.js.map +1 -0
- package/dist/botlit/components/Card.js +31 -0
- package/dist/botlit/components/Card.js.map +1 -0
- package/dist/botlit/components/ChannelSelectorSheet.js +130 -0
- package/dist/botlit/components/ChannelSelectorSheet.js.map +1 -0
- package/dist/botlit/components/EmptyState.js +35 -0
- package/dist/botlit/components/EmptyState.js.map +1 -0
- package/dist/botlit/components/ErrorState.js +33 -0
- package/dist/botlit/components/ErrorState.js.map +1 -0
- package/dist/botlit/components/Input.js +59 -0
- package/dist/botlit/components/Input.js.map +1 -0
- package/dist/botlit/components/PageLayout.js +34 -0
- package/dist/botlit/components/PageLayout.js.map +1 -0
- package/dist/botlit/components/QuotaExhaustedDialog.js +20 -0
- package/dist/botlit/components/QuotaExhaustedDialog.js.map +1 -0
- package/dist/botlit/components/RouteLoader.js +52 -0
- package/dist/botlit/components/RouteLoader.js.map +1 -0
- package/dist/botlit/components/VersionHistoryPanel.js +144 -0
- package/dist/botlit/components/VersionHistoryPanel.js.map +1 -0
- package/dist/botlit/components/WorkspaceRequired.js +70 -0
- package/dist/botlit/components/WorkspaceRequired.js.map +1 -0
- package/dist/botlit/hooks/index.js +16 -0
- package/dist/botlit/hooks/internal/mutationInput.js +16 -0
- package/dist/botlit/hooks/internal/mutationInput.js.map +1 -0
- package/dist/botlit/hooks/internal/workspaceGateway.js +99 -0
- package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -0
- package/dist/botlit/hooks/useA2A.js +184 -0
- package/dist/botlit/hooks/useA2A.js.map +1 -0
- package/dist/botlit/hooks/useAgents.js +469 -0
- package/dist/botlit/hooks/useAgents.js.map +1 -0
- package/dist/botlit/hooks/useBots.js +306 -0
- package/dist/botlit/hooks/useBots.js.map +1 -0
- package/dist/botlit/hooks/useBuckets.js +119 -0
- package/dist/botlit/hooks/useBuckets.js.map +1 -0
- package/dist/botlit/hooks/useChannels.js +213 -0
- package/dist/botlit/hooks/useChannels.js.map +1 -0
- package/dist/botlit/hooks/useConversations.js +64 -0
- package/dist/botlit/hooks/useConversations.js.map +1 -0
- package/dist/botlit/hooks/useExecutions.js +86 -0
- package/dist/botlit/hooks/useExecutions.js.map +1 -0
- package/dist/botlit/hooks/useKnowledgeBases.js +113 -0
- package/dist/botlit/hooks/useKnowledgeBases.js.map +1 -0
- package/dist/botlit/hooks/useLLMProviders.js +83 -0
- package/dist/botlit/hooks/useLLMProviders.js.map +1 -0
- package/dist/botlit/hooks/useMCPServers.js +134 -0
- package/dist/botlit/hooks/useMCPServers.js.map +1 -0
- package/dist/botlit/hooks/usePolicies.js +120 -0
- package/dist/botlit/hooks/usePolicies.js.map +1 -0
- package/dist/botlit/hooks/usePromptTemplates.js +161 -0
- package/dist/botlit/hooks/usePromptTemplates.js.map +1 -0
- package/dist/botlit/hooks/useRetrievalProfiles.js +146 -0
- package/dist/botlit/hooks/useRetrievalProfiles.js.map +1 -0
- package/dist/botlit/hooks/useSkills.js +132 -0
- package/dist/botlit/hooks/useSkills.js.map +1 -0
- package/dist/botlit/hooks/useStore.js +167 -0
- package/dist/botlit/hooks/useStore.js.map +1 -0
- package/dist/botlit/hooks/useUserPlatformConnection.js +172 -0
- package/dist/botlit/hooks/useUserPlatformConnection.js.map +1 -0
- package/dist/botlit/index.js +11 -0
- package/dist/botlit/pages/A2AAgentDetailPage.js +589 -0
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -0
- package/dist/botlit/pages/A2ARegistryPage.js +240 -0
- package/dist/botlit/pages/A2ARegistryPage.js.map +1 -0
- package/dist/botlit/pages/AgentBuilderPage.js +486 -0
- package/dist/botlit/pages/AgentBuilderPage.js.map +1 -0
- package/dist/botlit/pages/AgentDetailPage.js +517 -0
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -0
- package/dist/botlit/pages/AgentsListPage.js +294 -0
- package/dist/botlit/pages/AgentsListPage.js.map +1 -0
- package/dist/botlit/pages/BotChannelsTab.js +530 -0
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -0
- package/dist/botlit/pages/BotDetailPage.js +872 -0
- package/dist/botlit/pages/BotDetailPage.js.map +1 -0
- package/dist/botlit/pages/BotWorkflowTab.js +229 -0
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -0
- package/dist/botlit/pages/BotsListPage.js +313 -0
- package/dist/botlit/pages/BotsListPage.js.map +1 -0
- package/dist/botlit/pages/BucketsPage.js +604 -0
- package/dist/botlit/pages/BucketsPage.js.map +1 -0
- package/dist/botlit/pages/ChannelDetailPage.js +955 -0
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -0
- package/dist/botlit/pages/ChannelRoutesPage.js +218 -0
- package/dist/botlit/pages/ChannelRoutesPage.js.map +1 -0
- package/dist/botlit/pages/ChannelsPage.js +304 -0
- package/dist/botlit/pages/ChannelsPage.js.map +1 -0
- package/dist/botlit/pages/ChatPage.js +247 -0
- package/dist/botlit/pages/ChatPage.js.map +1 -0
- package/dist/botlit/pages/DashboardPage.js +318 -0
- package/dist/botlit/pages/DashboardPage.js.map +1 -0
- package/dist/botlit/pages/ExecutionDetailPage.js +313 -0
- package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -0
- package/dist/botlit/pages/ExecutionsPage.js +294 -0
- package/dist/botlit/pages/ExecutionsPage.js.map +1 -0
- package/dist/botlit/pages/InstalledPackagesPage.js +619 -0
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -0
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +473 -0
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -0
- package/dist/botlit/pages/KnowledgeBasesPage.js +150 -0
- package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -0
- package/dist/botlit/pages/MCPServerDetailPage.js +550 -0
- package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -0
- package/dist/botlit/pages/MCPServersPage.js +321 -0
- package/dist/botlit/pages/MCPServersPage.js.map +1 -0
- package/dist/botlit/pages/PoliciesPage.js +224 -0
- package/dist/botlit/pages/PoliciesPage.js.map +1 -0
- package/dist/botlit/pages/PolicyDetailPage.js +861 -0
- package/dist/botlit/pages/PolicyDetailPage.js.map +1 -0
- package/dist/botlit/pages/PromptStudioPage.js +236 -0
- package/dist/botlit/pages/PromptStudioPage.js.map +1 -0
- package/dist/botlit/pages/PromptTemplateDetailPage.js +812 -0
- package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -0
- package/dist/botlit/pages/PromptTemplatesPage.js +269 -0
- package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -0
- package/dist/botlit/pages/RetrievalProfileDetailPage.js +559 -0
- package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -0
- package/dist/botlit/pages/RetrievalProfilesPage.js +219 -0
- package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -0
- package/dist/botlit/pages/SettingsPage.js +655 -0
- package/dist/botlit/pages/SettingsPage.js.map +1 -0
- package/dist/botlit/pages/SkillDetailPage.js +778 -0
- package/dist/botlit/pages/SkillDetailPage.js.map +1 -0
- package/dist/botlit/pages/SkillsPage.js +206 -0
- package/dist/botlit/pages/SkillsPage.js.map +1 -0
- package/dist/botlit/pages/StorePackageDetailPage.js +462 -0
- package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -0
- package/dist/botlit/pages/StorePage.js +315 -0
- package/dist/botlit/pages/StorePage.js.map +1 -0
- package/dist/botlit/providers/BotlitProvider.js +93 -0
- package/dist/botlit/providers/BotlitProvider.js.map +1 -0
- package/dist/botlit/store/botlitStore.js +101 -0
- package/dist/botlit/store/botlitStore.js.map +1 -0
- package/dist/botlit/utils/cn.js +10 -0
- package/dist/botlit/utils/cn.js.map +1 -0
- package/dist/botlit/utils/formatters.js +37 -0
- package/dist/botlit/utils/formatters.js.map +1 -0
- package/dist/botlit/utils/navigation.js +9 -0
- package/dist/botlit/utils/navigation.js.map +1 -0
- package/dist/botlit/utils/unions.js +14 -0
- package/dist/botlit/utils/unions.js.map +1 -0
- package/dist/generated/global-operations.js +66 -0
- package/dist/generated/global-operations.js.map +1 -0
- package/dist/generated/global-types.js +8 -0
- package/dist/generated/global-types.js.map +1 -0
- package/dist/generated/wspace-operations.js +1591 -0
- package/dist/generated/wspace-operations.js.map +1 -0
- package/dist/generated/wspace-types.js +12 -0
- package/dist/generated/wspace-types.js.map +1 -0
- package/dist/index.js +13 -0
- package/dist/utils/nativeBridge.js +2 -0
- package/package.json +133 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PolicyDetailPage.js","names":[],"sources":["../../../src/botlit/pages/PolicyDetailPage.tsx"],"sourcesContent":["/**\n * Policy Detail Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport { toast } from 'sonner';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { isNative, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\nimport {\n ArrowLeft,\n Shield,\n Settings,\n Save,\n AlertTriangle,\n Wrench,\n Database,\n FileText,\n DollarSign,\n Clock,\n Trash2,\n Edit,\n} from 'lucide-react';\nimport { PageLayout } from '../components/PageLayout';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { EmptyState } from '../components/EmptyState';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, Textarea, FormField } from '../components/Input';\nimport { StatusBadge, Badge } from '../components/Badge';\nimport { usePolicy, useCreatePolicy, useUpdatePolicy, useDeletePolicy } from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { toUnion } from '../utils/unions';\nimport type { PolicyType, Visibility, PolicyConfig } from '../types';\n\n/** Policy types the UI can render; the column itself is a free-form String. */\nconst POLICY_TYPES: PolicyType[] = [\n 'CONTENT',\n 'TOOL',\n 'DATA',\n 'RESPONSE',\n 'BUDGET',\n 'RATE_LIMIT',\n 'RETENTION',\n];\n\nconst VISIBILITIES: Visibility[] = ['PRIVATE', 'WORKSPACE', 'PUBLIC'];\n\ninterface PolicyDetailPageProps {\n isNew?: boolean;\n}\n\nconst PolicyTypeIcon: FC<{ type: PolicyType }> = ({ type }) => {\n const icons: Record<PolicyType, React.ReactElement> = {\n CONTENT: <AlertTriangle size={18} />,\n TOOL: <Wrench size={18} />,\n DATA: <Database size={18} />,\n RESPONSE: <FileText size={18} />,\n BUDGET: <DollarSign size={18} />,\n RATE_LIMIT: <Clock size={18} />,\n RETENTION: <Trash2 size={18} />,\n };\n return icons[type] || <Shield size={18} />;\n};\n\nconst PolicyTypeLabel: Record<PolicyType, string> = {\n CONTENT: 'Content Policy',\n TOOL: 'Tool Policy',\n DATA: 'Data Policy',\n RESPONSE: 'Response Policy',\n BUDGET: 'Budget Policy',\n RATE_LIMIT: 'Rate Limit Policy',\n RETENTION: 'Retention Policy',\n};\n\nexport const PolicyDetailPage: FC<PolicyDetailPageProps> = ({ isNew }) => {\n const { policyId } = useParams();\n const { navigateTo } = useBotlit();\n const { data: policy, loading } = usePolicy(isNew ? undefined : policyId);\n const { create: createPolicy, loading: createLoading } = useCreatePolicy();\n const { update: updatePolicy, loading: updateLoading } = useUpdatePolicy();\n const { remove: deletePolicy, loading: deleteLoading } = useDeletePolicy();\n\n const [isEditing, setIsEditing] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n\n const [formData, setFormData] = useState({\n name: '',\n description: '',\n type: 'CONTENT' as PolicyType,\n visibility: 'PRIVATE' as Visibility,\n });\n\n // Content Policy Config\n const [contentConfig, setContentConfig] = useState({\n jailbreakDetection: true,\n piiDetection: true,\n toxicityThreshold: 0.7,\n customPatterns: '',\n });\n\n // Tool Policy Config\n const [toolConfig, setToolConfig] = useState({\n allowedTools: '',\n deniedTools: '',\n maxCallsPerExecution: 10,\n timeoutSeconds: 30,\n });\n\n // Budget Policy Config\n const [budgetConfig, setBudgetConfig] = useState({\n maxTokensPerExecution: 10000,\n maxCostPerExecution: 1.0,\n allowEscalation: false,\n maxModelTier: 'gpt-4',\n });\n\n // Rate Limit Policy Config\n const [rateLimitConfig, setRateLimitConfig] = useState({\n requestsPerMinute: 60,\n requestsPerHour: 1000,\n tokensPerMinute: 100000,\n scope: 'app' as 'connector' | 'app' | 'agent' | 'user_group',\n });\n\n // Retention Policy Config\n const [retentionConfig, setRetentionConfig] = useState({\n executionDataRetentionDays: 90,\n payloadSnapshotsEnabled: true,\n });\n\n const handleCreate = async () => {\n if (!formData.name) return;\n\n let config: PolicyConfig | undefined;\n switch (formData.type) {\n case 'CONTENT':\n config = {\n jailbreakDetection: contentConfig.jailbreakDetection,\n piiDetection: contentConfig.piiDetection,\n toxicityThreshold: contentConfig.toxicityThreshold,\n customPatterns: contentConfig.customPatterns.split('\\n').filter(Boolean),\n };\n break;\n case 'TOOL':\n config = {\n allowedTools: toolConfig.allowedTools\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean),\n deniedTools: toolConfig.deniedTools\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean),\n limits: {\n maxCallsPerExecution: toolConfig.maxCallsPerExecution,\n timeoutSeconds: toolConfig.timeoutSeconds,\n },\n };\n break;\n case 'BUDGET':\n config = {\n maxTokensPerExecution: budgetConfig.maxTokensPerExecution,\n maxCostPerExecution: budgetConfig.maxCostPerExecution,\n modelEscalationConstraints: {\n allowEscalation: budgetConfig.allowEscalation,\n maxModelTier: budgetConfig.maxModelTier,\n },\n };\n break;\n case 'RATE_LIMIT':\n config = {\n limits: {\n requestsPerMinute: rateLimitConfig.requestsPerMinute,\n requestsPerHour: rateLimitConfig.requestsPerHour,\n tokensPerMinute: rateLimitConfig.tokensPerMinute,\n },\n scope: rateLimitConfig.scope,\n };\n break;\n case 'RETENTION':\n config = {\n executionDataRetentionDays: retentionConfig.executionDataRetentionDays,\n payloadSnapshotsEnabled: retentionConfig.payloadSnapshotsEnabled,\n };\n break;\n }\n\n try {\n await createPolicy({\n name: formData.name,\n description: formData.description,\n type: formData.type,\n visibility: formData.visibility,\n config: config as unknown as Record<string, unknown>,\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to create policy');\n return;\n }\n toast.success(`Policy \"${formData.name}\" created`);\n navigateTo('policies');\n };\n\n const handleUpdate = async () => {\n if (!policyId || !formData.name) return;\n try {\n await updatePolicy({\n policyId,\n input: {\n name: formData.name,\n description: formData.description,\n visibility: formData.visibility,\n },\n });\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update policy');\n return;\n }\n toast.success('Policy updated');\n setIsEditing(false);\n };\n\n const handleDelete = async () => {\n if (!policyId) return;\n try {\n await deletePolicy(policyId);\n if (isNative()) void nativeNotify('success');\n navigateTo('policies');\n } catch (err) {\n if (isNative()) void nativeNotify('error');\n throw err;\n }\n };\n\n const startEditing = () => {\n if (!policy) return;\n setFormData({\n name: policy.name,\n description: policy.description || '',\n type: toUnion(policy.type, POLICY_TYPES, 'CONTENT'),\n visibility: toUnion(policy.visibility, VISIBILITIES, 'PRIVATE'),\n });\n setIsEditing(true);\n };\n\n if (isNew) {\n return (\n <PageLayout\n title=\"Create Policy\"\n description=\"Define guardrails and constraints for your AI agents\"\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" onClick={() => navigateTo('policies')}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleCreate}\n isLoading={createLoading}\n disabled={!formData.name}\n >\n Create\n </Button>\n </div>\n }\n >\n <div className=\"max-w-2xl space-y-6\">\n <Card>\n <CardHeader>\n <CardTitle>Basic Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Policy Name\" required>\n <Input\n placeholder=\"e.g., Production Content Policy\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n\n <FormField label=\"Description\">\n <Textarea\n placeholder=\"What does this policy enforce?\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Policy Type\" required>\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={formData.type}\n onChange={(e) =>\n setFormData({ ...formData, type: e.target.value as PolicyType })\n }\n >\n <option value=\"CONTENT\">Content Policy</option>\n <option value=\"TOOL\">Tool Policy</option>\n <option value=\"DATA\">Data Policy</option>\n <option value=\"RESPONSE\">Response Policy</option>\n <option value=\"BUDGET\">Budget Policy</option>\n <option value=\"RATE_LIMIT\">Rate Limit Policy</option>\n <option value=\"RETENTION\">Retention Policy</option>\n </select>\n </FormField>\n\n <FormField label=\"Visibility\">\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={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n </div>\n </CardContent>\n </Card>\n\n {/* Policy-specific configuration */}\n {formData.type === 'CONTENT' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <AlertTriangle size={18} />\n Content Policy Configuration\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"jailbreak\"\n checked={contentConfig.jailbreakDetection}\n onChange={(e) =>\n setContentConfig({ ...contentConfig, jailbreakDetection: e.target.checked })\n }\n className=\"h-4 w-4\"\n />\n <label htmlFor=\"jailbreak\" className=\"text-sm\">\n Jailbreak Detection\n </label>\n </div>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"pii\"\n checked={contentConfig.piiDetection}\n onChange={(e) =>\n setContentConfig({ ...contentConfig, piiDetection: e.target.checked })\n }\n className=\"h-4 w-4\"\n />\n <label htmlFor=\"pii\" className=\"text-sm\">\n PII Detection\n </label>\n </div>\n </div>\n\n <FormField label=\"Toxicity Threshold\" description=\"0.0 to 1.0\">\n <Input\n type=\"number\"\n min={0}\n max={1}\n step={0.1}\n value={contentConfig.toxicityThreshold}\n onChange={(e) =>\n setContentConfig({\n ...contentConfig,\n toxicityThreshold: parseFloat(e.target.value),\n })\n }\n />\n </FormField>\n\n <FormField label=\"Custom Patterns\" description=\"One regex pattern per line\">\n <Textarea\n placeholder=\"Enter custom patterns...\"\n value={contentConfig.customPatterns}\n onChange={(e) =>\n setContentConfig({ ...contentConfig, customPatterns: e.target.value })\n }\n rows={3}\n />\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'TOOL' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wrench size={18} />\n Tool Policy Configuration\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Allowed Tools\" description=\"Comma-separated tool IDs\">\n <Input\n placeholder=\"e.g., search, read_file, web_browse\"\n value={toolConfig.allowedTools}\n onChange={(e) => setToolConfig({ ...toolConfig, allowedTools: e.target.value })}\n />\n </FormField>\n\n <FormField label=\"Denied Tools\" description=\"Comma-separated tool IDs\">\n <Input\n placeholder=\"e.g., delete_file, execute_code\"\n value={toolConfig.deniedTools}\n onChange={(e) => setToolConfig({ ...toolConfig, deniedTools: e.target.value })}\n />\n </FormField>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Max Calls Per Execution\">\n <Input\n type=\"number\"\n min={1}\n value={toolConfig.maxCallsPerExecution}\n onChange={(e) =>\n setToolConfig({\n ...toolConfig,\n maxCallsPerExecution: parseInt(e.target.value),\n })\n }\n />\n </FormField>\n <FormField label=\"Timeout (seconds)\">\n <Input\n type=\"number\"\n min={1}\n value={toolConfig.timeoutSeconds}\n onChange={(e) =>\n setToolConfig({\n ...toolConfig,\n timeoutSeconds: parseInt(e.target.value),\n })\n }\n />\n </FormField>\n </div>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'BUDGET' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <DollarSign size={18} />\n Budget Policy Configuration\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Max Tokens Per Execution\">\n <Input\n type=\"number\"\n min={100}\n value={budgetConfig.maxTokensPerExecution}\n onChange={(e) =>\n setBudgetConfig({\n ...budgetConfig,\n maxTokensPerExecution: parseInt(e.target.value),\n })\n }\n />\n </FormField>\n <FormField label=\"Max Cost Per Execution ($)\">\n <Input\n type=\"number\"\n min={0.01}\n step={0.01}\n value={budgetConfig.maxCostPerExecution}\n onChange={(e) =>\n setBudgetConfig({\n ...budgetConfig,\n maxCostPerExecution: parseFloat(e.target.value),\n })\n }\n />\n </FormField>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"escalation\"\n checked={budgetConfig.allowEscalation}\n onChange={(e) =>\n setBudgetConfig({ ...budgetConfig, allowEscalation: e.target.checked })\n }\n className=\"h-4 w-4\"\n />\n <label htmlFor=\"escalation\" className=\"text-sm\">\n Allow Model Escalation\n </label>\n </div>\n\n <FormField label=\"Max Model Tier\">\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={budgetConfig.maxModelTier}\n onChange={(e) =>\n setBudgetConfig({ ...budgetConfig, maxModelTier: e.target.value })\n }\n >\n <option value=\"gpt-3.5-turbo\">GPT-3.5 Turbo</option>\n <option value=\"gpt-4\">GPT-4</option>\n <option value=\"gpt-4-turbo\">GPT-4 Turbo</option>\n <option value=\"claude-3-sonnet\">Claude 3 Sonnet</option>\n <option value=\"claude-3-opus\">Claude 3 Opus</option>\n </select>\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RATE_LIMIT' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Clock size={18} />\n Rate Limit Configuration\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-3 gap-4\">\n <FormField label=\"Requests / Minute\">\n <Input\n type=\"number\"\n min={1}\n value={rateLimitConfig.requestsPerMinute}\n onChange={(e) =>\n setRateLimitConfig({\n ...rateLimitConfig,\n requestsPerMinute: parseInt(e.target.value),\n })\n }\n />\n </FormField>\n <FormField label=\"Requests / Hour\">\n <Input\n type=\"number\"\n min={1}\n value={rateLimitConfig.requestsPerHour}\n onChange={(e) =>\n setRateLimitConfig({\n ...rateLimitConfig,\n requestsPerHour: parseInt(e.target.value),\n })\n }\n />\n </FormField>\n <FormField label=\"Tokens / Minute\">\n <Input\n type=\"number\"\n min={1}\n value={rateLimitConfig.tokensPerMinute}\n onChange={(e) =>\n setRateLimitConfig({\n ...rateLimitConfig,\n tokensPerMinute: parseInt(e.target.value),\n })\n }\n />\n </FormField>\n </div>\n\n <FormField label=\"Scope\">\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={rateLimitConfig.scope}\n onChange={(e) =>\n setRateLimitConfig({\n ...rateLimitConfig,\n scope: e.target.value as 'connector' | 'app' | 'agent' | 'user_group',\n })\n }\n >\n <option value=\"connector\">Per Connector</option>\n <option value=\"app\">Per Bot</option>\n <option value=\"agent\">Per Agent</option>\n <option value=\"user_group\">Per User Group</option>\n </select>\n </FormField>\n </CardContent>\n </Card>\n )}\n\n {formData.type === 'RETENTION' && (\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Trash2 size={18} />\n Retention Policy Configuration\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Execution Data Retention (days)\">\n <Input\n type=\"number\"\n min={1}\n value={retentionConfig.executionDataRetentionDays}\n onChange={(e) =>\n setRetentionConfig({\n ...retentionConfig,\n executionDataRetentionDays: parseInt(e.target.value),\n })\n }\n />\n </FormField>\n\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"snapshots\"\n checked={retentionConfig.payloadSnapshotsEnabled}\n onChange={(e) =>\n setRetentionConfig({\n ...retentionConfig,\n payloadSnapshotsEnabled: e.target.checked,\n })\n }\n className=\"h-4 w-4\"\n />\n <label htmlFor=\"snapshots\" className=\"text-sm\">\n Enable Payload Snapshots\n </label>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n </PageLayout>\n );\n }\n\n if (loading) {\n return (\n <PageLayout title=\"Loading...\">\n <div className=\"h-96 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n </PageLayout>\n );\n }\n\n if (!policy) {\n return (\n <PageLayout title=\"Policy Not Found\">\n <EmptyState\n illustration=\"empty-generic\"\n title=\"Policy Not Found\"\n description=\"This policy doesn't exist.\"\n action={<Button onClick={() => navigateTo('policies')}>Back to Policies</Button>}\n />\n </PageLayout>\n );\n }\n\n const policyType = toUnion(policy.type, POLICY_TYPES, 'CONTENT');\n\n return (\n <PageLayout\n title={\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigateTo('policies')}>\n <ArrowLeft size={20} />\n </Button>\n <div className=\"p-2 rounded-lg bg-action-primary-bg/10\">\n <PolicyTypeIcon type={policyType} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span>{policy.name}</span>\n <StatusBadge status={policy.status} />\n </div>\n <p className=\"text-sm font-normal text-text-secondary\">{policy.description}</p>\n </div>\n </div>\n }\n actions={\n <div className=\"flex gap-2\">\n {isEditing ? (\n <>\n <Button variant=\"outline\" onClick={() => setIsEditing(false)}>\n Cancel\n </Button>\n <Button\n leftIcon={<Save size={16} />}\n onClick={handleUpdate}\n isLoading={updateLoading}\n disabled={!formData.name}\n >\n Save Changes\n </Button>\n </>\n ) : (\n <>\n <Button variant=\"outline\" leftIcon={<Edit size={16} />} onClick={startEditing}>\n Edit\n </Button>\n {showDeleteConfirm ? (\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowDeleteConfirm(false)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => {\n nativeImpact('medium');\n void handleDelete();\n }}\n isLoading={deleteLoading}\n >\n Confirm Delete\n </Button>\n </div>\n ) : (\n <Button\n variant=\"destructive\"\n leftIcon={<Trash2 size={16} />}\n onClick={() => setShowDeleteConfirm(true)}\n >\n Delete\n </Button>\n )}\n </>\n )}\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Shield size={18} />}>\n This is a single guardrail and its rules. Review and tune exactly what it enforces — what\n content to block, which tools are allowed, the spend or rate limits it applies — then\n attach it to the agents and bots that should obey it. Policies are how you keep agents\n safe, compliant and within budget.\n </PagePurpose>\n\n {/* Edit Form */}\n {isEditing && (\n <Card>\n <CardHeader>\n <CardTitle>Edit Policy</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label=\"Policy Name\" required>\n <Input\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n />\n </FormField>\n <FormField label=\"Description\">\n <Textarea\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n rows={3}\n />\n </FormField>\n <FormField label=\"Visibility\">\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={formData.visibility}\n onChange={(e) =>\n setFormData({ ...formData, visibility: e.target.value as Visibility })\n }\n >\n <option value=\"PRIVATE\">Private</option>\n <option value=\"WORKSPACE\">Workspace</option>\n <option value=\"PUBLIC\">Public</option>\n </select>\n </FormField>\n <p className=\"text-sm text-text-secondary\">\n Note: Policy type and configuration cannot be changed after creation.\n </p>\n </CardContent>\n </Card>\n )}\n\n {/* Overview */}\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card treatment=\"glass\" glow>\n <CardContent className=\"pt-6 text-center\">\n <div className=\"p-3 rounded-full bg-action-primary-bg/10 w-fit mx-auto mb-2\">\n <PolicyTypeIcon type={policyType} />\n </div>\n <p className=\"text-lg font-bold\">{PolicyTypeLabel[policyType]}</p>\n <p className=\"text-sm text-text-secondary\">Policy Type</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary capitalize\">\n {policy.visibility.toLowerCase()}\n </p>\n <p className=\"text-sm text-text-secondary\">Visibility</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-3xl font-bold text-text-primary\">{policy.revision}</p>\n <p className=\"text-sm text-text-secondary\">Revision</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-6 text-center\">\n <p className=\"text-lg font-bold text-text-primary\">\n {formatRelativeTime(policy.updatedAt)}\n </p>\n <p className=\"text-sm text-text-secondary\">Last Updated</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Configuration */}\n <Card>\n <CardHeader>\n <CardTitle>Configuration</CardTitle>\n <CardDescription>Current policy configuration</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"p-4 bg-bg-sunken rounded-lg font-mono text-sm overflow-auto\">\n <pre>{JSON.stringify(policy.config, null, 2)}</pre>\n </div>\n </CardContent>\n </Card>\n\n {/* Metadata */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Settings size={18} />\n Metadata\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-6 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Created</p>\n <p className=\"font-medium\">{formatRelativeTime(policy.createdAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Updated</p>\n <p className=\"font-medium\">{formatRelativeTime(policy.updatedAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Tags</p>\n <div className=\"flex gap-1\">\n {policy.tags.length > 0 ? (\n policy.tags.map((tag: string) => (\n <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n {tag}\n </Badge>\n ))\n ) : (\n <span className=\"text-text-secondary\">None</span>\n )}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { useBotlit as e } from "../providers/BotlitProvider.js";
|
|
2
|
+
import { formatRelativeTime as t } from "../utils/formatters.js";
|
|
3
|
+
import { PageLayout as n } from "../components/PageLayout.js";
|
|
4
|
+
import { Card as r, CardContent as i, CardDescription as a, CardHeader as o, CardTitle as s } from "../components/Card.js";
|
|
5
|
+
import { Button as c } from "../components/Button.js";
|
|
6
|
+
import { Badge as l } from "../components/Badge.js";
|
|
7
|
+
import { EmptyState as u } from "../components/EmptyState.js";
|
|
8
|
+
import { FormField as d, Input as f, Textarea as p } from "../components/Input.js";
|
|
9
|
+
import { ErrorState as m } from "../components/ErrorState.js";
|
|
10
|
+
import { promptTemplateVariables as h, usePromptTemplates as g, useRenderPromptTemplate as _ } from "../hooks/usePromptTemplates.js";
|
|
11
|
+
import "../hooks/index.js";
|
|
12
|
+
import { useEffect as v, useMemo as y, useState as b } from "react";
|
|
13
|
+
import { GlassCard as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
|
|
14
|
+
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
15
|
+
import { Play as T, Plus as E, Tag as D } from "lucide-react";
|
|
16
|
+
import { toast as O } from "sonner";
|
|
17
|
+
//#region src/botlit/pages/PromptStudioPage.tsx
|
|
18
|
+
function k(e) {
|
|
19
|
+
if (!e || typeof e != "object" || Array.isArray(e)) return null;
|
|
20
|
+
let t = e, n = typeof t.name == "string" ? t.name : void 0;
|
|
21
|
+
return n ? {
|
|
22
|
+
name: n,
|
|
23
|
+
type: typeof t.type == "string" ? t.type : "string",
|
|
24
|
+
description: typeof t.description == "string" ? t.description : void 0,
|
|
25
|
+
required: t.required === !0,
|
|
26
|
+
defaultValue: t.defaultValue
|
|
27
|
+
} : null;
|
|
28
|
+
}
|
|
29
|
+
function A(e) {
|
|
30
|
+
return e ? h(e).map(k).filter((e) => e !== null) : [];
|
|
31
|
+
}
|
|
32
|
+
var j = () => {
|
|
33
|
+
let { navigateTo: h } = e(), { data: k, loading: j, error: M, refetch: N } = g(), { render: P, loading: F } = _(), [I, L] = b(null), [R, z] = b({}), [B, V] = b("");
|
|
34
|
+
v(() => {
|
|
35
|
+
!I && k.length > 0 && L(k[0].id);
|
|
36
|
+
}, [k, I]);
|
|
37
|
+
let H = y(() => k.find((e) => e.id === I), [k, I]), U = y(() => A(H), [H]), W = async () => {
|
|
38
|
+
if (H) try {
|
|
39
|
+
V(await P({
|
|
40
|
+
templateId: H.id,
|
|
41
|
+
variables: R
|
|
42
|
+
}));
|
|
43
|
+
} catch (e) {
|
|
44
|
+
O.error(e instanceof Error ? e.message : "Failed to render prompt");
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
return /* @__PURE__ */ C(n, {
|
|
48
|
+
title: "Prompt Studio",
|
|
49
|
+
description: "Create, test, and manage prompts for your AI agents",
|
|
50
|
+
actions: /* @__PURE__ */ C(c, {
|
|
51
|
+
leftIcon: /* @__PURE__ */ C(E, { size: 16 }),
|
|
52
|
+
onClick: () => h("prompt-templates/new"),
|
|
53
|
+
children: "New Prompt"
|
|
54
|
+
}),
|
|
55
|
+
children: /* @__PURE__ */ w("div", {
|
|
56
|
+
className: "space-y-6",
|
|
57
|
+
children: [/* @__PURE__ */ C(S, {
|
|
58
|
+
icon: /* @__PURE__ */ C(T, { size: 18 }),
|
|
59
|
+
children: "Prompt Studio is your interactive workbench for writing and testing prompts before they go live. Pick a prompt, edit its text and variables on the left, then fill in sample values and hit Run Test to preview exactly what the agent will receive — so you can iterate on wording and catch mistakes here instead of in production."
|
|
60
|
+
}), /* @__PURE__ */ w("div", {
|
|
61
|
+
className: "grid grid-cols-12 gap-6",
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ C("div", {
|
|
64
|
+
className: "col-span-3",
|
|
65
|
+
children: /* @__PURE__ */ w(r, { children: [/* @__PURE__ */ C(o, { children: /* @__PURE__ */ C(s, {
|
|
66
|
+
className: "text-base",
|
|
67
|
+
children: "Prompts"
|
|
68
|
+
}) }), /* @__PURE__ */ C(i, {
|
|
69
|
+
className: "p-0",
|
|
70
|
+
children: j ? /* @__PURE__ */ C("div", {
|
|
71
|
+
className: "space-y-2 p-4",
|
|
72
|
+
children: [
|
|
73
|
+
1,
|
|
74
|
+
2,
|
|
75
|
+
3
|
|
76
|
+
].map((e) => /* @__PURE__ */ C("div", { className: "h-14 bg-bg-sunken motion-safe:animate-vc-shimmer rounded" }, e))
|
|
77
|
+
}) : M ? /* @__PURE__ */ C(m, {
|
|
78
|
+
resource: "prompt templates",
|
|
79
|
+
error: M,
|
|
80
|
+
onRetry: () => void N(),
|
|
81
|
+
className: "m-4"
|
|
82
|
+
}) : k.length === 0 ? /* @__PURE__ */ C("p", {
|
|
83
|
+
className: "p-4 text-sm text-text-secondary",
|
|
84
|
+
children: "No prompt templates yet. Create one to start iterating."
|
|
85
|
+
}) : /* @__PURE__ */ C("div", {
|
|
86
|
+
className: "divide-y divide-border-subtle",
|
|
87
|
+
children: k.map((e) => /* @__PURE__ */ w("button", {
|
|
88
|
+
type: "button",
|
|
89
|
+
className: `w-full text-left p-4 hover:bg-accent transition-colors ${H?.id === e.id ? "bg-accent" : ""}`,
|
|
90
|
+
onClick: () => {
|
|
91
|
+
L(e.id), z({}), V("");
|
|
92
|
+
},
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ C("p", {
|
|
95
|
+
className: "font-medium truncate",
|
|
96
|
+
children: e.name
|
|
97
|
+
}),
|
|
98
|
+
/* @__PURE__ */ w("p", {
|
|
99
|
+
className: "text-xs text-text-secondary mt-1 truncate",
|
|
100
|
+
children: ["v", e.version]
|
|
101
|
+
}),
|
|
102
|
+
/* @__PURE__ */ w("div", {
|
|
103
|
+
className: "flex items-center gap-2 mt-2",
|
|
104
|
+
children: [e.visibility === "PUBLIC" && /* @__PURE__ */ C(l, {
|
|
105
|
+
variant: "secondary",
|
|
106
|
+
className: "text-[10px]",
|
|
107
|
+
children: "Public"
|
|
108
|
+
}), /* @__PURE__ */ w("span", {
|
|
109
|
+
className: "text-xs text-text-secondary",
|
|
110
|
+
children: [A(e).length, " vars"]
|
|
111
|
+
})]
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
}, e.id))
|
|
115
|
+
})
|
|
116
|
+
})] })
|
|
117
|
+
}),
|
|
118
|
+
/* @__PURE__ */ C("div", {
|
|
119
|
+
className: "col-span-6",
|
|
120
|
+
children: H ? /* @__PURE__ */ w(x, {
|
|
121
|
+
treatment: "glass",
|
|
122
|
+
glow: !0,
|
|
123
|
+
className: "overflow-hidden",
|
|
124
|
+
children: [/* @__PURE__ */ w(o, {
|
|
125
|
+
className: "flex flex-row items-center justify-between",
|
|
126
|
+
children: [/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C(s, { children: H.name }), /* @__PURE__ */ C(a, { children: H.description })] }), /* @__PURE__ */ C(c, {
|
|
127
|
+
size: "sm",
|
|
128
|
+
variant: "outline",
|
|
129
|
+
onClick: () => h(`prompt-templates/${H.id}`),
|
|
130
|
+
children: "Open template"
|
|
131
|
+
})]
|
|
132
|
+
}), /* @__PURE__ */ w(i, {
|
|
133
|
+
className: "space-y-4",
|
|
134
|
+
children: [
|
|
135
|
+
/* @__PURE__ */ w("div", {
|
|
136
|
+
className: "flex items-center gap-2",
|
|
137
|
+
children: [/* @__PURE__ */ C(D, {
|
|
138
|
+
size: 14,
|
|
139
|
+
className: "text-text-secondary"
|
|
140
|
+
}), H.tags.map((e) => /* @__PURE__ */ C(l, {
|
|
141
|
+
variant: "secondary",
|
|
142
|
+
children: e
|
|
143
|
+
}, e))]
|
|
144
|
+
}),
|
|
145
|
+
/* @__PURE__ */ C(d, {
|
|
146
|
+
label: "Prompt Content",
|
|
147
|
+
children: /* @__PURE__ */ C(p, {
|
|
148
|
+
value: H.templateText,
|
|
149
|
+
rows: 15,
|
|
150
|
+
readOnly: !0,
|
|
151
|
+
className: "font-mono text-sm"
|
|
152
|
+
})
|
|
153
|
+
}),
|
|
154
|
+
U.length > 0 && /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
|
|
155
|
+
className: "text-sm font-medium mb-2",
|
|
156
|
+
children: "Variables"
|
|
157
|
+
}), /* @__PURE__ */ C("div", {
|
|
158
|
+
className: "space-y-2",
|
|
159
|
+
children: U.map((e) => /* @__PURE__ */ w("div", {
|
|
160
|
+
className: "flex items-center gap-4 p-3 bg-bg-sunken rounded-lg",
|
|
161
|
+
children: [/* @__PURE__ */ w("div", {
|
|
162
|
+
className: "flex-1",
|
|
163
|
+
children: [/* @__PURE__ */ w("p", {
|
|
164
|
+
className: "font-medium text-sm",
|
|
165
|
+
children: [`{{${e.name}}}`, e.required && /* @__PURE__ */ C("span", {
|
|
166
|
+
className: "text-status-error-text ml-1",
|
|
167
|
+
children: "*"
|
|
168
|
+
})]
|
|
169
|
+
}), e.description && /* @__PURE__ */ C("p", {
|
|
170
|
+
className: "text-xs text-text-secondary",
|
|
171
|
+
children: e.description
|
|
172
|
+
})]
|
|
173
|
+
}), /* @__PURE__ */ C(l, {
|
|
174
|
+
variant: "outline",
|
|
175
|
+
className: "capitalize",
|
|
176
|
+
children: e.type
|
|
177
|
+
})]
|
|
178
|
+
}, e.name))
|
|
179
|
+
})] }),
|
|
180
|
+
/* @__PURE__ */ w("div", {
|
|
181
|
+
className: "pt-4 text-xs text-text-secondary",
|
|
182
|
+
children: ["Updated ", t(H.updatedAt)]
|
|
183
|
+
})
|
|
184
|
+
]
|
|
185
|
+
})]
|
|
186
|
+
}) : /* @__PURE__ */ C(u, {
|
|
187
|
+
illustration: "onboarding",
|
|
188
|
+
title: "Select a prompt",
|
|
189
|
+
description: "Choose a prompt from the list to view and edit"
|
|
190
|
+
})
|
|
191
|
+
}),
|
|
192
|
+
/* @__PURE__ */ C("div", {
|
|
193
|
+
className: "col-span-3",
|
|
194
|
+
children: /* @__PURE__ */ w(r, { children: [/* @__PURE__ */ C(o, { children: /* @__PURE__ */ w(s, {
|
|
195
|
+
className: "text-base flex items-center gap-2",
|
|
196
|
+
children: [/* @__PURE__ */ C(T, { size: 16 }), "Test Prompt"]
|
|
197
|
+
}) }), /* @__PURE__ */ w(i, {
|
|
198
|
+
className: "space-y-4",
|
|
199
|
+
children: [
|
|
200
|
+
U.map((e) => /* @__PURE__ */ C(d, {
|
|
201
|
+
label: e.name,
|
|
202
|
+
children: /* @__PURE__ */ C(f, {
|
|
203
|
+
placeholder: e.description || `Enter ${e.name}`,
|
|
204
|
+
value: R[e.name] || "",
|
|
205
|
+
onChange: (t) => z({
|
|
206
|
+
...R,
|
|
207
|
+
[e.name]: t.target.value
|
|
208
|
+
})
|
|
209
|
+
})
|
|
210
|
+
}, e.name)),
|
|
211
|
+
/* @__PURE__ */ C(c, {
|
|
212
|
+
className: "w-full",
|
|
213
|
+
onClick: () => void W(),
|
|
214
|
+
isLoading: F,
|
|
215
|
+
disabled: !H,
|
|
216
|
+
children: "Run Test"
|
|
217
|
+
}),
|
|
218
|
+
B && /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
|
|
219
|
+
className: "text-sm font-medium mb-2",
|
|
220
|
+
children: "Output"
|
|
221
|
+
}), /* @__PURE__ */ C("div", {
|
|
222
|
+
className: "p-3 bg-bg-sunken rounded-lg text-sm whitespace-pre-wrap font-mono max-h-64 overflow-auto",
|
|
223
|
+
children: B
|
|
224
|
+
})] })
|
|
225
|
+
]
|
|
226
|
+
})] })
|
|
227
|
+
})
|
|
228
|
+
]
|
|
229
|
+
})]
|
|
230
|
+
})
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
//#endregion
|
|
234
|
+
export { j as PromptStudioPage };
|
|
235
|
+
|
|
236
|
+
//# sourceMappingURL=PromptStudioPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptStudioPage.js","names":[],"sources":["../../../src/botlit/pages/PromptStudioPage.tsx"],"sourcesContent":["/**\n * Prompt Studio Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Plus, Play, Tag } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { PagePurpose, 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 { Input, Textarea, FormField } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n usePromptTemplates,\n useRenderPromptTemplate,\n promptTemplateVariables,\n type PromptTemplateRecord,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { PromptVariable } from '../types';\n\n/** Normalises one entry of a template's free-form `variables` JSON. */\nfunction toPromptVariable(value: unknown): PromptVariable | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n const name = typeof record.name === 'string' ? record.name : undefined;\n if (!name) return null;\n const type = typeof record.type === 'string' ? record.type : 'string';\n return {\n name,\n type: type as PromptVariable['type'],\n description: typeof record.description === 'string' ? record.description : undefined,\n required: record.required === true,\n defaultValue: record.defaultValue,\n };\n}\n\nfunction templateVariables(template: PromptTemplateRecord | undefined): PromptVariable[] {\n if (!template) return [];\n return promptTemplateVariables(template)\n .map(toPromptVariable)\n .filter((variable): variable is PromptVariable => variable !== null);\n}\n\nexport const PromptStudioPage: FC = () => {\n const { navigateTo } = useBotlit();\n const { data: templates, loading, error, refetch } = usePromptTemplates();\n const { render, loading: isRunning } = useRenderPromptTemplate();\n\n const [selectedPromptId, setSelectedPromptId] = useState<string | null>(null);\n const [testVariables, setTestVariables] = useState<Record<string, string>>({});\n const [testOutput, setTestOutput] = useState('');\n\n // Select the first template once the list arrives.\n useEffect(() => {\n if (!selectedPromptId && templates.length > 0) {\n setSelectedPromptId(templates[0].id);\n }\n }, [templates, selectedPromptId]);\n\n const selectedPrompt = useMemo(\n () => templates.find((template) => template.id === selectedPromptId),\n [templates, selectedPromptId]\n );\n\n const selectedVariables = useMemo(() => templateVariables(selectedPrompt), [selectedPrompt]);\n\n const handleTest = async () => {\n if (!selectedPrompt) return;\n try {\n // Rendered by wspace-botlit-svc so the preview matches what the agent\n // actually receives — never a client-side string substitution.\n const output = await render({\n templateId: selectedPrompt.id,\n variables: testVariables,\n });\n setTestOutput(output);\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to render prompt');\n }\n };\n\n return (\n <PageLayout\n title=\"Prompt Studio\"\n description=\"Create, test, and manage prompts for your AI agents\"\n actions={\n <Button leftIcon={<Plus size={16} />} onClick={() => navigateTo('prompt-templates/new')}>\n New Prompt\n </Button>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Play size={18} />}>\n Prompt Studio is your interactive workbench for writing and testing prompts before they go\n live. Pick a prompt, edit its text and variables on the left, then fill in sample values\n and hit Run Test to preview exactly what the agent will receive — so you can iterate on\n wording and catch mistakes here instead of in production.\n </PagePurpose>\n\n <div className=\"grid grid-cols-12 gap-6\">\n {/* Prompt List */}\n <div className=\"col-span-3\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Prompts</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {loading ? (\n <div className=\"space-y-2 p-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-14 bg-bg-sunken motion-safe:animate-vc-shimmer rounded\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState\n resource=\"prompt templates\"\n error={error}\n onRetry={() => void refetch()}\n className=\"m-4\"\n />\n ) : templates.length === 0 ? (\n <p className=\"p-4 text-sm text-text-secondary\">\n No prompt templates yet. Create one to start iterating.\n </p>\n ) : (\n <div className=\"divide-y divide-border-subtle\">\n {templates.map((prompt: PromptTemplateRecord) => (\n <button\n key={prompt.id}\n type=\"button\"\n className={`w-full text-left p-4 hover:bg-accent transition-colors ${\n selectedPrompt?.id === prompt.id ? 'bg-accent' : ''\n }`}\n onClick={() => {\n setSelectedPromptId(prompt.id);\n setTestVariables({});\n setTestOutput('');\n }}\n >\n <p className=\"font-medium truncate\">{prompt.name}</p>\n <p className=\"text-xs text-text-secondary mt-1 truncate\">\n v{prompt.version}\n </p>\n <div className=\"flex items-center gap-2 mt-2\">\n {prompt.visibility === 'PUBLIC' && (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n Public\n </Badge>\n )}\n <span className=\"text-xs text-text-secondary\">\n {templateVariables(prompt).length} vars\n </span>\n </div>\n </button>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n\n {/* Editor */}\n <div className=\"col-span-6\">\n {selectedPrompt ? (\n <GlassCard treatment=\"glass\" glow className=\"overflow-hidden\">\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>{selectedPrompt.name}</CardTitle>\n <CardDescription>{selectedPrompt.description}</CardDescription>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => navigateTo(`prompt-templates/${selectedPrompt.id}`)}\n >\n Open template\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {/* Tags */}\n <div className=\"flex items-center gap-2\">\n <Tag size={14} className=\"text-text-secondary\" />\n {selectedPrompt.tags.map((tag) => (\n <Badge key={tag} variant=\"secondary\">\n {tag}\n </Badge>\n ))}\n </div>\n\n {/* Content */}\n <FormField label=\"Prompt Content\">\n <Textarea\n value={selectedPrompt.templateText}\n rows={15}\n readOnly\n className=\"font-mono text-sm\"\n />\n </FormField>\n\n {/* Variables */}\n {selectedVariables.length > 0 && (\n <div>\n <p className=\"text-sm font-medium mb-2\">Variables</p>\n <div className=\"space-y-2\">\n {selectedVariables.map((variable: PromptVariable) => (\n <div\n key={variable.name}\n className=\"flex items-center gap-4 p-3 bg-bg-sunken rounded-lg\"\n >\n <div className=\"flex-1\">\n <p className=\"font-medium text-sm\">\n {`{{${variable.name}}}`}\n {variable.required && (\n <span className=\"text-status-error-text ml-1\">*</span>\n )}\n </p>\n {variable.description && (\n <p className=\"text-xs text-text-secondary\">\n {variable.description}\n </p>\n )}\n </div>\n <Badge variant=\"outline\" className=\"capitalize\">\n {variable.type}\n </Badge>\n </div>\n ))}\n </div>\n </div>\n )}\n\n <div className=\"pt-4 text-xs text-text-secondary\">\n Updated {formatRelativeTime(selectedPrompt.updatedAt)}\n </div>\n </CardContent>\n </GlassCard>\n ) : (\n <EmptyState\n illustration=\"onboarding\"\n title=\"Select a prompt\"\n description=\"Choose a prompt from the list to view and edit\"\n />\n )}\n </div>\n\n {/* Test Panel */}\n <div className=\"col-span-3\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Play size={16} />\n Test Prompt\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {selectedVariables.map((variable: PromptVariable) => (\n <FormField key={variable.name} label={variable.name}>\n <Input\n placeholder={variable.description || `Enter ${variable.name}`}\n value={testVariables[variable.name] || ''}\n onChange={(e) =>\n setTestVariables({ ...testVariables, [variable.name]: e.target.value })\n }\n />\n </FormField>\n ))}\n\n <Button\n className=\"w-full\"\n onClick={() => void handleTest()}\n isLoading={isRunning}\n disabled={!selectedPrompt}\n >\n Run Test\n </Button>\n\n {testOutput && (\n <div>\n <p className=\"text-sm font-medium mb-2\">Output</p>\n <div className=\"p-3 bg-bg-sunken rounded-lg text-sm whitespace-pre-wrap font-mono max-h-64 overflow-auto\">\n {testOutput}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|