@contractspec/example.agent-console 0.0.0-canary-20260113170453
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/.turbo/turbo-build$colon$bundle.log +280 -0
- package/.turbo/turbo-build.log +281 -0
- package/CHANGELOG.md +368 -0
- package/LICENSE +21 -0
- package/README.md +86 -0
- package/dist/agent/agent.entity.d.ts +55 -0
- package/dist/agent/agent.entity.d.ts.map +1 -0
- package/dist/agent/agent.entity.js +136 -0
- package/dist/agent/agent.entity.js.map +1 -0
- package/dist/agent/agent.enum.d.ts +18 -0
- package/dist/agent/agent.enum.d.ts.map +1 -0
- package/dist/agent/agent.enum.js +34 -0
- package/dist/agent/agent.enum.js.map +1 -0
- package/dist/agent/agent.event.d.ts +128 -0
- package/dist/agent/agent.event.d.ts.map +1 -0
- package/dist/agent/agent.event.js +210 -0
- package/dist/agent/agent.event.js.map +1 -0
- package/dist/agent/agent.handler.d.ts +100 -0
- package/dist/agent/agent.handler.d.ts.map +1 -0
- package/dist/agent/agent.handler.js +84 -0
- package/dist/agent/agent.handler.js.map +1 -0
- package/dist/agent/agent.operation.d.ts +471 -0
- package/dist/agent/agent.operation.d.ts.map +1 -0
- package/dist/agent/agent.operation.js +486 -0
- package/dist/agent/agent.operation.js.map +1 -0
- package/dist/agent/agent.presentation.d.ts +18 -0
- package/dist/agent/agent.presentation.d.ts.map +1 -0
- package/dist/agent/agent.presentation.js +89 -0
- package/dist/agent/agent.presentation.js.map +1 -0
- package/dist/agent/agent.schema.d.ts +401 -0
- package/dist/agent/agent.schema.d.ts.map +1 -0
- package/dist/agent/agent.schema.js +406 -0
- package/dist/agent/agent.schema.js.map +1 -0
- package/dist/agent/agent.test-spec.d.ts +8 -0
- package/dist/agent/agent.test-spec.d.ts.map +1 -0
- package/dist/agent/agent.test-spec.js +65 -0
- package/dist/agent/agent.test-spec.js.map +1 -0
- package/dist/agent/index.d.ts +8 -0
- package/dist/agent/index.js +9 -0
- package/dist/agent.capability.d.ts +7 -0
- package/dist/agent.capability.d.ts.map +1 -0
- package/dist/agent.capability.js +20 -0
- package/dist/agent.capability.js.map +1 -0
- package/dist/agent.feature.d.ts +12 -0
- package/dist/agent.feature.d.ts.map +1 -0
- package/dist/agent.feature.js +305 -0
- package/dist/agent.feature.js.map +1 -0
- package/dist/docs/agent-console.docblock.d.ts +1 -0
- package/dist/docs/agent-console.docblock.js +113 -0
- package/dist/docs/agent-console.docblock.js.map +1 -0
- package/dist/docs/index.d.ts +1 -0
- package/dist/docs/index.js +1 -0
- package/dist/example.d.ts +7 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/example.js +58 -0
- package/dist/example.js.map +1 -0
- package/dist/handlers/agent.handlers.d.ts +135 -0
- package/dist/handlers/agent.handlers.d.ts.map +1 -0
- package/dist/handlers/agent.handlers.js +263 -0
- package/dist/handlers/agent.handlers.js.map +1 -0
- package/dist/handlers/index.d.ts +5 -0
- package/dist/handlers/index.js +6 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.js +50 -0
- package/dist/presentations/index.d.ts +4 -0
- package/dist/presentations/index.js +5 -0
- package/dist/run/index.d.ts +8 -0
- package/dist/run/index.js +9 -0
- package/dist/run/run.entity.d.ts +82 -0
- package/dist/run/run.entity.d.ts.map +1 -0
- package/dist/run/run.entity.js +205 -0
- package/dist/run/run.entity.js.map +1 -0
- package/dist/run/run.enum.d.ts +22 -0
- package/dist/run/run.enum.d.ts.map +1 -0
- package/dist/run/run.enum.js +45 -0
- package/dist/run/run.enum.js.map +1 -0
- package/dist/run/run.event.d.ts +290 -0
- package/dist/run/run.event.d.ts.map +1 -0
- package/dist/run/run.event.js +434 -0
- package/dist/run/run.event.js.map +1 -0
- package/dist/run/run.handler.d.ts +203 -0
- package/dist/run/run.handler.d.ts.map +1 -0
- package/dist/run/run.handler.js +83 -0
- package/dist/run/run.handler.js.map +1 -0
- package/dist/run/run.operation.d.ts +720 -0
- package/dist/run/run.operation.d.ts.map +1 -0
- package/dist/run/run.operation.js +626 -0
- package/dist/run/run.operation.js.map +1 -0
- package/dist/run/run.presentation.d.ts +14 -0
- package/dist/run/run.presentation.d.ts.map +1 -0
- package/dist/run/run.presentation.js +65 -0
- package/dist/run/run.presentation.js.map +1 -0
- package/dist/run/run.schema.d.ts +416 -0
- package/dist/run/run.schema.d.ts.map +1 -0
- package/dist/run/run.schema.js +338 -0
- package/dist/run/run.schema.js.map +1 -0
- package/dist/run/run.test-spec.d.ts +8 -0
- package/dist/run/run.test-spec.d.ts.map +1 -0
- package/dist/run/run.test-spec.js +65 -0
- package/dist/run/run.test-spec.js.map +1 -0
- package/dist/seeders/index.d.ts +10 -0
- package/dist/seeders/index.d.ts.map +1 -0
- package/dist/seeders/index.js +20 -0
- package/dist/seeders/index.js.map +1 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared/index.js +5 -0
- package/dist/shared/mock-agents.d.ts +88 -0
- package/dist/shared/mock-agents.d.ts.map +1 -0
- package/dist/shared/mock-agents.js +94 -0
- package/dist/shared/mock-agents.js.map +1 -0
- package/dist/shared/mock-runs.d.ts +120 -0
- package/dist/shared/mock-runs.d.ts.map +1 -0
- package/dist/shared/mock-runs.js +118 -0
- package/dist/shared/mock-runs.js.map +1 -0
- package/dist/shared/mock-tools.d.ts +244 -0
- package/dist/shared/mock-tools.d.ts.map +1 -0
- package/dist/shared/mock-tools.js +181 -0
- package/dist/shared/mock-tools.js.map +1 -0
- package/dist/shared/overlay-types.d.ts +34 -0
- package/dist/shared/overlay-types.d.ts.map +1 -0
- package/dist/shared/overlay-types.js +0 -0
- package/dist/tool/index.d.ts +8 -0
- package/dist/tool/index.js +9 -0
- package/dist/tool/tool.entity.d.ts +42 -0
- package/dist/tool/tool.entity.d.ts.map +1 -0
- package/dist/tool/tool.entity.js +105 -0
- package/dist/tool/tool.entity.js.map +1 -0
- package/dist/tool/tool.enum.d.ts +18 -0
- package/dist/tool/tool.enum.d.ts.map +1 -0
- package/dist/tool/tool.enum.js +35 -0
- package/dist/tool/tool.enum.js.map +1 -0
- package/dist/tool/tool.event.d.ts +103 -0
- package/dist/tool/tool.event.d.ts.map +1 -0
- package/dist/tool/tool.event.js +159 -0
- package/dist/tool/tool.event.js.map +1 -0
- package/dist/tool/tool.handler.d.ts +315 -0
- package/dist/tool/tool.handler.d.ts.map +1 -0
- package/dist/tool/tool.handler.js +87 -0
- package/dist/tool/tool.handler.js.map +1 -0
- package/dist/tool/tool.operation.d.ts +411 -0
- package/dist/tool/tool.operation.d.ts.map +1 -0
- package/dist/tool/tool.operation.js +406 -0
- package/dist/tool/tool.operation.js.map +1 -0
- package/dist/tool/tool.presentation.d.ts +14 -0
- package/dist/tool/tool.presentation.d.ts.map +1 -0
- package/dist/tool/tool.presentation.js +65 -0
- package/dist/tool/tool.presentation.js.map +1 -0
- package/dist/tool/tool.schema.d.ts +218 -0
- package/dist/tool/tool.schema.d.ts.map +1 -0
- package/dist/tool/tool.schema.js +236 -0
- package/dist/tool/tool.schema.js.map +1 -0
- package/dist/tool/tool.test-spec.d.ts +8 -0
- package/dist/tool/tool.test-spec.d.ts.map +1 -0
- package/dist/tool/tool.test-spec.js +65 -0
- package/dist/tool/tool.test-spec.js.map +1 -0
- package/dist/ui/AgentDashboard.d.ts +7 -0
- package/dist/ui/AgentDashboard.d.ts.map +1 -0
- package/dist/ui/AgentDashboard.js +420 -0
- package/dist/ui/AgentDashboard.js.map +1 -0
- package/dist/ui/AgentRunList.d.ts +2 -0
- package/dist/ui/AgentRunList.js +5 -0
- package/dist/ui/AgentToolRegistry.d.ts +2 -0
- package/dist/ui/AgentToolRegistry.js +5 -0
- package/dist/ui/hooks/index.d.ts +6 -0
- package/dist/ui/hooks/index.js +8 -0
- package/dist/ui/hooks/useAgentList.d.ts +28 -0
- package/dist/ui/hooks/useAgentList.d.ts.map +1 -0
- package/dist/ui/hooks/useAgentList.js +66 -0
- package/dist/ui/hooks/useAgentList.js.map +1 -0
- package/dist/ui/hooks/useAgentMutations.d.ts +29 -0
- package/dist/ui/hooks/useAgentMutations.d.ts.map +1 -0
- package/dist/ui/hooks/useAgentMutations.js +124 -0
- package/dist/ui/hooks/useAgentMutations.js.map +1 -0
- package/dist/ui/hooks/useRunList.d.ts +24 -0
- package/dist/ui/hooks/useRunList.d.ts.map +1 -0
- package/dist/ui/hooks/useRunList.js +66 -0
- package/dist/ui/hooks/useRunList.js.map +1 -0
- package/dist/ui/hooks/useToolList.d.ts +40 -0
- package/dist/ui/hooks/useToolList.d.ts.map +1 -0
- package/dist/ui/hooks/useToolList.js +96 -0
- package/dist/ui/hooks/useToolList.js.map +1 -0
- package/dist/ui/index.d.ts +24 -0
- package/dist/ui/index.js +24 -0
- package/dist/ui/modals/AgentActionsModal.d.ts +27 -0
- package/dist/ui/modals/AgentActionsModal.d.ts.map +1 -0
- package/dist/ui/modals/AgentActionsModal.js +262 -0
- package/dist/ui/modals/AgentActionsModal.js.map +1 -0
- package/dist/ui/modals/CreateAgentModal.d.ts +25 -0
- package/dist/ui/modals/CreateAgentModal.d.ts.map +1 -0
- package/dist/ui/modals/CreateAgentModal.js +214 -0
- package/dist/ui/modals/CreateAgentModal.js.map +1 -0
- package/dist/ui/modals/index.d.ts +3 -0
- package/dist/ui/modals/index.js +4 -0
- package/dist/ui/overlays/demo-overlays.d.ts +19 -0
- package/dist/ui/overlays/demo-overlays.d.ts.map +1 -0
- package/dist/ui/overlays/demo-overlays.js +73 -0
- package/dist/ui/overlays/demo-overlays.js.map +1 -0
- package/dist/ui/overlays/index.d.ts +2 -0
- package/dist/ui/overlays/index.js +3 -0
- package/dist/ui/renderers/agent-list.markdown.d.ts +15 -0
- package/dist/ui/renderers/agent-list.markdown.d.ts.map +1 -0
- package/dist/ui/renderers/agent-list.markdown.js +51 -0
- package/dist/ui/renderers/agent-list.markdown.js.map +1 -0
- package/dist/ui/renderers/agent-list.renderer.d.ts +11 -0
- package/dist/ui/renderers/agent-list.renderer.d.ts.map +1 -0
- package/dist/ui/renderers/agent-list.renderer.js +19 -0
- package/dist/ui/renderers/agent-list.renderer.js.map +1 -0
- package/dist/ui/renderers/dashboard.markdown.d.ts +15 -0
- package/dist/ui/renderers/dashboard.markdown.d.ts.map +1 -0
- package/dist/ui/renderers/dashboard.markdown.js +100 -0
- package/dist/ui/renderers/dashboard.markdown.js.map +1 -0
- package/dist/ui/renderers/index.d.ts +6 -0
- package/dist/ui/renderers/index.js +7 -0
- package/dist/ui/renderers/run-list.markdown.d.ts +15 -0
- package/dist/ui/renderers/run-list.markdown.d.ts.map +1 -0
- package/dist/ui/renderers/run-list.markdown.js +44 -0
- package/dist/ui/renderers/run-list.markdown.js.map +1 -0
- package/dist/ui/renderers/tool-registry.markdown.d.ts +15 -0
- package/dist/ui/renderers/tool-registry.markdown.d.ts.map +1 -0
- package/dist/ui/renderers/tool-registry.markdown.js +55 -0
- package/dist/ui/renderers/tool-registry.markdown.js.map +1 -0
- package/dist/ui/views/AgentListView.d.ts +7 -0
- package/dist/ui/views/AgentListView.d.ts.map +1 -0
- package/dist/ui/views/AgentListView.js +93 -0
- package/dist/ui/views/AgentListView.js.map +1 -0
- package/dist/ui/views/RunListView.d.ts +14 -0
- package/dist/ui/views/RunListView.d.ts.map +1 -0
- package/dist/ui/views/RunListView.js +165 -0
- package/dist/ui/views/RunListView.js.map +1 -0
- package/dist/ui/views/ToolRegistryView.d.ts +14 -0
- package/dist/ui/views/ToolRegistryView.d.ts.map +1 -0
- package/dist/ui/views/ToolRegistryView.js +97 -0
- package/dist/ui/views/ToolRegistryView.js.map +1 -0
- package/dist/ui/views/index.d.ts +4 -0
- package/dist/ui/views/index.js +5 -0
- package/example.ts +1 -0
- package/package.json +155 -0
- package/src/agent/agent.entity.ts +137 -0
- package/src/agent/agent.enum.ts +31 -0
- package/src/agent/agent.event.ts +142 -0
- package/src/agent/agent.handler.ts +178 -0
- package/src/agent/agent.operation.ts +444 -0
- package/src/agent/agent.presentation.ts +80 -0
- package/src/agent/agent.schema.ts +214 -0
- package/src/agent/agent.test-spec.ts +55 -0
- package/src/agent/index.ts +67 -0
- package/src/agent.capability.ts +13 -0
- package/src/agent.feature.ts +147 -0
- package/src/docs/agent-console.docblock.ts +97 -0
- package/src/docs/index.ts +1 -0
- package/src/example.ts +41 -0
- package/src/handlers/agent.handlers.ts +572 -0
- package/src/handlers/index.ts +30 -0
- package/src/index.ts +32 -0
- package/src/presentations/index.ts +26 -0
- package/src/run/index.ts +68 -0
- package/src/run/run.entity.ts +175 -0
- package/src/run/run.enum.ts +43 -0
- package/src/run/run.event.ts +264 -0
- package/src/run/run.handler.ts +138 -0
- package/src/run/run.operation.ts +524 -0
- package/src/run/run.presentation.ts +54 -0
- package/src/run/run.schema.ts +169 -0
- package/src/run/run.test-spec.ts +55 -0
- package/src/seeders/index.ts +29 -0
- package/src/shared/index.ts +6 -0
- package/src/shared/mock-agents.ts +81 -0
- package/src/shared/mock-runs.ts +107 -0
- package/src/shared/mock-tools.ts +145 -0
- package/src/shared/overlay-types.ts +39 -0
- package/src/tool/index.ts +60 -0
- package/src/tool/tool.entity.ts +99 -0
- package/src/tool/tool.enum.ts +32 -0
- package/src/tool/tool.event.ts +119 -0
- package/src/tool/tool.handler.ts +154 -0
- package/src/tool/tool.operation.ts +366 -0
- package/src/tool/tool.presentation.ts +55 -0
- package/src/tool/tool.schema.ts +133 -0
- package/src/tool/tool.test-spec.ts +55 -0
- package/src/ui/AgentDashboard.tsx +416 -0
- package/src/ui/AgentRunList.tsx +8 -0
- package/src/ui/AgentToolRegistry.tsx +8 -0
- package/src/ui/hooks/index.ts +14 -0
- package/src/ui/hooks/useAgentList.ts +80 -0
- package/src/ui/hooks/useAgentMutations.ts +156 -0
- package/src/ui/hooks/useRunList.ts +81 -0
- package/src/ui/hooks/useToolList.ts +122 -0
- package/src/ui/index.ts +21 -0
- package/src/ui/modals/AgentActionsModal.tsx +306 -0
- package/src/ui/modals/CreateAgentModal.tsx +257 -0
- package/src/ui/modals/index.ts +2 -0
- package/src/ui/overlays/demo-overlays.ts +77 -0
- package/src/ui/overlays/index.ts +1 -0
- package/src/ui/renderers/agent-list.markdown.ts +84 -0
- package/src/ui/renderers/agent-list.renderer.tsx +27 -0
- package/src/ui/renderers/dashboard.markdown.ts +169 -0
- package/src/ui/renderers/index.ts +12 -0
- package/src/ui/renderers/run-list.markdown.ts +75 -0
- package/src/ui/renderers/tool-registry.markdown.ts +91 -0
- package/src/ui/views/AgentListView.tsx +113 -0
- package/src/ui/views/RunListView.tsx +173 -0
- package/src/ui/views/ToolRegistryView.tsx +140 -0
- package/src/ui/views/index.ts +6 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsdown.config.js +7 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Agent Console Dashboard
|
|
5
|
+
*
|
|
6
|
+
* Fully integrated with ContractSpec example handlers,
|
|
7
|
+
* design-system components, and command mutations.
|
|
8
|
+
*
|
|
9
|
+
* Commands wired:
|
|
10
|
+
* - CreateAgentCommand -> Create Agent button + modal
|
|
11
|
+
* - UpdateAgentCommand -> Status changes via modal
|
|
12
|
+
* - ExecuteAgentCommand -> Execute agent via modal
|
|
13
|
+
*/
|
|
14
|
+
import { useState, useMemo, useCallback } from 'react';
|
|
15
|
+
import {
|
|
16
|
+
StatCard,
|
|
17
|
+
StatCardGroup,
|
|
18
|
+
Button,
|
|
19
|
+
} from '@contractspec/lib.design-system';
|
|
20
|
+
// import { AgentListView } from './views/AgentListView';
|
|
21
|
+
import { RunListView } from './views/RunListView';
|
|
22
|
+
import { ToolRegistryView } from './views/ToolRegistryView';
|
|
23
|
+
import { useRunList, type RunMetrics } from './hooks/useRunList';
|
|
24
|
+
import { useAgentList, type Agent } from './hooks/useAgentList';
|
|
25
|
+
import { useAgentMutations } from './hooks/useAgentMutations';
|
|
26
|
+
import { CreateAgentModal } from './modals/CreateAgentModal';
|
|
27
|
+
import { AgentActionsModal } from './modals/AgentActionsModal';
|
|
28
|
+
|
|
29
|
+
type Tab = 'runs' | 'agents' | 'tools' | 'metrics';
|
|
30
|
+
|
|
31
|
+
export function AgentDashboard() {
|
|
32
|
+
const [activeTab, setActiveTab] = useState<Tab>('runs');
|
|
33
|
+
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
|
34
|
+
const [selectedAgent, setSelectedAgent] = useState<Agent | null>(null);
|
|
35
|
+
const [isAgentActionsOpen, setIsAgentActionsOpen] = useState(false);
|
|
36
|
+
|
|
37
|
+
const { metrics, refetch: refetchRuns } = useRunList();
|
|
38
|
+
const { refetch: refetchAgents } = useAgentList();
|
|
39
|
+
|
|
40
|
+
const mutations = useAgentMutations({
|
|
41
|
+
onSuccess: () => {
|
|
42
|
+
refetchAgents();
|
|
43
|
+
refetchRuns();
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const handleAgentClick = useCallback((agent: Agent) => {
|
|
48
|
+
setSelectedAgent(agent);
|
|
49
|
+
setIsAgentActionsOpen(true);
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
const tabs: { id: Tab; label: string; icon: string }[] = [
|
|
53
|
+
{ id: 'runs', label: 'Runs', icon: '▶' },
|
|
54
|
+
{ id: 'agents', label: 'Agents', icon: '🤖' },
|
|
55
|
+
{ id: 'tools', label: 'Tools', icon: '🔧' },
|
|
56
|
+
{ id: 'metrics', label: 'Metrics', icon: '📊' },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
// Compute summary stats from metrics
|
|
60
|
+
const summaryStats = useMemo(() => {
|
|
61
|
+
if (!metrics) {
|
|
62
|
+
return [
|
|
63
|
+
{ label: 'Total Runs', value: '-', hint: 'Loading...' },
|
|
64
|
+
{ label: 'Success Rate', value: '-', hint: '' },
|
|
65
|
+
{ label: 'Total Tokens', value: '-', hint: '' },
|
|
66
|
+
{ label: 'Total Cost', value: '-', hint: '' },
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
label: 'Total Runs',
|
|
72
|
+
value: metrics.totalRuns.toLocaleString(),
|
|
73
|
+
hint: `${(metrics.successRate * 100).toFixed(0)}% success`,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
label: 'Success Rate',
|
|
77
|
+
value: `${(metrics.successRate * 100).toFixed(0)}%`,
|
|
78
|
+
hint: 'of all runs',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
label: 'Total Tokens',
|
|
82
|
+
value:
|
|
83
|
+
metrics.totalTokens >= 1000000
|
|
84
|
+
? `${(metrics.totalTokens / 1000000).toFixed(1)}M`
|
|
85
|
+
: `${(metrics.totalTokens / 1000).toFixed(0)}K`,
|
|
86
|
+
hint: 'This period',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
label: 'Total Cost',
|
|
90
|
+
value: `$${metrics.totalCostUsd.toFixed(2)}`,
|
|
91
|
+
hint: 'This period',
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
}, [metrics]);
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<div className="space-y-6">
|
|
98
|
+
{/* Header */}
|
|
99
|
+
<div className="flex items-center justify-between">
|
|
100
|
+
<h2 className="text-2xl font-bold">AI Agent Console</h2>
|
|
101
|
+
<Button onPress={() => setIsCreateModalOpen(true)}>
|
|
102
|
+
<span className="mr-2">+</span> New Agent
|
|
103
|
+
</Button>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
{/* Summary Stats Row */}
|
|
107
|
+
<StatCardGroup>
|
|
108
|
+
{summaryStats.map((stat, i) => (
|
|
109
|
+
<StatCard
|
|
110
|
+
key={i}
|
|
111
|
+
label={stat.label}
|
|
112
|
+
value={stat.value}
|
|
113
|
+
hint={stat.hint}
|
|
114
|
+
/>
|
|
115
|
+
))}
|
|
116
|
+
</StatCardGroup>
|
|
117
|
+
|
|
118
|
+
{/* Navigation Tabs */}
|
|
119
|
+
<nav className="bg-muted flex gap-1 rounded-lg p-1" role="tablist">
|
|
120
|
+
{tabs.map((tab) => (
|
|
121
|
+
<button
|
|
122
|
+
key={tab.id}
|
|
123
|
+
type="button"
|
|
124
|
+
role="tab"
|
|
125
|
+
aria-selected={activeTab === tab.id}
|
|
126
|
+
onClick={() => setActiveTab(tab.id)}
|
|
127
|
+
className={`flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${
|
|
128
|
+
activeTab === tab.id
|
|
129
|
+
? 'bg-background text-foreground shadow-sm'
|
|
130
|
+
: 'text-muted-foreground hover:text-foreground'
|
|
131
|
+
}`}
|
|
132
|
+
>
|
|
133
|
+
<span>{tab.icon}</span>
|
|
134
|
+
{tab.label}
|
|
135
|
+
</button>
|
|
136
|
+
))}
|
|
137
|
+
</nav>
|
|
138
|
+
|
|
139
|
+
{/* Tab Content */}
|
|
140
|
+
<div className="min-h-[400px]" role="tabpanel">
|
|
141
|
+
{activeTab === 'runs' && <RunListView />}
|
|
142
|
+
{activeTab === 'agents' && (
|
|
143
|
+
<AgentListViewWithActions onAgentClick={handleAgentClick} />
|
|
144
|
+
)}
|
|
145
|
+
{activeTab === 'tools' && <ToolRegistryView />}
|
|
146
|
+
{activeTab === 'metrics' && <MetricsView metrics={metrics} />}
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
{/* Create Agent Modal */}
|
|
150
|
+
<CreateAgentModal
|
|
151
|
+
isOpen={isCreateModalOpen}
|
|
152
|
+
onClose={() => setIsCreateModalOpen(false)}
|
|
153
|
+
onSubmit={async (input) => {
|
|
154
|
+
await mutations.createAgent(input);
|
|
155
|
+
}}
|
|
156
|
+
isLoading={mutations.createState.loading}
|
|
157
|
+
/>
|
|
158
|
+
|
|
159
|
+
{/* Agent Actions Modal */}
|
|
160
|
+
<AgentActionsModal
|
|
161
|
+
isOpen={isAgentActionsOpen}
|
|
162
|
+
agent={selectedAgent}
|
|
163
|
+
onClose={() => {
|
|
164
|
+
setIsAgentActionsOpen(false);
|
|
165
|
+
setSelectedAgent(null);
|
|
166
|
+
}}
|
|
167
|
+
onActivate={async (agentId) => {
|
|
168
|
+
await mutations.activateAgent(agentId);
|
|
169
|
+
}}
|
|
170
|
+
onPause={async (agentId) => {
|
|
171
|
+
await mutations.pauseAgent(agentId);
|
|
172
|
+
}}
|
|
173
|
+
onArchive={async (agentId) => {
|
|
174
|
+
await mutations.archiveAgent(agentId);
|
|
175
|
+
}}
|
|
176
|
+
onExecute={async (agentId, message) => {
|
|
177
|
+
await mutations.executeAgent({ agentId, message });
|
|
178
|
+
}}
|
|
179
|
+
isLoading={mutations.isLoading}
|
|
180
|
+
/>
|
|
181
|
+
</div>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Agent List View with click handler
|
|
187
|
+
*/
|
|
188
|
+
function AgentListViewWithActions({
|
|
189
|
+
onAgentClick,
|
|
190
|
+
}: {
|
|
191
|
+
onAgentClick: (agent: Agent) => void;
|
|
192
|
+
}) {
|
|
193
|
+
const { data, loading, error, stats, refetch } = useAgentList();
|
|
194
|
+
|
|
195
|
+
if (loading && !data) {
|
|
196
|
+
return (
|
|
197
|
+
<div className="text-muted-foreground flex h-64 items-center justify-center">
|
|
198
|
+
Loading agents...
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (error) {
|
|
204
|
+
return (
|
|
205
|
+
<div className="text-destructive flex h-64 flex-col items-center justify-center">
|
|
206
|
+
<p>Failed to load agents: {error.message}</p>
|
|
207
|
+
<Button variant="outline" onPress={refetch} className="mt-2">
|
|
208
|
+
Retry
|
|
209
|
+
</Button>
|
|
210
|
+
</div>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (!data?.items.length) {
|
|
215
|
+
return (
|
|
216
|
+
<div className="text-muted-foreground flex h-64 flex-col items-center justify-center">
|
|
217
|
+
<p className="text-lg font-medium">No agents yet</p>
|
|
218
|
+
<p className="text-sm">Create your first AI agent to get started.</p>
|
|
219
|
+
</div>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<div className="space-y-4">
|
|
225
|
+
{/* Stats */}
|
|
226
|
+
{stats && (
|
|
227
|
+
<div className="flex gap-4 text-sm">
|
|
228
|
+
<span>Total: {stats.total}</span>
|
|
229
|
+
<span className="text-green-600">Active: {stats.active}</span>
|
|
230
|
+
<span className="text-yellow-600">Paused: {stats.paused}</span>
|
|
231
|
+
<span className="text-blue-600">Draft: {stats.draft}</span>
|
|
232
|
+
</div>
|
|
233
|
+
)}
|
|
234
|
+
|
|
235
|
+
{/* Agent Grid */}
|
|
236
|
+
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
237
|
+
{data.items.map((agent) => (
|
|
238
|
+
<AgentCard
|
|
239
|
+
key={agent.id}
|
|
240
|
+
agent={agent}
|
|
241
|
+
onClick={() => onAgentClick(agent)}
|
|
242
|
+
/>
|
|
243
|
+
))}
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Agent Card Component
|
|
251
|
+
*/
|
|
252
|
+
function AgentCard({ agent, onClick }: { agent: Agent; onClick: () => void }) {
|
|
253
|
+
const statusColors: Record<string, string> = {
|
|
254
|
+
ACTIVE:
|
|
255
|
+
'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
|
|
256
|
+
DRAFT: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
|
|
257
|
+
PAUSED:
|
|
258
|
+
'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400',
|
|
259
|
+
ARCHIVED: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400',
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<div
|
|
264
|
+
onClick={onClick}
|
|
265
|
+
className="border-border bg-card cursor-pointer rounded-xl border p-4 transition-all hover:shadow-md"
|
|
266
|
+
role="button"
|
|
267
|
+
tabIndex={0}
|
|
268
|
+
onKeyDown={(e) => {
|
|
269
|
+
if (e.key === 'Enter' || e.key === ' ') onClick();
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
272
|
+
<div className="flex items-start justify-between">
|
|
273
|
+
<div className="min-w-0 flex-1">
|
|
274
|
+
<h3 className="truncate font-semibold">{agent.name}</h3>
|
|
275
|
+
<p className="text-muted-foreground text-sm">
|
|
276
|
+
{agent.modelProvider} / {agent.modelName}
|
|
277
|
+
</p>
|
|
278
|
+
</div>
|
|
279
|
+
<span
|
|
280
|
+
className={`rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[agent.status]}`}
|
|
281
|
+
>
|
|
282
|
+
{agent.status}
|
|
283
|
+
</span>
|
|
284
|
+
</div>
|
|
285
|
+
{agent.description && (
|
|
286
|
+
<p className="text-muted-foreground mt-2 line-clamp-2 text-sm">
|
|
287
|
+
{agent.description}
|
|
288
|
+
</p>
|
|
289
|
+
)}
|
|
290
|
+
<div className="mt-3 flex items-center justify-between">
|
|
291
|
+
<span className="text-muted-foreground text-xs">{agent.modelName}</span>
|
|
292
|
+
<Button variant="ghost" size="sm" onPress={onClick}>
|
|
293
|
+
Actions
|
|
294
|
+
</Button>
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Metrics View - Shows usage analytics
|
|
302
|
+
*/
|
|
303
|
+
function MetricsView({ metrics }: { metrics: RunMetrics | null }) {
|
|
304
|
+
if (!metrics) {
|
|
305
|
+
return (
|
|
306
|
+
<div className="text-muted-foreground flex h-64 items-center justify-center">
|
|
307
|
+
Loading metrics...
|
|
308
|
+
</div>
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Calculate derived metrics
|
|
313
|
+
const completedRuns = Math.round(metrics.totalRuns * metrics.successRate);
|
|
314
|
+
const failedRuns = metrics.totalRuns - completedRuns;
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<div className="space-y-6">
|
|
318
|
+
<h3 className="text-lg font-semibold">Usage Analytics</h3>
|
|
319
|
+
|
|
320
|
+
<div className="grid gap-6 md:grid-cols-2">
|
|
321
|
+
{/* Success/Failure breakdown */}
|
|
322
|
+
<div className="border-border bg-card rounded-xl border p-4">
|
|
323
|
+
<h4 className="font-medium">Run Outcomes</h4>
|
|
324
|
+
<div className="mt-4 space-y-3">
|
|
325
|
+
<ProgressBar
|
|
326
|
+
label="Completed"
|
|
327
|
+
value={completedRuns}
|
|
328
|
+
total={metrics.totalRuns}
|
|
329
|
+
color="bg-green-500"
|
|
330
|
+
/>
|
|
331
|
+
<ProgressBar
|
|
332
|
+
label="Failed"
|
|
333
|
+
value={failedRuns}
|
|
334
|
+
total={metrics.totalRuns}
|
|
335
|
+
color="bg-red-500"
|
|
336
|
+
/>
|
|
337
|
+
</div>
|
|
338
|
+
</div>
|
|
339
|
+
|
|
340
|
+
{/* Key Stats */}
|
|
341
|
+
<div className="border-border bg-card rounded-xl border p-4">
|
|
342
|
+
<h4 className="font-medium">Performance</h4>
|
|
343
|
+
<dl className="mt-4 grid grid-cols-2 gap-4">
|
|
344
|
+
<div>
|
|
345
|
+
<dt className="text-muted-foreground text-sm">Avg Duration</dt>
|
|
346
|
+
<dd className="text-xl font-semibold">
|
|
347
|
+
{(metrics.averageDurationMs / 1000).toFixed(1)}s
|
|
348
|
+
</dd>
|
|
349
|
+
</div>
|
|
350
|
+
<div>
|
|
351
|
+
<dt className="text-muted-foreground text-sm">Success Rate</dt>
|
|
352
|
+
<dd className="text-xl font-semibold">
|
|
353
|
+
{(metrics.successRate * 100).toFixed(0)}%
|
|
354
|
+
</dd>
|
|
355
|
+
</div>
|
|
356
|
+
</dl>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
{/* Key Metrics */}
|
|
361
|
+
<div className="border-border bg-card rounded-xl border p-4">
|
|
362
|
+
<h4 className="font-medium">Key Metrics</h4>
|
|
363
|
+
<dl className="mt-4 grid gap-4 sm:grid-cols-3">
|
|
364
|
+
<div>
|
|
365
|
+
<dt className="text-muted-foreground text-sm">Total Runs</dt>
|
|
366
|
+
<dd className="text-2xl font-semibold">
|
|
367
|
+
{metrics.totalRuns.toLocaleString()}
|
|
368
|
+
</dd>
|
|
369
|
+
</div>
|
|
370
|
+
<div>
|
|
371
|
+
<dt className="text-muted-foreground text-sm">Total Tokens</dt>
|
|
372
|
+
<dd className="text-2xl font-semibold">
|
|
373
|
+
{(metrics.totalTokens / 1000).toFixed(0)}K
|
|
374
|
+
</dd>
|
|
375
|
+
</div>
|
|
376
|
+
<div>
|
|
377
|
+
<dt className="text-muted-foreground text-sm">Cost per Run</dt>
|
|
378
|
+
<dd className="text-2xl font-semibold">
|
|
379
|
+
$
|
|
380
|
+
{metrics.totalRuns > 0
|
|
381
|
+
? (metrics.totalCostUsd / metrics.totalRuns).toFixed(4)
|
|
382
|
+
: '0'}
|
|
383
|
+
</dd>
|
|
384
|
+
</div>
|
|
385
|
+
</dl>
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function ProgressBar({
|
|
392
|
+
label,
|
|
393
|
+
value,
|
|
394
|
+
total,
|
|
395
|
+
color,
|
|
396
|
+
}: {
|
|
397
|
+
label: string;
|
|
398
|
+
value: number;
|
|
399
|
+
total: number;
|
|
400
|
+
color: string;
|
|
401
|
+
}) {
|
|
402
|
+
const pct = total > 0 ? (value / total) * 100 : 0;
|
|
403
|
+
return (
|
|
404
|
+
<div>
|
|
405
|
+
<div className="flex justify-between text-sm">
|
|
406
|
+
<span>{label}</span>
|
|
407
|
+
<span className="text-muted-foreground">
|
|
408
|
+
{value} ({pct.toFixed(0)}%)
|
|
409
|
+
</span>
|
|
410
|
+
</div>
|
|
411
|
+
<div className="bg-muted mt-1 h-2 overflow-hidden rounded-full">
|
|
412
|
+
<div className={`h-full ${color}`} style={{ width: `${pct}%` }} />
|
|
413
|
+
</div>
|
|
414
|
+
</div>
|
|
415
|
+
);
|
|
416
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Data hooks for agent-console template
|
|
5
|
+
*/
|
|
6
|
+
export { useAgentList, type UseAgentListOptions } from './useAgentList';
|
|
7
|
+
export { useRunList, type UseRunListOptions } from './useRunList';
|
|
8
|
+
export { useToolList, type UseToolListOptions } from './useToolList';
|
|
9
|
+
export {
|
|
10
|
+
useAgentMutations,
|
|
11
|
+
type UseAgentMutationsOptions,
|
|
12
|
+
type CreateAgentInput,
|
|
13
|
+
type UpdateAgentInput,
|
|
14
|
+
} from './useAgentMutations';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for fetching and managing agent list data
|
|
3
|
+
*
|
|
4
|
+
* Uses runtime-local database-backed handlers.
|
|
5
|
+
*/
|
|
6
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
|
+
import { useTemplateRuntime } from '@contractspec/lib.example-shared-ui';
|
|
8
|
+
import type {
|
|
9
|
+
Agent as RuntimeAgent,
|
|
10
|
+
ListAgentsOutput as RuntimeListAgentsOutput,
|
|
11
|
+
} from '../../handlers/agent.handlers';
|
|
12
|
+
import type { AgentHandlers } from '../../handlers/agent.handlers';
|
|
13
|
+
|
|
14
|
+
// Re-export types for convenience
|
|
15
|
+
export type Agent = RuntimeAgent;
|
|
16
|
+
export type ListAgentsOutput = RuntimeListAgentsOutput;
|
|
17
|
+
|
|
18
|
+
export interface UseAgentListOptions {
|
|
19
|
+
search?: string;
|
|
20
|
+
status?: 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'ARCHIVED' | 'all';
|
|
21
|
+
limit?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function useAgentList(options: UseAgentListOptions = {}) {
|
|
25
|
+
const { handlers, projectId } = useTemplateRuntime<{
|
|
26
|
+
agent: AgentHandlers;
|
|
27
|
+
}>();
|
|
28
|
+
const { agent } = handlers;
|
|
29
|
+
|
|
30
|
+
const [data, setData] = useState<ListAgentsOutput | null>(null);
|
|
31
|
+
const [loading, setLoading] = useState(true);
|
|
32
|
+
const [error, setError] = useState<Error | null>(null);
|
|
33
|
+
const [page, setPage] = useState(1);
|
|
34
|
+
|
|
35
|
+
const fetchData = useCallback(async () => {
|
|
36
|
+
setLoading(true);
|
|
37
|
+
setError(null);
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const result = await agent.listAgents({
|
|
41
|
+
projectId,
|
|
42
|
+
search: options.search,
|
|
43
|
+
status: options.status === 'all' ? undefined : options.status,
|
|
44
|
+
limit: options.limit ?? 20,
|
|
45
|
+
offset: (page - 1) * (options.limit ?? 20),
|
|
46
|
+
});
|
|
47
|
+
setData(result);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
setError(err instanceof Error ? err : new Error('Unknown error'));
|
|
50
|
+
} finally {
|
|
51
|
+
setLoading(false);
|
|
52
|
+
}
|
|
53
|
+
}, [agent, projectId, options.search, options.status, options.limit, page]);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
fetchData();
|
|
57
|
+
}, [fetchData]);
|
|
58
|
+
|
|
59
|
+
// Calculate stats
|
|
60
|
+
const stats = useMemo(() => {
|
|
61
|
+
if (!data) return null;
|
|
62
|
+
return {
|
|
63
|
+
total: data.total,
|
|
64
|
+
active: data.items.filter((a) => a.status === 'ACTIVE').length,
|
|
65
|
+
paused: data.items.filter((a) => a.status === 'PAUSED').length,
|
|
66
|
+
draft: data.items.filter((a) => a.status === 'DRAFT').length,
|
|
67
|
+
};
|
|
68
|
+
}, [data]);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
data,
|
|
72
|
+
loading,
|
|
73
|
+
error,
|
|
74
|
+
stats,
|
|
75
|
+
page,
|
|
76
|
+
refetch: fetchData,
|
|
77
|
+
nextPage: () => setPage((p) => p + 1),
|
|
78
|
+
prevPage: () => page > 1 && setPage((p) => p - 1),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for Agent Console mutations (commands)
|
|
3
|
+
*
|
|
4
|
+
* Uses runtime-local database-backed handlers for:
|
|
5
|
+
* - CreateAgentCommand
|
|
6
|
+
* - UpdateAgentCommand
|
|
7
|
+
*/
|
|
8
|
+
import { useCallback, useState } from 'react';
|
|
9
|
+
import { useTemplateRuntime } from '@contractspec/lib.example-shared-ui';
|
|
10
|
+
import type {
|
|
11
|
+
Agent,
|
|
12
|
+
CreateAgentInput,
|
|
13
|
+
UpdateAgentInput,
|
|
14
|
+
AgentHandlers,
|
|
15
|
+
} from '../../handlers/agent.handlers';
|
|
16
|
+
|
|
17
|
+
export interface MutationState<T> {
|
|
18
|
+
loading: boolean;
|
|
19
|
+
error: Error | null;
|
|
20
|
+
data: T | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface UseAgentMutationsOptions {
|
|
24
|
+
onSuccess?: () => void;
|
|
25
|
+
onError?: (error: Error) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function useAgentMutations(options: UseAgentMutationsOptions = {}) {
|
|
29
|
+
const { handlers, projectId } = useTemplateRuntime<{
|
|
30
|
+
agent: AgentHandlers;
|
|
31
|
+
}>();
|
|
32
|
+
const { agent } = handlers;
|
|
33
|
+
|
|
34
|
+
const [createState, setCreateState] = useState<MutationState<Agent>>({
|
|
35
|
+
loading: false,
|
|
36
|
+
error: null,
|
|
37
|
+
data: null,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const [updateState, setUpdateState] = useState<MutationState<Agent>>({
|
|
41
|
+
loading: false,
|
|
42
|
+
error: null,
|
|
43
|
+
data: null,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a new agent
|
|
48
|
+
*/
|
|
49
|
+
const createAgent = useCallback(
|
|
50
|
+
async (input: CreateAgentInput): Promise<Agent | null> => {
|
|
51
|
+
setCreateState({ loading: true, error: null, data: null });
|
|
52
|
+
try {
|
|
53
|
+
const result = await agent.createAgent(input, {
|
|
54
|
+
projectId,
|
|
55
|
+
organizationId: 'demo-org',
|
|
56
|
+
});
|
|
57
|
+
setCreateState({ loading: false, error: null, data: result });
|
|
58
|
+
options.onSuccess?.();
|
|
59
|
+
return result;
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const error =
|
|
62
|
+
err instanceof Error ? err : new Error('Failed to create agent');
|
|
63
|
+
setCreateState({ loading: false, error, data: null });
|
|
64
|
+
options.onError?.(error);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
[agent, projectId, options]
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Update an agent (name, status)
|
|
73
|
+
*/
|
|
74
|
+
const updateAgent = useCallback(
|
|
75
|
+
async (input: UpdateAgentInput): Promise<Agent | null> => {
|
|
76
|
+
setUpdateState({ loading: true, error: null, data: null });
|
|
77
|
+
try {
|
|
78
|
+
const result = await agent.updateAgent(input);
|
|
79
|
+
setUpdateState({ loading: false, error: null, data: result });
|
|
80
|
+
options.onSuccess?.();
|
|
81
|
+
return result;
|
|
82
|
+
} catch (err) {
|
|
83
|
+
const error =
|
|
84
|
+
err instanceof Error ? err : new Error('Failed to update agent');
|
|
85
|
+
setUpdateState({ loading: false, error, data: null });
|
|
86
|
+
options.onError?.(error);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
[agent, options]
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Activate an agent
|
|
95
|
+
*/
|
|
96
|
+
const activateAgent = useCallback(
|
|
97
|
+
async (agentId: string): Promise<Agent | null> => {
|
|
98
|
+
return updateAgent({ id: agentId, status: 'ACTIVE' });
|
|
99
|
+
},
|
|
100
|
+
[updateAgent]
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Pause an agent
|
|
105
|
+
*/
|
|
106
|
+
const pauseAgent = useCallback(
|
|
107
|
+
async (agentId: string): Promise<Agent | null> => {
|
|
108
|
+
return updateAgent({ id: agentId, status: 'PAUSED' });
|
|
109
|
+
},
|
|
110
|
+
[updateAgent]
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Archive an agent
|
|
115
|
+
*/
|
|
116
|
+
const archiveAgent = useCallback(
|
|
117
|
+
async (agentId: string): Promise<Agent | null> => {
|
|
118
|
+
return updateAgent({ id: agentId, status: 'ARCHIVED' });
|
|
119
|
+
},
|
|
120
|
+
[updateAgent]
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Execute an agent (placeholder - needs run handler)
|
|
125
|
+
* Note: Execute functionality requires adding createRun/executeRun to agent handlers
|
|
126
|
+
*/
|
|
127
|
+
const executeAgent = useCallback(
|
|
128
|
+
async (input: { agentId: string; message: string }): Promise<null> => {
|
|
129
|
+
// TODO: Implement execute when run creation handler is added to runtime-local
|
|
130
|
+
console.log('Execute agent:', input);
|
|
131
|
+
options.onSuccess?.();
|
|
132
|
+
return null;
|
|
133
|
+
},
|
|
134
|
+
[options]
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
// Mutations
|
|
139
|
+
createAgent,
|
|
140
|
+
updateAgent,
|
|
141
|
+
activateAgent,
|
|
142
|
+
pauseAgent,
|
|
143
|
+
archiveAgent,
|
|
144
|
+
executeAgent,
|
|
145
|
+
|
|
146
|
+
// State
|
|
147
|
+
createState,
|
|
148
|
+
updateState,
|
|
149
|
+
|
|
150
|
+
// Convenience
|
|
151
|
+
isLoading: createState.loading || updateState.loading,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Re-export types for convenience
|
|
156
|
+
export type { CreateAgentInput, UpdateAgentInput, Agent };
|