@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,420 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useRunList } from "./hooks/useRunList.js";
|
|
4
|
+
import { RunListView } from "./views/RunListView.js";
|
|
5
|
+
import { ToolRegistryView } from "./views/ToolRegistryView.js";
|
|
6
|
+
import { useAgentList } from "./hooks/useAgentList.js";
|
|
7
|
+
import { useAgentMutations } from "./hooks/useAgentMutations.js";
|
|
8
|
+
import { CreateAgentModal } from "./modals/CreateAgentModal.js";
|
|
9
|
+
import { AgentActionsModal } from "./modals/AgentActionsModal.js";
|
|
10
|
+
import { useCallback, useMemo, useState } from "react";
|
|
11
|
+
import { Button, StatCard, StatCardGroup } from "@contractspec/lib.design-system";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
|
|
14
|
+
//#region src/ui/AgentDashboard.tsx
|
|
15
|
+
/**
|
|
16
|
+
* Agent Console Dashboard
|
|
17
|
+
*
|
|
18
|
+
* Fully integrated with ContractSpec example handlers,
|
|
19
|
+
* design-system components, and command mutations.
|
|
20
|
+
*
|
|
21
|
+
* Commands wired:
|
|
22
|
+
* - CreateAgentCommand -> Create Agent button + modal
|
|
23
|
+
* - UpdateAgentCommand -> Status changes via modal
|
|
24
|
+
* - ExecuteAgentCommand -> Execute agent via modal
|
|
25
|
+
*/
|
|
26
|
+
function AgentDashboard() {
|
|
27
|
+
const [activeTab, setActiveTab] = useState("runs");
|
|
28
|
+
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
|
29
|
+
const [selectedAgent, setSelectedAgent] = useState(null);
|
|
30
|
+
const [isAgentActionsOpen, setIsAgentActionsOpen] = useState(false);
|
|
31
|
+
const { metrics, refetch: refetchRuns } = useRunList();
|
|
32
|
+
const { refetch: refetchAgents } = useAgentList();
|
|
33
|
+
const mutations = useAgentMutations({ onSuccess: () => {
|
|
34
|
+
refetchAgents();
|
|
35
|
+
refetchRuns();
|
|
36
|
+
} });
|
|
37
|
+
const handleAgentClick = useCallback((agent) => {
|
|
38
|
+
setSelectedAgent(agent);
|
|
39
|
+
setIsAgentActionsOpen(true);
|
|
40
|
+
}, []);
|
|
41
|
+
const tabs = [
|
|
42
|
+
{
|
|
43
|
+
id: "runs",
|
|
44
|
+
label: "Runs",
|
|
45
|
+
icon: "▶"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "agents",
|
|
49
|
+
label: "Agents",
|
|
50
|
+
icon: "🤖"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "tools",
|
|
54
|
+
label: "Tools",
|
|
55
|
+
icon: "🔧"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "metrics",
|
|
59
|
+
label: "Metrics",
|
|
60
|
+
icon: "📊"
|
|
61
|
+
}
|
|
62
|
+
];
|
|
63
|
+
const summaryStats = useMemo(() => {
|
|
64
|
+
if (!metrics) return [
|
|
65
|
+
{
|
|
66
|
+
label: "Total Runs",
|
|
67
|
+
value: "-",
|
|
68
|
+
hint: "Loading..."
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
label: "Success Rate",
|
|
72
|
+
value: "-",
|
|
73
|
+
hint: ""
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
label: "Total Tokens",
|
|
77
|
+
value: "-",
|
|
78
|
+
hint: ""
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
label: "Total Cost",
|
|
82
|
+
value: "-",
|
|
83
|
+
hint: ""
|
|
84
|
+
}
|
|
85
|
+
];
|
|
86
|
+
return [
|
|
87
|
+
{
|
|
88
|
+
label: "Total Runs",
|
|
89
|
+
value: metrics.totalRuns.toLocaleString(),
|
|
90
|
+
hint: `${(metrics.successRate * 100).toFixed(0)}% success`
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
label: "Success Rate",
|
|
94
|
+
value: `${(metrics.successRate * 100).toFixed(0)}%`,
|
|
95
|
+
hint: "of all runs"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
label: "Total Tokens",
|
|
99
|
+
value: metrics.totalTokens >= 1e6 ? `${(metrics.totalTokens / 1e6).toFixed(1)}M` : `${(metrics.totalTokens / 1e3).toFixed(0)}K`,
|
|
100
|
+
hint: "This period"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: "Total Cost",
|
|
104
|
+
value: `$${metrics.totalCostUsd.toFixed(2)}`,
|
|
105
|
+
hint: "This period"
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
}, [metrics]);
|
|
109
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
110
|
+
className: "space-y-6",
|
|
111
|
+
children: [
|
|
112
|
+
/* @__PURE__ */ jsxs("div", {
|
|
113
|
+
className: "flex items-center justify-between",
|
|
114
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
115
|
+
className: "text-2xl font-bold",
|
|
116
|
+
children: "AI Agent Console"
|
|
117
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
118
|
+
onPress: () => setIsCreateModalOpen(true),
|
|
119
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
120
|
+
className: "mr-2",
|
|
121
|
+
children: "+"
|
|
122
|
+
}), " New Agent"]
|
|
123
|
+
})]
|
|
124
|
+
}),
|
|
125
|
+
/* @__PURE__ */ jsx(StatCardGroup, { children: summaryStats.map((stat, i) => /* @__PURE__ */ jsx(StatCard, {
|
|
126
|
+
label: stat.label,
|
|
127
|
+
value: stat.value,
|
|
128
|
+
hint: stat.hint
|
|
129
|
+
}, i)) }),
|
|
130
|
+
/* @__PURE__ */ jsx("nav", {
|
|
131
|
+
className: "bg-muted flex gap-1 rounded-lg p-1",
|
|
132
|
+
role: "tablist",
|
|
133
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs("button", {
|
|
134
|
+
type: "button",
|
|
135
|
+
role: "tab",
|
|
136
|
+
"aria-selected": activeTab === tab.id,
|
|
137
|
+
onClick: () => setActiveTab(tab.id),
|
|
138
|
+
className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
|
|
139
|
+
children: [/* @__PURE__ */ jsx("span", { children: tab.icon }), tab.label]
|
|
140
|
+
}, tab.id))
|
|
141
|
+
}),
|
|
142
|
+
/* @__PURE__ */ jsxs("div", {
|
|
143
|
+
className: "min-h-[400px]",
|
|
144
|
+
role: "tabpanel",
|
|
145
|
+
children: [
|
|
146
|
+
activeTab === "runs" && /* @__PURE__ */ jsx(RunListView, {}),
|
|
147
|
+
activeTab === "agents" && /* @__PURE__ */ jsx(AgentListViewWithActions, { onAgentClick: handleAgentClick }),
|
|
148
|
+
activeTab === "tools" && /* @__PURE__ */ jsx(ToolRegistryView, {}),
|
|
149
|
+
activeTab === "metrics" && /* @__PURE__ */ jsx(MetricsView, { metrics })
|
|
150
|
+
]
|
|
151
|
+
}),
|
|
152
|
+
/* @__PURE__ */ jsx(CreateAgentModal, {
|
|
153
|
+
isOpen: isCreateModalOpen,
|
|
154
|
+
onClose: () => setIsCreateModalOpen(false),
|
|
155
|
+
onSubmit: async (input) => {
|
|
156
|
+
await mutations.createAgent(input);
|
|
157
|
+
},
|
|
158
|
+
isLoading: mutations.createState.loading
|
|
159
|
+
}),
|
|
160
|
+
/* @__PURE__ */ jsx(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({
|
|
178
|
+
agentId,
|
|
179
|
+
message
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
isLoading: mutations.isLoading
|
|
183
|
+
})
|
|
184
|
+
]
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Agent List View with click handler
|
|
189
|
+
*/
|
|
190
|
+
function AgentListViewWithActions({ onAgentClick }) {
|
|
191
|
+
const { data, loading, error, stats, refetch } = useAgentList();
|
|
192
|
+
if (loading && !data) return /* @__PURE__ */ jsx("div", {
|
|
193
|
+
className: "text-muted-foreground flex h-64 items-center justify-center",
|
|
194
|
+
children: "Loading agents..."
|
|
195
|
+
});
|
|
196
|
+
if (error) return /* @__PURE__ */ jsxs("div", {
|
|
197
|
+
className: "text-destructive flex h-64 flex-col items-center justify-center",
|
|
198
|
+
children: [/* @__PURE__ */ jsxs("p", { children: ["Failed to load agents: ", error.message] }), /* @__PURE__ */ jsx(Button, {
|
|
199
|
+
variant: "outline",
|
|
200
|
+
onPress: refetch,
|
|
201
|
+
className: "mt-2",
|
|
202
|
+
children: "Retry"
|
|
203
|
+
})]
|
|
204
|
+
});
|
|
205
|
+
if (!data?.items.length) return /* @__PURE__ */ jsxs("div", {
|
|
206
|
+
className: "text-muted-foreground flex h-64 flex-col items-center justify-center",
|
|
207
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
208
|
+
className: "text-lg font-medium",
|
|
209
|
+
children: "No agents yet"
|
|
210
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
211
|
+
className: "text-sm",
|
|
212
|
+
children: "Create your first AI agent to get started."
|
|
213
|
+
})]
|
|
214
|
+
});
|
|
215
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
216
|
+
className: "space-y-4",
|
|
217
|
+
children: [stats && /* @__PURE__ */ jsxs("div", {
|
|
218
|
+
className: "flex gap-4 text-sm",
|
|
219
|
+
children: [
|
|
220
|
+
/* @__PURE__ */ jsxs("span", { children: ["Total: ", stats.total] }),
|
|
221
|
+
/* @__PURE__ */ jsxs("span", {
|
|
222
|
+
className: "text-green-600",
|
|
223
|
+
children: ["Active: ", stats.active]
|
|
224
|
+
}),
|
|
225
|
+
/* @__PURE__ */ jsxs("span", {
|
|
226
|
+
className: "text-yellow-600",
|
|
227
|
+
children: ["Paused: ", stats.paused]
|
|
228
|
+
}),
|
|
229
|
+
/* @__PURE__ */ jsxs("span", {
|
|
230
|
+
className: "text-blue-600",
|
|
231
|
+
children: ["Draft: ", stats.draft]
|
|
232
|
+
})
|
|
233
|
+
]
|
|
234
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
235
|
+
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
236
|
+
children: data.items.map((agent) => /* @__PURE__ */ jsx(AgentCard, {
|
|
237
|
+
agent,
|
|
238
|
+
onClick: () => onAgentClick(agent)
|
|
239
|
+
}, agent.id))
|
|
240
|
+
})]
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Agent Card Component
|
|
245
|
+
*/
|
|
246
|
+
function AgentCard({ agent, onClick }) {
|
|
247
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
248
|
+
onClick,
|
|
249
|
+
className: "border-border bg-card cursor-pointer rounded-xl border p-4 transition-all hover:shadow-md",
|
|
250
|
+
role: "button",
|
|
251
|
+
tabIndex: 0,
|
|
252
|
+
onKeyDown: (e) => {
|
|
253
|
+
if (e.key === "Enter" || e.key === " ") onClick();
|
|
254
|
+
},
|
|
255
|
+
children: [
|
|
256
|
+
/* @__PURE__ */ jsxs("div", {
|
|
257
|
+
className: "flex items-start justify-between",
|
|
258
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
259
|
+
className: "min-w-0 flex-1",
|
|
260
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
261
|
+
className: "truncate font-semibold",
|
|
262
|
+
children: agent.name
|
|
263
|
+
}), /* @__PURE__ */ jsxs("p", {
|
|
264
|
+
className: "text-muted-foreground text-sm",
|
|
265
|
+
children: [
|
|
266
|
+
agent.modelProvider,
|
|
267
|
+
" / ",
|
|
268
|
+
agent.modelName
|
|
269
|
+
]
|
|
270
|
+
})]
|
|
271
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
272
|
+
className: `rounded-full px-2 py-0.5 text-xs font-medium ${{
|
|
273
|
+
ACTIVE: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
274
|
+
DRAFT: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400",
|
|
275
|
+
PAUSED: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400",
|
|
276
|
+
ARCHIVED: "bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400"
|
|
277
|
+
}[agent.status]}`,
|
|
278
|
+
children: agent.status
|
|
279
|
+
})]
|
|
280
|
+
}),
|
|
281
|
+
agent.description && /* @__PURE__ */ jsx("p", {
|
|
282
|
+
className: "text-muted-foreground mt-2 line-clamp-2 text-sm",
|
|
283
|
+
children: agent.description
|
|
284
|
+
}),
|
|
285
|
+
/* @__PURE__ */ jsxs("div", {
|
|
286
|
+
className: "mt-3 flex items-center justify-between",
|
|
287
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
288
|
+
className: "text-muted-foreground text-xs",
|
|
289
|
+
children: agent.modelName
|
|
290
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
291
|
+
variant: "ghost",
|
|
292
|
+
size: "sm",
|
|
293
|
+
onPress: onClick,
|
|
294
|
+
children: "Actions"
|
|
295
|
+
})]
|
|
296
|
+
})
|
|
297
|
+
]
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Metrics View - Shows usage analytics
|
|
302
|
+
*/
|
|
303
|
+
function MetricsView({ metrics }) {
|
|
304
|
+
if (!metrics) return /* @__PURE__ */ jsx("div", {
|
|
305
|
+
className: "text-muted-foreground flex h-64 items-center justify-center",
|
|
306
|
+
children: "Loading metrics..."
|
|
307
|
+
});
|
|
308
|
+
const completedRuns = Math.round(metrics.totalRuns * metrics.successRate);
|
|
309
|
+
const failedRuns = metrics.totalRuns - completedRuns;
|
|
310
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
311
|
+
className: "space-y-6",
|
|
312
|
+
children: [
|
|
313
|
+
/* @__PURE__ */ jsx("h3", {
|
|
314
|
+
className: "text-lg font-semibold",
|
|
315
|
+
children: "Usage Analytics"
|
|
316
|
+
}),
|
|
317
|
+
/* @__PURE__ */ jsxs("div", {
|
|
318
|
+
className: "grid gap-6 md:grid-cols-2",
|
|
319
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
320
|
+
className: "border-border bg-card rounded-xl border p-4",
|
|
321
|
+
children: [/* @__PURE__ */ jsx("h4", {
|
|
322
|
+
className: "font-medium",
|
|
323
|
+
children: "Run Outcomes"
|
|
324
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
325
|
+
className: "mt-4 space-y-3",
|
|
326
|
+
children: [/* @__PURE__ */ jsx(ProgressBar, {
|
|
327
|
+
label: "Completed",
|
|
328
|
+
value: completedRuns,
|
|
329
|
+
total: metrics.totalRuns,
|
|
330
|
+
color: "bg-green-500"
|
|
331
|
+
}), /* @__PURE__ */ jsx(ProgressBar, {
|
|
332
|
+
label: "Failed",
|
|
333
|
+
value: failedRuns,
|
|
334
|
+
total: metrics.totalRuns,
|
|
335
|
+
color: "bg-red-500"
|
|
336
|
+
})]
|
|
337
|
+
})]
|
|
338
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
339
|
+
className: "border-border bg-card rounded-xl border p-4",
|
|
340
|
+
children: [/* @__PURE__ */ jsx("h4", {
|
|
341
|
+
className: "font-medium",
|
|
342
|
+
children: "Performance"
|
|
343
|
+
}), /* @__PURE__ */ jsxs("dl", {
|
|
344
|
+
className: "mt-4 grid grid-cols-2 gap-4",
|
|
345
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", {
|
|
346
|
+
className: "text-muted-foreground text-sm",
|
|
347
|
+
children: "Avg Duration"
|
|
348
|
+
}), /* @__PURE__ */ jsxs("dd", {
|
|
349
|
+
className: "text-xl font-semibold",
|
|
350
|
+
children: [(metrics.averageDurationMs / 1e3).toFixed(1), "s"]
|
|
351
|
+
})] }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", {
|
|
352
|
+
className: "text-muted-foreground text-sm",
|
|
353
|
+
children: "Success Rate"
|
|
354
|
+
}), /* @__PURE__ */ jsxs("dd", {
|
|
355
|
+
className: "text-xl font-semibold",
|
|
356
|
+
children: [(metrics.successRate * 100).toFixed(0), "%"]
|
|
357
|
+
})] })]
|
|
358
|
+
})]
|
|
359
|
+
})]
|
|
360
|
+
}),
|
|
361
|
+
/* @__PURE__ */ jsxs("div", {
|
|
362
|
+
className: "border-border bg-card rounded-xl border p-4",
|
|
363
|
+
children: [/* @__PURE__ */ jsx("h4", {
|
|
364
|
+
className: "font-medium",
|
|
365
|
+
children: "Key Metrics"
|
|
366
|
+
}), /* @__PURE__ */ jsxs("dl", {
|
|
367
|
+
className: "mt-4 grid gap-4 sm:grid-cols-3",
|
|
368
|
+
children: [
|
|
369
|
+
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", {
|
|
370
|
+
className: "text-muted-foreground text-sm",
|
|
371
|
+
children: "Total Runs"
|
|
372
|
+
}), /* @__PURE__ */ jsx("dd", {
|
|
373
|
+
className: "text-2xl font-semibold",
|
|
374
|
+
children: metrics.totalRuns.toLocaleString()
|
|
375
|
+
})] }),
|
|
376
|
+
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", {
|
|
377
|
+
className: "text-muted-foreground text-sm",
|
|
378
|
+
children: "Total Tokens"
|
|
379
|
+
}), /* @__PURE__ */ jsxs("dd", {
|
|
380
|
+
className: "text-2xl font-semibold",
|
|
381
|
+
children: [(metrics.totalTokens / 1e3).toFixed(0), "K"]
|
|
382
|
+
})] }),
|
|
383
|
+
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", {
|
|
384
|
+
className: "text-muted-foreground text-sm",
|
|
385
|
+
children: "Cost per Run"
|
|
386
|
+
}), /* @__PURE__ */ jsxs("dd", {
|
|
387
|
+
className: "text-2xl font-semibold",
|
|
388
|
+
children: ["$", metrics.totalRuns > 0 ? (metrics.totalCostUsd / metrics.totalRuns).toFixed(4) : "0"]
|
|
389
|
+
})] })
|
|
390
|
+
]
|
|
391
|
+
})]
|
|
392
|
+
})
|
|
393
|
+
]
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
function ProgressBar({ label, value, total, color }) {
|
|
397
|
+
const pct = total > 0 ? value / total * 100 : 0;
|
|
398
|
+
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
|
|
399
|
+
className: "flex justify-between text-sm",
|
|
400
|
+
children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsxs("span", {
|
|
401
|
+
className: "text-muted-foreground",
|
|
402
|
+
children: [
|
|
403
|
+
value,
|
|
404
|
+
" (",
|
|
405
|
+
pct.toFixed(0),
|
|
406
|
+
"%)"
|
|
407
|
+
]
|
|
408
|
+
})]
|
|
409
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
410
|
+
className: "bg-muted mt-1 h-2 overflow-hidden rounded-full",
|
|
411
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
412
|
+
className: `h-full ${color}`,
|
|
413
|
+
style: { width: `${pct}%` }
|
|
414
|
+
})
|
|
415
|
+
})] });
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
//#endregion
|
|
419
|
+
export { AgentDashboard };
|
|
420
|
+
//# sourceMappingURL=AgentDashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentDashboard.js","names":[],"sources":["../../src/ui/AgentDashboard.tsx"],"sourcesContent":["'use client';\n\n/**\n * Agent Console Dashboard\n *\n * Fully integrated with ContractSpec example handlers,\n * design-system components, and command mutations.\n *\n * Commands wired:\n * - CreateAgentCommand -> Create Agent button + modal\n * - UpdateAgentCommand -> Status changes via modal\n * - ExecuteAgentCommand -> Execute agent via modal\n */\nimport { useState, useMemo, useCallback } from 'react';\nimport {\n StatCard,\n StatCardGroup,\n Button,\n} from '@contractspec/lib.design-system';\n// import { AgentListView } from './views/AgentListView';\nimport { RunListView } from './views/RunListView';\nimport { ToolRegistryView } from './views/ToolRegistryView';\nimport { useRunList, type RunMetrics } from './hooks/useRunList';\nimport { useAgentList, type Agent } from './hooks/useAgentList';\nimport { useAgentMutations } from './hooks/useAgentMutations';\nimport { CreateAgentModal } from './modals/CreateAgentModal';\nimport { AgentActionsModal } from './modals/AgentActionsModal';\n\ntype Tab = 'runs' | 'agents' | 'tools' | 'metrics';\n\nexport function AgentDashboard() {\n const [activeTab, setActiveTab] = useState<Tab>('runs');\n const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);\n const [selectedAgent, setSelectedAgent] = useState<Agent | null>(null);\n const [isAgentActionsOpen, setIsAgentActionsOpen] = useState(false);\n\n const { metrics, refetch: refetchRuns } = useRunList();\n const { refetch: refetchAgents } = useAgentList();\n\n const mutations = useAgentMutations({\n onSuccess: () => {\n refetchAgents();\n refetchRuns();\n },\n });\n\n const handleAgentClick = useCallback((agent: Agent) => {\n setSelectedAgent(agent);\n setIsAgentActionsOpen(true);\n }, []);\n\n const tabs: { id: Tab; label: string; icon: string }[] = [\n { id: 'runs', label: 'Runs', icon: '▶' },\n { id: 'agents', label: 'Agents', icon: '🤖' },\n { id: 'tools', label: 'Tools', icon: '🔧' },\n { id: 'metrics', label: 'Metrics', icon: '📊' },\n ];\n\n // Compute summary stats from metrics\n const summaryStats = useMemo(() => {\n if (!metrics) {\n return [\n { label: 'Total Runs', value: '-', hint: 'Loading...' },\n { label: 'Success Rate', value: '-', hint: '' },\n { label: 'Total Tokens', value: '-', hint: '' },\n { label: 'Total Cost', value: '-', hint: '' },\n ];\n }\n return [\n {\n label: 'Total Runs',\n value: metrics.totalRuns.toLocaleString(),\n hint: `${(metrics.successRate * 100).toFixed(0)}% success`,\n },\n {\n label: 'Success Rate',\n value: `${(metrics.successRate * 100).toFixed(0)}%`,\n hint: 'of all runs',\n },\n {\n label: 'Total Tokens',\n value:\n metrics.totalTokens >= 1000000\n ? `${(metrics.totalTokens / 1000000).toFixed(1)}M`\n : `${(metrics.totalTokens / 1000).toFixed(0)}K`,\n hint: 'This period',\n },\n {\n label: 'Total Cost',\n value: `$${metrics.totalCostUsd.toFixed(2)}`,\n hint: 'This period',\n },\n ];\n }, [metrics]);\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-2xl font-bold\">AI Agent Console</h2>\n <Button onPress={() => setIsCreateModalOpen(true)}>\n <span className=\"mr-2\">+</span> New Agent\n </Button>\n </div>\n\n {/* Summary Stats Row */}\n <StatCardGroup>\n {summaryStats.map((stat, i) => (\n <StatCard\n key={i}\n label={stat.label}\n value={stat.value}\n hint={stat.hint}\n />\n ))}\n </StatCardGroup>\n\n {/* Navigation Tabs */}\n <nav className=\"bg-muted flex gap-1 rounded-lg p-1\" role=\"tablist\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={`flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n <span>{tab.icon}</span>\n {tab.label}\n </button>\n ))}\n </nav>\n\n {/* Tab Content */}\n <div className=\"min-h-[400px]\" role=\"tabpanel\">\n {activeTab === 'runs' && <RunListView />}\n {activeTab === 'agents' && (\n <AgentListViewWithActions onAgentClick={handleAgentClick} />\n )}\n {activeTab === 'tools' && <ToolRegistryView />}\n {activeTab === 'metrics' && <MetricsView metrics={metrics} />}\n </div>\n\n {/* Create Agent Modal */}\n <CreateAgentModal\n isOpen={isCreateModalOpen}\n onClose={() => setIsCreateModalOpen(false)}\n onSubmit={async (input) => {\n await mutations.createAgent(input);\n }}\n isLoading={mutations.createState.loading}\n />\n\n {/* Agent Actions Modal */}\n <AgentActionsModal\n isOpen={isAgentActionsOpen}\n agent={selectedAgent}\n onClose={() => {\n setIsAgentActionsOpen(false);\n setSelectedAgent(null);\n }}\n onActivate={async (agentId) => {\n await mutations.activateAgent(agentId);\n }}\n onPause={async (agentId) => {\n await mutations.pauseAgent(agentId);\n }}\n onArchive={async (agentId) => {\n await mutations.archiveAgent(agentId);\n }}\n onExecute={async (agentId, message) => {\n await mutations.executeAgent({ agentId, message });\n }}\n isLoading={mutations.isLoading}\n />\n </div>\n );\n}\n\n/**\n * Agent List View with click handler\n */\nfunction AgentListViewWithActions({\n onAgentClick,\n}: {\n onAgentClick: (agent: Agent) => void;\n}) {\n const { data, loading, error, stats, refetch } = useAgentList();\n\n if (loading && !data) {\n return (\n <div className=\"text-muted-foreground flex h-64 items-center justify-center\">\n Loading agents...\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"text-destructive flex h-64 flex-col items-center justify-center\">\n <p>Failed to load agents: {error.message}</p>\n <Button variant=\"outline\" onPress={refetch} className=\"mt-2\">\n Retry\n </Button>\n </div>\n );\n }\n\n if (!data?.items.length) {\n return (\n <div className=\"text-muted-foreground flex h-64 flex-col items-center justify-center\">\n <p className=\"text-lg font-medium\">No agents yet</p>\n <p className=\"text-sm\">Create your first AI agent to get started.</p>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {/* Stats */}\n {stats && (\n <div className=\"flex gap-4 text-sm\">\n <span>Total: {stats.total}</span>\n <span className=\"text-green-600\">Active: {stats.active}</span>\n <span className=\"text-yellow-600\">Paused: {stats.paused}</span>\n <span className=\"text-blue-600\">Draft: {stats.draft}</span>\n </div>\n )}\n\n {/* Agent Grid */}\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {data.items.map((agent) => (\n <AgentCard\n key={agent.id}\n agent={agent}\n onClick={() => onAgentClick(agent)}\n />\n ))}\n </div>\n </div>\n );\n}\n\n/**\n * Agent Card Component\n */\nfunction AgentCard({ agent, onClick }: { agent: Agent; onClick: () => void }) {\n const statusColors: Record<string, string> = {\n ACTIVE:\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n DRAFT: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n PAUSED:\n 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400',\n ARCHIVED: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400',\n };\n\n return (\n <div\n onClick={onClick}\n className=\"border-border bg-card cursor-pointer rounded-xl border p-4 transition-all hover:shadow-md\"\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') onClick();\n }}\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate font-semibold\">{agent.name}</h3>\n <p className=\"text-muted-foreground text-sm\">\n {agent.modelProvider} / {agent.modelName}\n </p>\n </div>\n <span\n className={`rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[agent.status]}`}\n >\n {agent.status}\n </span>\n </div>\n {agent.description && (\n <p className=\"text-muted-foreground mt-2 line-clamp-2 text-sm\">\n {agent.description}\n </p>\n )}\n <div className=\"mt-3 flex items-center justify-between\">\n <span className=\"text-muted-foreground text-xs\">{agent.modelName}</span>\n <Button variant=\"ghost\" size=\"sm\" onPress={onClick}>\n Actions\n </Button>\n </div>\n </div>\n );\n}\n\n/**\n * Metrics View - Shows usage analytics\n */\nfunction MetricsView({ metrics }: { metrics: RunMetrics | null }) {\n if (!metrics) {\n return (\n <div className=\"text-muted-foreground flex h-64 items-center justify-center\">\n Loading metrics...\n </div>\n );\n }\n\n // Calculate derived metrics\n const completedRuns = Math.round(metrics.totalRuns * metrics.successRate);\n const failedRuns = metrics.totalRuns - completedRuns;\n\n return (\n <div className=\"space-y-6\">\n <h3 className=\"text-lg font-semibold\">Usage Analytics</h3>\n\n <div className=\"grid gap-6 md:grid-cols-2\">\n {/* Success/Failure breakdown */}\n <div className=\"border-border bg-card rounded-xl border p-4\">\n <h4 className=\"font-medium\">Run Outcomes</h4>\n <div className=\"mt-4 space-y-3\">\n <ProgressBar\n label=\"Completed\"\n value={completedRuns}\n total={metrics.totalRuns}\n color=\"bg-green-500\"\n />\n <ProgressBar\n label=\"Failed\"\n value={failedRuns}\n total={metrics.totalRuns}\n color=\"bg-red-500\"\n />\n </div>\n </div>\n\n {/* Key Stats */}\n <div className=\"border-border bg-card rounded-xl border p-4\">\n <h4 className=\"font-medium\">Performance</h4>\n <dl className=\"mt-4 grid grid-cols-2 gap-4\">\n <div>\n <dt className=\"text-muted-foreground text-sm\">Avg Duration</dt>\n <dd className=\"text-xl font-semibold\">\n {(metrics.averageDurationMs / 1000).toFixed(1)}s\n </dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground text-sm\">Success Rate</dt>\n <dd className=\"text-xl font-semibold\">\n {(metrics.successRate * 100).toFixed(0)}%\n </dd>\n </div>\n </dl>\n </div>\n </div>\n\n {/* Key Metrics */}\n <div className=\"border-border bg-card rounded-xl border p-4\">\n <h4 className=\"font-medium\">Key Metrics</h4>\n <dl className=\"mt-4 grid gap-4 sm:grid-cols-3\">\n <div>\n <dt className=\"text-muted-foreground text-sm\">Total Runs</dt>\n <dd className=\"text-2xl font-semibold\">\n {metrics.totalRuns.toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground text-sm\">Total Tokens</dt>\n <dd className=\"text-2xl font-semibold\">\n {(metrics.totalTokens / 1000).toFixed(0)}K\n </dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground text-sm\">Cost per Run</dt>\n <dd className=\"text-2xl font-semibold\">\n $\n {metrics.totalRuns > 0\n ? (metrics.totalCostUsd / metrics.totalRuns).toFixed(4)\n : '0'}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n );\n}\n\nfunction ProgressBar({\n label,\n value,\n total,\n color,\n}: {\n label: string;\n value: number;\n total: number;\n color: string;\n}) {\n const pct = total > 0 ? (value / total) * 100 : 0;\n return (\n <div>\n <div className=\"flex justify-between text-sm\">\n <span>{label}</span>\n <span className=\"text-muted-foreground\">\n {value} ({pct.toFixed(0)}%)\n </span>\n </div>\n <div className=\"bg-muted mt-1 h-2 overflow-hidden rounded-full\">\n <div className={`h-full ${color}`} style={{ width: `${pct}%` }} />\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CreateAgentInput, UpdateAgentInput } from "../../handlers/agent.handlers.js";
|
|
2
|
+
import { UseAgentListOptions, useAgentList } from "./useAgentList.js";
|
|
3
|
+
import { UseRunListOptions, useRunList } from "./useRunList.js";
|
|
4
|
+
import { UseToolListOptions, useToolList } from "./useToolList.js";
|
|
5
|
+
import { UseAgentMutationsOptions, useAgentMutations } from "./useAgentMutations.js";
|
|
6
|
+
export { type CreateAgentInput, type UpdateAgentInput, type UseAgentListOptions, type UseAgentMutationsOptions, type UseRunListOptions, type UseToolListOptions, useAgentList, useAgentMutations, useRunList, useToolList };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useRunList } from "./useRunList.js";
|
|
4
|
+
import { useToolList } from "./useToolList.js";
|
|
5
|
+
import { useAgentList } from "./useAgentList.js";
|
|
6
|
+
import { useAgentMutations } from "./useAgentMutations.js";
|
|
7
|
+
|
|
8
|
+
export { useAgentList, useAgentMutations, useRunList, useToolList };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Agent as Agent$1, ListAgentsOutput as ListAgentsOutput$1 } from "../../handlers/agent.handlers.js";
|
|
2
|
+
|
|
3
|
+
//#region src/ui/hooks/useAgentList.d.ts
|
|
4
|
+
type Agent = Agent$1;
|
|
5
|
+
type ListAgentsOutput = ListAgentsOutput$1;
|
|
6
|
+
interface UseAgentListOptions {
|
|
7
|
+
search?: string;
|
|
8
|
+
status?: 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'ARCHIVED' | 'all';
|
|
9
|
+
limit?: number;
|
|
10
|
+
}
|
|
11
|
+
declare function useAgentList(options?: UseAgentListOptions): {
|
|
12
|
+
data: ListAgentsOutput$1 | null;
|
|
13
|
+
loading: boolean;
|
|
14
|
+
error: Error | null;
|
|
15
|
+
stats: {
|
|
16
|
+
total: number;
|
|
17
|
+
active: number;
|
|
18
|
+
paused: number;
|
|
19
|
+
draft: number;
|
|
20
|
+
} | null;
|
|
21
|
+
page: number;
|
|
22
|
+
refetch: () => Promise<void>;
|
|
23
|
+
nextPage: () => void;
|
|
24
|
+
prevPage: () => false | void;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { Agent, ListAgentsOutput, UseAgentListOptions, useAgentList };
|
|
28
|
+
//# sourceMappingURL=useAgentList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAgentList.d.ts","names":[],"sources":["../../../src/ui/hooks/useAgentList.ts"],"sourcesContent":[],"mappings":";;;KAcY,KAAA,GAAQ;KACR,gBAAA,GAAmB;AADnB,UAGK,mBAAA,CAHe;EACpB,MAAA,CAAA,EAAA,MAAA;EAEK,MAAA,CAAA,EAAA,OAAA,GAAA,QAAmB,GAAA,QAAA,GAAA,UAAA,GAAA,KAAA;EAMpB,KAAA,CAAA,EAAA,MAAA;;iBAAA,YAAA,WAAsB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
|
|
3
|
+
|
|
4
|
+
//#region src/ui/hooks/useAgentList.ts
|
|
5
|
+
/**
|
|
6
|
+
* Hook for fetching and managing agent list data
|
|
7
|
+
*
|
|
8
|
+
* Uses runtime-local database-backed handlers.
|
|
9
|
+
*/
|
|
10
|
+
function useAgentList(options = {}) {
|
|
11
|
+
const { handlers, projectId } = useTemplateRuntime();
|
|
12
|
+
const { agent } = handlers;
|
|
13
|
+
const [data, setData] = useState(null);
|
|
14
|
+
const [loading, setLoading] = useState(true);
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
const [page, setPage] = useState(1);
|
|
17
|
+
const fetchData = useCallback(async () => {
|
|
18
|
+
setLoading(true);
|
|
19
|
+
setError(null);
|
|
20
|
+
try {
|
|
21
|
+
setData(await agent.listAgents({
|
|
22
|
+
projectId,
|
|
23
|
+
search: options.search,
|
|
24
|
+
status: options.status === "all" ? void 0 : options.status,
|
|
25
|
+
limit: options.limit ?? 20,
|
|
26
|
+
offset: (page - 1) * (options.limit ?? 20)
|
|
27
|
+
}));
|
|
28
|
+
} catch (err) {
|
|
29
|
+
setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error"));
|
|
30
|
+
} finally {
|
|
31
|
+
setLoading(false);
|
|
32
|
+
}
|
|
33
|
+
}, [
|
|
34
|
+
agent,
|
|
35
|
+
projectId,
|
|
36
|
+
options.search,
|
|
37
|
+
options.status,
|
|
38
|
+
options.limit,
|
|
39
|
+
page
|
|
40
|
+
]);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
fetchData();
|
|
43
|
+
}, [fetchData]);
|
|
44
|
+
return {
|
|
45
|
+
data,
|
|
46
|
+
loading,
|
|
47
|
+
error,
|
|
48
|
+
stats: useMemo(() => {
|
|
49
|
+
if (!data) return null;
|
|
50
|
+
return {
|
|
51
|
+
total: data.total,
|
|
52
|
+
active: data.items.filter((a) => a.status === "ACTIVE").length,
|
|
53
|
+
paused: data.items.filter((a) => a.status === "PAUSED").length,
|
|
54
|
+
draft: data.items.filter((a) => a.status === "DRAFT").length
|
|
55
|
+
};
|
|
56
|
+
}, [data]),
|
|
57
|
+
page,
|
|
58
|
+
refetch: fetchData,
|
|
59
|
+
nextPage: () => setPage((p) => p + 1),
|
|
60
|
+
prevPage: () => page > 1 && setPage((p) => p - 1)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
export { useAgentList };
|
|
66
|
+
//# sourceMappingURL=useAgentList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAgentList.js","names":[],"sources":["../../../src/ui/hooks/useAgentList.ts"],"sourcesContent":["/**\n * Hook for fetching and managing agent list data\n *\n * Uses runtime-local database-backed handlers.\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useTemplateRuntime } from '@contractspec/lib.example-shared-ui';\nimport type {\n Agent as RuntimeAgent,\n ListAgentsOutput as RuntimeListAgentsOutput,\n} from '../../handlers/agent.handlers';\nimport type { AgentHandlers } from '../../handlers/agent.handlers';\n\n// Re-export types for convenience\nexport type Agent = RuntimeAgent;\nexport type ListAgentsOutput = RuntimeListAgentsOutput;\n\nexport interface UseAgentListOptions {\n search?: string;\n status?: 'DRAFT' | 'ACTIVE' | 'PAUSED' | 'ARCHIVED' | 'all';\n limit?: number;\n}\n\nexport function useAgentList(options: UseAgentListOptions = {}) {\n const { handlers, projectId } = useTemplateRuntime<{\n agent: AgentHandlers;\n }>();\n const { agent } = handlers;\n\n const [data, setData] = useState<ListAgentsOutput | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [page, setPage] = useState(1);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n const result = await agent.listAgents({\n projectId,\n search: options.search,\n status: options.status === 'all' ? undefined : options.status,\n limit: options.limit ?? 20,\n offset: (page - 1) * (options.limit ?? 20),\n });\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Unknown error'));\n } finally {\n setLoading(false);\n }\n }, [agent, projectId, options.search, options.status, options.limit, page]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n // Calculate stats\n const stats = useMemo(() => {\n if (!data) return null;\n return {\n total: data.total,\n active: data.items.filter((a) => a.status === 'ACTIVE').length,\n paused: data.items.filter((a) => a.status === 'PAUSED').length,\n draft: data.items.filter((a) => a.status === 'DRAFT').length,\n };\n }, [data]);\n\n return {\n data,\n loading,\n error,\n stats,\n page,\n refetch: fetchData,\n nextPage: () => setPage((p) => p + 1),\n prevPage: () => page > 1 && setPage((p) => p - 1),\n };\n}\n"],"mappings":";;;;;;;;;AAuBA,SAAgB,aAAa,UAA+B,EAAE,EAAE;CAC9D,MAAM,EAAE,UAAU,cAAc,oBAE5B;CACJ,MAAM,EAAE,UAAU;CAElB,MAAM,CAAC,MAAM,WAAW,SAAkC,KAAK;CAC/D,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,CAAC,OAAO,YAAY,SAAuB,KAAK;CACtD,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CAEnC,MAAM,YAAY,YAAY,YAAY;AACxC,aAAW,KAAK;AAChB,WAAS,KAAK;AAEd,MAAI;AAQF,WAPe,MAAM,MAAM,WAAW;IACpC;IACA,QAAQ,QAAQ;IAChB,QAAQ,QAAQ,WAAW,QAAQ,SAAY,QAAQ;IACvD,OAAO,QAAQ,SAAS;IACxB,SAAS,OAAO,MAAM,QAAQ,SAAS;IACxC,CAAC,CACa;WACR,KAAK;AACZ,YAAS,eAAe,QAAQ,sBAAM,IAAI,MAAM,gBAAgB,CAAC;YACzD;AACR,cAAW,MAAM;;IAElB;EAAC;EAAO;EAAW,QAAQ;EAAQ,QAAQ;EAAQ,QAAQ;EAAO;EAAK,CAAC;AAE3E,iBAAgB;AACd,aAAW;IACV,CAAC,UAAU,CAAC;AAaf,QAAO;EACL;EACA;EACA;EACA,OAdY,cAAc;AAC1B,OAAI,CAAC,KAAM,QAAO;AAClB,UAAO;IACL,OAAO,KAAK;IACZ,QAAQ,KAAK,MAAM,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC;IACxD,QAAQ,KAAK,MAAM,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC;IACxD,OAAO,KAAK,MAAM,QAAQ,MAAM,EAAE,WAAW,QAAQ,CAAC;IACvD;KACA,CAAC,KAAK,CAAC;EAOR;EACA,SAAS;EACT,gBAAgB,SAAS,MAAM,IAAI,EAAE;EACrC,gBAAgB,OAAO,KAAK,SAAS,MAAM,IAAI,EAAE;EAClD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Agent, CreateAgentInput, UpdateAgentInput } from "../../handlers/agent.handlers.js";
|
|
2
|
+
|
|
3
|
+
//#region src/ui/hooks/useAgentMutations.d.ts
|
|
4
|
+
interface MutationState<T> {
|
|
5
|
+
loading: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
data: T | null;
|
|
8
|
+
}
|
|
9
|
+
interface UseAgentMutationsOptions {
|
|
10
|
+
onSuccess?: () => void;
|
|
11
|
+
onError?: (error: Error) => void;
|
|
12
|
+
}
|
|
13
|
+
declare function useAgentMutations(options?: UseAgentMutationsOptions): {
|
|
14
|
+
createAgent: (input: CreateAgentInput) => Promise<Agent | null>;
|
|
15
|
+
updateAgent: (input: UpdateAgentInput) => Promise<Agent | null>;
|
|
16
|
+
activateAgent: (agentId: string) => Promise<Agent | null>;
|
|
17
|
+
pauseAgent: (agentId: string) => Promise<Agent | null>;
|
|
18
|
+
archiveAgent: (agentId: string) => Promise<Agent | null>;
|
|
19
|
+
executeAgent: (input: {
|
|
20
|
+
agentId: string;
|
|
21
|
+
message: string;
|
|
22
|
+
}) => Promise<null>;
|
|
23
|
+
createState: MutationState<Agent>;
|
|
24
|
+
updateState: MutationState<Agent>;
|
|
25
|
+
isLoading: boolean;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { type Agent, type CreateAgentInput, MutationState, type UpdateAgentInput, UseAgentMutationsOptions, useAgentMutations };
|
|
29
|
+
//# sourceMappingURL=useAgentMutations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAgentMutations.d.ts","names":[],"sources":["../../../src/ui/hooks/useAgentMutations.ts"],"sourcesContent":[],"mappings":";;;UAgBiB;;EAAA,KAAA,EAER,KAFQ,GAAA,IAAa;EAMb,IAAA,EAHT,CAGS,GAAA,IAAA;AAKjB;AAA2C,UAL1B,wBAAA,CAK0B;EAsBzB,SAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAA2B,OAAA,CAAA,EAAA,CAAA,KAAA,EAzBzB,KAyByB,EAAA,GAAA,IAAA;;AAyB3B,iBA/CF,iBAAA,CA+CE,OAAA,CAAA,EA/CyB,wBA+CzB,CAAA,EAAA;EAA2B,WAAA,EAAA,CAAA,KAAA,EAzB3B,gBAyB2B,EAAA,GAzBR,OAyBQ,CAzBA,KAyBA,GAAA,IAAA,CAAA;EAAR,WAAA,EAAA,CAAA,KAAA,EAAnB,gBAAmB,EAAA,GAAA,OAAA,CAAQ,KAAR,GAAA,IAAA,CAAA;EAsBA,aAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAAR,OAAQ,CAAA,KAAA,GAAA,IAAA,CAAA;EAAR,UAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAUA,OAVA,CAUQ,KAVR,GAAA,IAAA,CAAA;EAUQ,YAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAUR,OAVQ,CAUA,KAVA,GAAA,IAAA,CAAA;EAAR,YAAA,EAAA,CAAA,KAAA,EAAA;IAUQ,OAAA,EAAA,MAAA;IAAR,OAAA,EAAA,MAAA;EAW4B,CAAA,EAAA,GAAA,OAAA,CAAA,IAAA,CAAA"}
|