@contractspec/example.agent-console 3.7.5 → 3.7.7
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.log +18 -18
- package/AGENTS.md +50 -31
- package/CHANGELOG.md +12 -0
- package/README.md +69 -77
- package/dist/agent/agent.event.js +1 -1
- package/dist/agent/agent.operation.js +1 -1
- package/dist/agent/index.d.ts +5 -5
- package/dist/agent/index.js +1 -1
- package/dist/browser/agent/agent.event.js +1 -1
- package/dist/browser/agent/agent.operation.js +1 -1
- package/dist/browser/agent/index.js +1 -1
- package/dist/browser/index.js +2145 -2145
- package/dist/browser/presentations/index.js +4 -4
- package/dist/browser/run/index.js +536 -536
- package/dist/browser/run/run.event.js +2 -2
- package/dist/browser/run/run.presentation.js +2 -2
- package/dist/browser/tool/index.js +260 -260
- package/dist/browser/tool/tool.event.js +1 -1
- package/dist/browser/tool/tool.presentation.js +2 -2
- package/dist/browser/ui/AgentDashboard.js +956 -956
- package/dist/browser/ui/AgentRunList.js +16 -16
- package/dist/browser/ui/AgentToolRegistry.js +9 -9
- package/dist/browser/ui/hooks/index.js +153 -153
- package/dist/browser/ui/hooks/useAgentList.js +1 -1
- package/dist/browser/ui/hooks/useAgentMutations.js +1 -1
- package/dist/browser/ui/hooks/useRunList.js +1 -1
- package/dist/browser/ui/hooks/useToolList.js +1 -1
- package/dist/browser/ui/index.js +1222 -1222
- package/dist/browser/ui/modals/AgentActionsModal.js +13 -13
- package/dist/browser/ui/modals/CreateAgentModal.js +15 -15
- package/dist/browser/ui/modals/index.js +297 -297
- package/dist/browser/ui/renderers/agent-list.renderer.js +7 -7
- package/dist/browser/ui/renderers/index.js +157 -157
- package/dist/browser/ui/views/AgentListView.js +7 -7
- package/dist/browser/ui/views/RunListView.js +16 -16
- package/dist/browser/ui/views/ToolRegistryView.js +9 -9
- package/dist/browser/ui/views/index.js +97 -97
- package/dist/handlers/index.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2145 -2145
- package/dist/node/agent/agent.event.js +1 -1
- package/dist/node/agent/agent.operation.js +1 -1
- package/dist/node/agent/index.js +1 -1
- package/dist/node/index.js +2145 -2145
- package/dist/node/presentations/index.js +4 -4
- package/dist/node/run/index.js +536 -536
- package/dist/node/run/run.event.js +2 -2
- package/dist/node/run/run.presentation.js +2 -2
- package/dist/node/tool/index.js +260 -260
- package/dist/node/tool/tool.event.js +1 -1
- package/dist/node/tool/tool.presentation.js +2 -2
- package/dist/node/ui/AgentDashboard.js +956 -956
- package/dist/node/ui/AgentRunList.js +16 -16
- package/dist/node/ui/AgentToolRegistry.js +9 -9
- package/dist/node/ui/hooks/index.js +153 -153
- package/dist/node/ui/hooks/useAgentList.js +1 -1
- package/dist/node/ui/hooks/useAgentMutations.js +1 -1
- package/dist/node/ui/hooks/useRunList.js +1 -1
- package/dist/node/ui/hooks/useToolList.js +1 -1
- package/dist/node/ui/index.js +1222 -1222
- package/dist/node/ui/modals/AgentActionsModal.js +13 -13
- package/dist/node/ui/modals/CreateAgentModal.js +15 -15
- package/dist/node/ui/modals/index.js +297 -297
- package/dist/node/ui/renderers/agent-list.renderer.js +7 -7
- package/dist/node/ui/renderers/index.js +157 -157
- package/dist/node/ui/views/AgentListView.js +7 -7
- package/dist/node/ui/views/RunListView.js +16 -16
- package/dist/node/ui/views/ToolRegistryView.js +9 -9
- package/dist/node/ui/views/index.js +97 -97
- package/dist/presentations/index.d.ts +3 -5
- package/dist/presentations/index.js +4 -4
- package/dist/run/index.d.ts +7 -7
- package/dist/run/index.js +536 -536
- package/dist/run/run.event.js +2 -2
- package/dist/run/run.handler.d.ts +3 -0
- package/dist/run/run.presentation.js +2 -2
- package/dist/shared/index.d.ts +1 -1
- package/dist/tool/index.d.ts +7 -7
- package/dist/tool/index.js +260 -260
- package/dist/tool/tool.event.js +1 -1
- package/dist/tool/tool.handler.d.ts +1 -1
- package/dist/tool/tool.presentation.js +2 -2
- package/dist/ui/AgentDashboard.js +956 -956
- package/dist/ui/AgentRunList.js +16 -16
- package/dist/ui/AgentToolRegistry.js +9 -9
- package/dist/ui/hooks/index.d.ts +4 -4
- package/dist/ui/hooks/index.js +153 -153
- package/dist/ui/hooks/useAgentList.d.ts +5 -0
- package/dist/ui/hooks/useAgentList.js +1 -1
- package/dist/ui/hooks/useAgentMutations.d.ts +9 -2
- package/dist/ui/hooks/useAgentMutations.js +1 -1
- package/dist/ui/hooks/useRunList.d.ts +5 -0
- package/dist/ui/hooks/useRunList.js +1 -1
- package/dist/ui/hooks/useToolList.d.ts +5 -0
- package/dist/ui/hooks/useToolList.js +1 -1
- package/dist/ui/index.d.ts +3 -3
- package/dist/ui/index.js +1222 -1222
- package/dist/ui/modals/AgentActionsModal.js +13 -13
- package/dist/ui/modals/CreateAgentModal.js +15 -15
- package/dist/ui/modals/index.d.ts +1 -1
- package/dist/ui/modals/index.js +297 -297
- package/dist/ui/renderers/agent-list.markdown.d.ts +5 -0
- package/dist/ui/renderers/agent-list.renderer.js +7 -7
- package/dist/ui/renderers/dashboard.markdown.d.ts +5 -0
- package/dist/ui/renderers/index.d.ts +2 -2
- package/dist/ui/renderers/index.js +157 -157
- package/dist/ui/renderers/run-list.markdown.d.ts +5 -0
- package/dist/ui/renderers/tool-registry.markdown.d.ts +5 -0
- package/dist/ui/views/AgentListView.js +7 -7
- package/dist/ui/views/RunListView.js +16 -16
- package/dist/ui/views/ToolRegistryView.js +9 -9
- package/dist/ui/views/index.js +97 -97
- package/package.json +10 -10
- package/src/agent/agent.entity.ts +111 -111
- package/src/agent/agent.enum.ts +12 -12
- package/src/agent/agent.event.ts +91 -91
- package/src/agent/agent.handler.ts +123 -123
- package/src/agent/agent.operation.ts +400 -400
- package/src/agent/agent.presentation.ts +62 -62
- package/src/agent/agent.schema.ts +175 -175
- package/src/agent/agent.test-spec.ts +48 -48
- package/src/agent/index.ts +46 -51
- package/src/agent.capability.ts +11 -11
- package/src/agent.feature.ts +131 -131
- package/src/docs/agent-console.docblock.ts +42 -42
- package/src/example.ts +35 -35
- package/src/handlers/agent.handlers.ts +522 -521
- package/src/handlers/index.ts +12 -12
- package/src/index.ts +8 -9
- package/src/presentations/index.ts +11 -13
- package/src/run/index.ts +49 -54
- package/src/run/run.entity.ts +137 -137
- package/src/run/run.enum.ts +18 -18
- package/src/run/run.event.ts +174 -174
- package/src/run/run.handler.ts +92 -91
- package/src/run/run.operation.ts +474 -474
- package/src/run/run.presentation.ts +42 -42
- package/src/run/run.schema.ts +126 -126
- package/src/run/run.test-spec.ts +48 -48
- package/src/seeders/index.ts +21 -21
- package/src/shared/index.ts +1 -1
- package/src/shared/mock-agents.ts +76 -76
- package/src/shared/mock-runs.ts +102 -102
- package/src/shared/mock-tools.ts +140 -140
- package/src/shared/overlay-types.ts +23 -23
- package/src/tool/index.ts +39 -44
- package/src/tool/tool.entity.ts +73 -73
- package/src/tool/tool.enum.ts +13 -13
- package/src/tool/tool.event.ts +80 -80
- package/src/tool/tool.handler.ts +102 -102
- package/src/tool/tool.operation.ts +328 -328
- package/src/tool/tool.presentation.ts +43 -43
- package/src/tool/tool.schema.ts +106 -106
- package/src/tool/tool.test-spec.ts +48 -48
- package/src/ui/AgentDashboard.tsx +348 -348
- package/src/ui/hooks/index.ts +7 -7
- package/src/ui/hooks/useAgentList.ts +57 -56
- package/src/ui/hooks/useAgentMutations.ts +160 -159
- package/src/ui/hooks/useRunList.ts +58 -57
- package/src/ui/hooks/useToolList.ts +102 -101
- package/src/ui/index.ts +6 -9
- package/src/ui/modals/AgentActionsModal.tsx +262 -262
- package/src/ui/modals/CreateAgentModal.tsx +232 -232
- package/src/ui/modals/index.ts +1 -1
- package/src/ui/overlays/demo-overlays.ts +52 -52
- package/src/ui/renderers/agent-list.markdown.ts +61 -60
- package/src/ui/renderers/agent-list.renderer.tsx +14 -14
- package/src/ui/renderers/dashboard.markdown.ts +140 -139
- package/src/ui/renderers/index.ts +3 -4
- package/src/ui/renderers/run-list.markdown.ts +48 -47
- package/src/ui/renderers/tool-registry.markdown.ts +66 -65
- package/src/ui/views/AgentListView.tsx +90 -90
- package/src/ui/views/RunListView.tsx +141 -141
- package/src/ui/views/ToolRegistryView.tsx +113 -113
- package/tsconfig.json +7 -8
- package/tsdown.config.js +7 -3
|
@@ -1,15 +1,161 @@
|
|
|
1
|
-
// src/ui/hooks/
|
|
2
|
-
import { useCallback, useEffect, useState } from "react";
|
|
1
|
+
// src/ui/hooks/useAgentList.ts
|
|
3
2
|
import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
|
|
4
|
-
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
+
function useAgentList(options = {}) {
|
|
5
5
|
const { handlers, projectId } = useTemplateRuntime();
|
|
6
6
|
const { agent } = handlers;
|
|
7
7
|
const [data, setData] = useState(null);
|
|
8
|
-
const [metrics, setMetrics] = useState(null);
|
|
9
8
|
const [loading, setLoading] = useState(true);
|
|
10
9
|
const [error, setError] = useState(null);
|
|
11
10
|
const [page, setPage] = useState(1);
|
|
12
11
|
const fetchData = useCallback(async () => {
|
|
12
|
+
setLoading(true);
|
|
13
|
+
setError(null);
|
|
14
|
+
try {
|
|
15
|
+
const result = await agent.listAgents({
|
|
16
|
+
projectId,
|
|
17
|
+
search: options.search,
|
|
18
|
+
status: options.status === "all" ? undefined : options.status,
|
|
19
|
+
limit: options.limit ?? 20,
|
|
20
|
+
offset: (page - 1) * (options.limit ?? 20)
|
|
21
|
+
});
|
|
22
|
+
setData(result);
|
|
23
|
+
} catch (err) {
|
|
24
|
+
setError(err instanceof Error ? err : new Error("Unknown error"));
|
|
25
|
+
} finally {
|
|
26
|
+
setLoading(false);
|
|
27
|
+
}
|
|
28
|
+
}, [agent, projectId, options.search, options.status, options.limit, page]);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
fetchData();
|
|
31
|
+
}, [fetchData]);
|
|
32
|
+
const stats = useMemo(() => {
|
|
33
|
+
if (!data)
|
|
34
|
+
return null;
|
|
35
|
+
return {
|
|
36
|
+
total: data.total,
|
|
37
|
+
active: data.items.filter((a) => a.status === "ACTIVE").length,
|
|
38
|
+
paused: data.items.filter((a) => a.status === "PAUSED").length,
|
|
39
|
+
draft: data.items.filter((a) => a.status === "DRAFT").length
|
|
40
|
+
};
|
|
41
|
+
}, [data]);
|
|
42
|
+
return {
|
|
43
|
+
data,
|
|
44
|
+
loading,
|
|
45
|
+
error,
|
|
46
|
+
stats,
|
|
47
|
+
page,
|
|
48
|
+
refetch: fetchData,
|
|
49
|
+
nextPage: () => setPage((p) => p + 1),
|
|
50
|
+
prevPage: () => page > 1 && setPage((p) => p - 1)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/ui/hooks/useAgentMutations.ts
|
|
55
|
+
import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
|
|
56
|
+
import { useCallback as useCallback2, useState as useState2 } from "react";
|
|
57
|
+
function useAgentMutations(options = {}) {
|
|
58
|
+
const { handlers, projectId } = useTemplateRuntime2();
|
|
59
|
+
const { agent } = handlers;
|
|
60
|
+
const [createState, setCreateState] = useState2({
|
|
61
|
+
loading: false,
|
|
62
|
+
error: null,
|
|
63
|
+
data: null
|
|
64
|
+
});
|
|
65
|
+
const [updateState, setUpdateState] = useState2({
|
|
66
|
+
loading: false,
|
|
67
|
+
error: null,
|
|
68
|
+
data: null
|
|
69
|
+
});
|
|
70
|
+
const [executeState, setExecuteState] = useState2({
|
|
71
|
+
loading: false,
|
|
72
|
+
error: null,
|
|
73
|
+
data: null
|
|
74
|
+
});
|
|
75
|
+
const createAgent = useCallback2(async (input) => {
|
|
76
|
+
setCreateState({ loading: true, error: null, data: null });
|
|
77
|
+
try {
|
|
78
|
+
const result = await agent.createAgent(input, {
|
|
79
|
+
projectId,
|
|
80
|
+
organizationId: "demo-org"
|
|
81
|
+
});
|
|
82
|
+
setCreateState({ loading: false, error: null, data: result });
|
|
83
|
+
options.onSuccess?.();
|
|
84
|
+
return result;
|
|
85
|
+
} catch (err) {
|
|
86
|
+
const error = err instanceof Error ? err : new Error("Failed to create agent");
|
|
87
|
+
setCreateState({ loading: false, error, data: null });
|
|
88
|
+
options.onError?.(error);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}, [agent, projectId, options]);
|
|
92
|
+
const updateAgent = useCallback2(async (input) => {
|
|
93
|
+
setUpdateState({ loading: true, error: null, data: null });
|
|
94
|
+
try {
|
|
95
|
+
const result = await agent.updateAgent(input);
|
|
96
|
+
setUpdateState({ loading: false, error: null, data: result });
|
|
97
|
+
options.onSuccess?.();
|
|
98
|
+
return result;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
const error = err instanceof Error ? err : new Error("Failed to update agent");
|
|
101
|
+
setUpdateState({ loading: false, error, data: null });
|
|
102
|
+
options.onError?.(error);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}, [agent, options]);
|
|
106
|
+
const activateAgent = useCallback2(async (agentId) => {
|
|
107
|
+
return updateAgent({ id: agentId, status: "ACTIVE" });
|
|
108
|
+
}, [updateAgent]);
|
|
109
|
+
const pauseAgent = useCallback2(async (agentId) => {
|
|
110
|
+
return updateAgent({ id: agentId, status: "PAUSED" });
|
|
111
|
+
}, [updateAgent]);
|
|
112
|
+
const archiveAgent = useCallback2(async (agentId) => {
|
|
113
|
+
return updateAgent({ id: agentId, status: "ARCHIVED" });
|
|
114
|
+
}, [updateAgent]);
|
|
115
|
+
const executeAgent = useCallback2(async (input) => {
|
|
116
|
+
setExecuteState({ loading: true, error: null, data: null });
|
|
117
|
+
try {
|
|
118
|
+
const result = await agent.executeAgent({
|
|
119
|
+
agentId: input.agentId,
|
|
120
|
+
message: input.message,
|
|
121
|
+
context: { projectId, organizationId: "demo-org" }
|
|
122
|
+
});
|
|
123
|
+
setExecuteState({ loading: false, error: null, data: result });
|
|
124
|
+
options.onSuccess?.();
|
|
125
|
+
return result;
|
|
126
|
+
} catch (err) {
|
|
127
|
+
const error = err instanceof Error ? err : new Error("Failed to execute agent");
|
|
128
|
+
setExecuteState({ loading: false, error, data: null });
|
|
129
|
+
options.onError?.(error);
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}, [agent, projectId, options]);
|
|
133
|
+
return {
|
|
134
|
+
createAgent,
|
|
135
|
+
updateAgent,
|
|
136
|
+
activateAgent,
|
|
137
|
+
pauseAgent,
|
|
138
|
+
archiveAgent,
|
|
139
|
+
executeAgent,
|
|
140
|
+
createState,
|
|
141
|
+
updateState,
|
|
142
|
+
executeState,
|
|
143
|
+
isLoading: createState.loading || updateState.loading || executeState.loading
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/ui/hooks/useRunList.ts
|
|
148
|
+
import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
|
|
149
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useState as useState3 } from "react";
|
|
150
|
+
function useRunList(options = {}) {
|
|
151
|
+
const { handlers, projectId } = useTemplateRuntime3();
|
|
152
|
+
const { agent } = handlers;
|
|
153
|
+
const [data, setData] = useState3(null);
|
|
154
|
+
const [metrics, setMetrics] = useState3(null);
|
|
155
|
+
const [loading, setLoading] = useState3(true);
|
|
156
|
+
const [error, setError] = useState3(null);
|
|
157
|
+
const [page, setPage] = useState3(1);
|
|
158
|
+
const fetchData = useCallback3(async () => {
|
|
13
159
|
setLoading(true);
|
|
14
160
|
setError(null);
|
|
15
161
|
try {
|
|
@@ -36,7 +182,7 @@ function useRunList(options = {}) {
|
|
|
36
182
|
setLoading(false);
|
|
37
183
|
}
|
|
38
184
|
}, [agent, projectId, options.agentId, options.status, options.limit, page]);
|
|
39
|
-
|
|
185
|
+
useEffect2(() => {
|
|
40
186
|
fetchData();
|
|
41
187
|
}, [fetchData]);
|
|
42
188
|
return {
|
|
@@ -51,555 +197,312 @@ function useRunList(options = {}) {
|
|
|
51
197
|
};
|
|
52
198
|
}
|
|
53
199
|
|
|
54
|
-
// src/ui/
|
|
55
|
-
import {
|
|
56
|
-
|
|
57
|
-
StatCardGroup,
|
|
58
|
-
StatusChip,
|
|
59
|
-
EmptyState,
|
|
60
|
-
LoaderBlock,
|
|
61
|
-
ErrorState
|
|
62
|
-
} from "@contractspec/lib.design-system";
|
|
200
|
+
// src/ui/modals/AgentActionsModal.tsx
|
|
201
|
+
import { Button } from "@contractspec/lib.design-system";
|
|
202
|
+
import { useState as useState4 } from "react";
|
|
63
203
|
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
64
204
|
"use client";
|
|
65
|
-
function
|
|
205
|
+
function getStatusColor(status) {
|
|
66
206
|
switch (status) {
|
|
67
|
-
case "
|
|
68
|
-
return "
|
|
69
|
-
case "
|
|
70
|
-
return "
|
|
71
|
-
case "
|
|
72
|
-
return "
|
|
73
|
-
case "
|
|
74
|
-
|
|
75
|
-
return "danger";
|
|
207
|
+
case "ACTIVE":
|
|
208
|
+
return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
|
|
209
|
+
case "DRAFT":
|
|
210
|
+
return "text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30";
|
|
211
|
+
case "PAUSED":
|
|
212
|
+
return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
|
|
213
|
+
case "ARCHIVED":
|
|
214
|
+
return "text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700";
|
|
76
215
|
default:
|
|
77
|
-
return "
|
|
216
|
+
return "text-gray-600 bg-gray-100";
|
|
78
217
|
}
|
|
79
218
|
}
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
if (error) {
|
|
109
|
-
return /* @__PURE__ */ jsxDEV(ErrorState, {
|
|
110
|
-
title: "Failed to load runs",
|
|
111
|
-
description: error.message,
|
|
112
|
-
onRetry: refetch,
|
|
113
|
-
retryLabel: "Retry"
|
|
114
|
-
}, undefined, false, undefined, this);
|
|
115
|
-
}
|
|
116
|
-
if (!data?.items.length) {
|
|
117
|
-
return /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
118
|
-
title: "No runs yet",
|
|
119
|
-
description: "Execute an agent to see run history here."
|
|
120
|
-
}, undefined, false, undefined, this);
|
|
121
|
-
}
|
|
122
|
-
return /* @__PURE__ */ jsxDEV("div", {
|
|
123
|
-
className: "space-y-6",
|
|
124
|
-
children: [
|
|
125
|
-
metrics && /* @__PURE__ */ jsxDEV(StatCardGroup, {
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ jsxDEV(StatCard, {
|
|
128
|
-
label: "Total Runs",
|
|
129
|
-
value: metrics.totalRuns
|
|
130
|
-
}, undefined, false, undefined, this),
|
|
131
|
-
/* @__PURE__ */ jsxDEV(StatCard, {
|
|
132
|
-
label: "Success Rate",
|
|
133
|
-
value: `${(metrics.successRate * 100).toFixed(1)}%`
|
|
134
|
-
}, undefined, false, undefined, this),
|
|
135
|
-
/* @__PURE__ */ jsxDEV(StatCard, {
|
|
136
|
-
label: "Total Tokens",
|
|
137
|
-
value: formatTokens(metrics.totalTokens)
|
|
138
|
-
}, undefined, false, undefined, this),
|
|
139
|
-
/* @__PURE__ */ jsxDEV(StatCard, {
|
|
140
|
-
label: "Total Cost",
|
|
141
|
-
value: `$${metrics.totalCostUsd.toFixed(2)}`
|
|
142
|
-
}, undefined, false, undefined, this)
|
|
143
|
-
]
|
|
144
|
-
}, undefined, true, undefined, this),
|
|
145
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
146
|
-
className: "border-border rounded-lg border",
|
|
147
|
-
children: /* @__PURE__ */ jsxDEV("table", {
|
|
148
|
-
className: "w-full",
|
|
149
|
-
children: [
|
|
150
|
-
/* @__PURE__ */ jsxDEV("thead", {
|
|
151
|
-
className: "border-border bg-muted/30 border-b",
|
|
152
|
-
children: /* @__PURE__ */ jsxDEV("tr", {
|
|
153
|
-
children: [
|
|
154
|
-
/* @__PURE__ */ jsxDEV("th", {
|
|
155
|
-
className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
|
|
156
|
-
children: "Run"
|
|
157
|
-
}, undefined, false, undefined, this),
|
|
158
|
-
/* @__PURE__ */ jsxDEV("th", {
|
|
159
|
-
className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
|
|
160
|
-
children: "Agent"
|
|
161
|
-
}, undefined, false, undefined, this),
|
|
162
|
-
/* @__PURE__ */ jsxDEV("th", {
|
|
163
|
-
className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
|
|
164
|
-
children: "Status"
|
|
165
|
-
}, undefined, false, undefined, this),
|
|
166
|
-
/* @__PURE__ */ jsxDEV("th", {
|
|
167
|
-
className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
|
|
168
|
-
children: "Tokens"
|
|
169
|
-
}, undefined, false, undefined, this),
|
|
170
|
-
/* @__PURE__ */ jsxDEV("th", {
|
|
171
|
-
className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
|
|
172
|
-
children: "Duration"
|
|
173
|
-
}, undefined, false, undefined, this),
|
|
174
|
-
/* @__PURE__ */ jsxDEV("th", {
|
|
175
|
-
className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
|
|
176
|
-
children: "Cost"
|
|
177
|
-
}, undefined, false, undefined, this)
|
|
178
|
-
]
|
|
179
|
-
}, undefined, true, undefined, this)
|
|
180
|
-
}, undefined, false, undefined, this),
|
|
181
|
-
/* @__PURE__ */ jsxDEV("tbody", {
|
|
182
|
-
className: "divide-border divide-y",
|
|
183
|
-
children: data.items.map((run) => /* @__PURE__ */ jsxDEV("tr", {
|
|
184
|
-
className: "hover:bg-muted/50 cursor-pointer transition-colors",
|
|
185
|
-
onClick: () => onRunClick?.(run.id),
|
|
186
|
-
children: [
|
|
187
|
-
/* @__PURE__ */ jsxDEV("td", {
|
|
188
|
-
className: "px-4 py-3",
|
|
189
|
-
children: [
|
|
190
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
191
|
-
className: "font-mono text-sm",
|
|
192
|
-
children: run.id.slice(-8)
|
|
193
|
-
}, undefined, false, undefined, this),
|
|
194
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
195
|
-
className: "text-muted-foreground text-xs",
|
|
196
|
-
children: run.queuedAt.toLocaleString()
|
|
197
|
-
}, undefined, false, undefined, this)
|
|
198
|
-
]
|
|
199
|
-
}, undefined, true, undefined, this),
|
|
200
|
-
/* @__PURE__ */ jsxDEV("td", {
|
|
201
|
-
className: "px-4 py-3",
|
|
202
|
-
children: /* @__PURE__ */ jsxDEV("span", {
|
|
203
|
-
className: "font-medium",
|
|
204
|
-
children: run.agentName
|
|
205
|
-
}, undefined, false, undefined, this)
|
|
206
|
-
}, undefined, false, undefined, this),
|
|
207
|
-
/* @__PURE__ */ jsxDEV("td", {
|
|
208
|
-
className: "px-4 py-3",
|
|
209
|
-
children: /* @__PURE__ */ jsxDEV(StatusChip, {
|
|
210
|
-
tone: getStatusTone(run.status),
|
|
211
|
-
label: run.status
|
|
212
|
-
}, undefined, false, undefined, this)
|
|
213
|
-
}, undefined, false, undefined, this),
|
|
214
|
-
/* @__PURE__ */ jsxDEV("td", {
|
|
215
|
-
className: "px-4 py-3 text-right font-mono text-sm",
|
|
216
|
-
children: formatTokens(run.totalTokens)
|
|
217
|
-
}, undefined, false, undefined, this),
|
|
218
|
-
/* @__PURE__ */ jsxDEV("td", {
|
|
219
|
-
className: "px-4 py-3 text-right font-mono text-sm",
|
|
220
|
-
children: formatDuration(run.durationMs)
|
|
221
|
-
}, undefined, false, undefined, this),
|
|
222
|
-
/* @__PURE__ */ jsxDEV("td", {
|
|
223
|
-
className: "px-4 py-3 text-right font-mono text-sm",
|
|
224
|
-
children: formatCost(run.estimatedCostUsd)
|
|
225
|
-
}, undefined, false, undefined, this)
|
|
226
|
-
]
|
|
227
|
-
}, run.id, true, undefined, this))
|
|
228
|
-
}, undefined, false, undefined, this)
|
|
229
|
-
]
|
|
230
|
-
}, undefined, true, undefined, this)
|
|
231
|
-
}, undefined, false, undefined, this),
|
|
232
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
233
|
-
className: "text-muted-foreground text-center text-sm",
|
|
234
|
-
children: [
|
|
235
|
-
"Showing ",
|
|
236
|
-
data.items.length,
|
|
237
|
-
" of ",
|
|
238
|
-
data.total,
|
|
239
|
-
" runs"
|
|
240
|
-
]
|
|
241
|
-
}, undefined, true, undefined, this)
|
|
242
|
-
]
|
|
243
|
-
}, undefined, true, undefined, this);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// src/ui/hooks/useToolList.ts
|
|
247
|
-
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
|
|
248
|
-
import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
|
|
249
|
-
function useToolList(options = {}) {
|
|
250
|
-
const { handlers, projectId } = useTemplateRuntime2();
|
|
251
|
-
const { agent } = handlers;
|
|
252
|
-
const [data, setData] = useState2(null);
|
|
253
|
-
const [loading, setLoading] = useState2(true);
|
|
254
|
-
const [error, setError] = useState2(null);
|
|
255
|
-
const [page, setPage] = useState2(1);
|
|
256
|
-
const fetchData = useCallback2(async () => {
|
|
257
|
-
setLoading(true);
|
|
219
|
+
function AgentActionsModal({
|
|
220
|
+
isOpen,
|
|
221
|
+
agent,
|
|
222
|
+
onClose,
|
|
223
|
+
onActivate,
|
|
224
|
+
onPause,
|
|
225
|
+
onArchive,
|
|
226
|
+
onExecute,
|
|
227
|
+
isLoading = false
|
|
228
|
+
}) {
|
|
229
|
+
const [mode, setMode] = useState4("menu");
|
|
230
|
+
const [message, setMessage] = useState4("");
|
|
231
|
+
const [confirmAction, setConfirmAction] = useState4(null);
|
|
232
|
+
const [error, setError] = useState4(null);
|
|
233
|
+
const resetForm = () => {
|
|
234
|
+
setMode("menu");
|
|
235
|
+
setMessage("");
|
|
236
|
+
setConfirmAction(null);
|
|
237
|
+
setError(null);
|
|
238
|
+
};
|
|
239
|
+
const handleClose = () => {
|
|
240
|
+
resetForm();
|
|
241
|
+
onClose();
|
|
242
|
+
};
|
|
243
|
+
const handleExecute = async () => {
|
|
244
|
+
if (!agent)
|
|
245
|
+
return;
|
|
258
246
|
setError(null);
|
|
247
|
+
if (!message.trim()) {
|
|
248
|
+
setError("Please enter a message");
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
259
251
|
try {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
search: options.search,
|
|
263
|
-
category: options.category,
|
|
264
|
-
status: options.status === "all" ? undefined : options.status,
|
|
265
|
-
limit: options.limit ?? 50,
|
|
266
|
-
offset: (page - 1) * (options.limit ?? 50)
|
|
267
|
-
});
|
|
268
|
-
setData(result);
|
|
252
|
+
await onExecute(agent.id, message.trim());
|
|
253
|
+
handleClose();
|
|
269
254
|
} catch (err) {
|
|
270
|
-
setError(err instanceof Error ? err :
|
|
271
|
-
} finally {
|
|
272
|
-
setLoading(false);
|
|
255
|
+
setError(err instanceof Error ? err.message : "Failed to execute agent");
|
|
273
256
|
}
|
|
274
|
-
}, [
|
|
275
|
-
agent,
|
|
276
|
-
projectId,
|
|
277
|
-
options.search,
|
|
278
|
-
options.category,
|
|
279
|
-
options.status,
|
|
280
|
-
options.limit,
|
|
281
|
-
page
|
|
282
|
-
]);
|
|
283
|
-
useEffect2(() => {
|
|
284
|
-
fetchData();
|
|
285
|
-
}, [fetchData]);
|
|
286
|
-
const { stats, groupedByCategory, categoryStats } = useMemo(() => {
|
|
287
|
-
if (!data)
|
|
288
|
-
return { stats: null, groupedByCategory: {}, categoryStats: [] };
|
|
289
|
-
const items = data.items;
|
|
290
|
-
const active = items.filter((t) => t.status === "ACTIVE").length;
|
|
291
|
-
const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
|
|
292
|
-
const disabled = items.filter((t) => t.status === "DISABLED").length;
|
|
293
|
-
const grouped = {};
|
|
294
|
-
const byCategory = {};
|
|
295
|
-
items.forEach((t) => {
|
|
296
|
-
const cat = t.category;
|
|
297
|
-
if (!grouped[cat])
|
|
298
|
-
grouped[cat] = [];
|
|
299
|
-
grouped[cat].push(t);
|
|
300
|
-
byCategory[cat] = (byCategory[cat] || 0) + 1;
|
|
301
|
-
});
|
|
302
|
-
const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
|
|
303
|
-
return {
|
|
304
|
-
stats: {
|
|
305
|
-
total: data.total,
|
|
306
|
-
active,
|
|
307
|
-
deprecated,
|
|
308
|
-
disabled,
|
|
309
|
-
topCategories: catStats.slice(0, 5)
|
|
310
|
-
},
|
|
311
|
-
groupedByCategory: grouped,
|
|
312
|
-
categoryStats: catStats
|
|
313
|
-
};
|
|
314
|
-
}, [data]);
|
|
315
|
-
return {
|
|
316
|
-
data,
|
|
317
|
-
loading,
|
|
318
|
-
error,
|
|
319
|
-
stats,
|
|
320
|
-
groupedByCategory,
|
|
321
|
-
categoryStats,
|
|
322
|
-
page,
|
|
323
|
-
refetch: fetchData,
|
|
324
|
-
nextPage: () => setPage((p) => p + 1),
|
|
325
|
-
prevPage: () => page > 1 && setPage((p) => p - 1)
|
|
326
257
|
};
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
case "ACTIVE":
|
|
353
|
-
return "success";
|
|
354
|
-
case "DRAFT":
|
|
355
|
-
return "neutral";
|
|
356
|
-
case "DEPRECATED":
|
|
357
|
-
return "warning";
|
|
358
|
-
case "DISABLED":
|
|
359
|
-
return "danger";
|
|
360
|
-
default:
|
|
361
|
-
return "neutral";
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
function ToolRegistryView({
|
|
365
|
-
onToolClick,
|
|
366
|
-
onCreateTool
|
|
367
|
-
}) {
|
|
368
|
-
const { data, loading, error, groupedByCategory, categoryStats, refetch } = useToolList();
|
|
369
|
-
if (loading && !data) {
|
|
370
|
-
return /* @__PURE__ */ jsxDEV2(LoaderBlock2, {
|
|
371
|
-
label: "Loading tools..."
|
|
372
|
-
}, undefined, false, undefined, this);
|
|
373
|
-
}
|
|
374
|
-
if (error) {
|
|
375
|
-
return /* @__PURE__ */ jsxDEV2(ErrorState2, {
|
|
376
|
-
title: "Failed to load tools",
|
|
377
|
-
description: error.message,
|
|
378
|
-
onRetry: refetch,
|
|
379
|
-
retryLabel: "Retry"
|
|
380
|
-
}, undefined, false, undefined, this);
|
|
381
|
-
}
|
|
382
|
-
if (!data?.items.length) {
|
|
383
|
-
return /* @__PURE__ */ jsxDEV2(EmptyState2, {
|
|
384
|
-
title: "No tools registered",
|
|
385
|
-
description: "Create your first tool to extend agent capabilities.",
|
|
386
|
-
primaryAction: onCreateTool ? /* @__PURE__ */ jsxDEV2(Button, {
|
|
387
|
-
onPress: onCreateTool,
|
|
388
|
-
children: "Create Tool"
|
|
389
|
-
}, undefined, false, undefined, this) : undefined
|
|
390
|
-
}, undefined, false, undefined, this);
|
|
391
|
-
}
|
|
392
|
-
return /* @__PURE__ */ jsxDEV2("div", {
|
|
393
|
-
className: "space-y-8",
|
|
258
|
+
const handleStatusChange = async (action) => {
|
|
259
|
+
if (!agent)
|
|
260
|
+
return;
|
|
261
|
+
setError(null);
|
|
262
|
+
try {
|
|
263
|
+
switch (action) {
|
|
264
|
+
case "activate":
|
|
265
|
+
await onActivate(agent.id);
|
|
266
|
+
break;
|
|
267
|
+
case "pause":
|
|
268
|
+
await onPause(agent.id);
|
|
269
|
+
break;
|
|
270
|
+
case "archive":
|
|
271
|
+
await onArchive(agent.id);
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
handleClose();
|
|
275
|
+
} catch (err) {
|
|
276
|
+
setError(err instanceof Error ? err.message : `Failed to ${action} agent`);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
if (!isOpen || !agent)
|
|
280
|
+
return null;
|
|
281
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
282
|
+
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
394
283
|
children: [
|
|
395
|
-
/* @__PURE__ */
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
className: "space-y-4",
|
|
284
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
285
|
+
className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
|
|
286
|
+
onClick: handleClose,
|
|
287
|
+
role: "button",
|
|
288
|
+
tabIndex: 0,
|
|
289
|
+
onKeyDown: (e) => {
|
|
290
|
+
if (e.key === "Enter" || e.key === " ")
|
|
291
|
+
handleClose();
|
|
292
|
+
},
|
|
293
|
+
"aria-label": "Close modal"
|
|
294
|
+
}, undefined, false, undefined, this),
|
|
295
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
296
|
+
className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
|
|
409
297
|
children: [
|
|
410
|
-
/* @__PURE__ */
|
|
411
|
-
className: "
|
|
298
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
299
|
+
className: "mb-4 border-border border-b pb-4",
|
|
412
300
|
children: [
|
|
413
|
-
/* @__PURE__ */
|
|
414
|
-
className: "text-
|
|
415
|
-
children:
|
|
416
|
-
}, undefined, false, undefined, this),
|
|
417
|
-
/* @__PURE__ */ jsxDEV2("h3", {
|
|
418
|
-
className: "text-lg font-semibold",
|
|
419
|
-
children: category
|
|
301
|
+
/* @__PURE__ */ jsxDEV("h2", {
|
|
302
|
+
className: "font-semibold text-xl",
|
|
303
|
+
children: agent.name
|
|
420
304
|
}, undefined, false, undefined, this),
|
|
421
|
-
/* @__PURE__ */
|
|
422
|
-
className: "
|
|
423
|
-
children:
|
|
305
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
306
|
+
className: "mt-1 flex items-center gap-2",
|
|
307
|
+
children: [
|
|
308
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
309
|
+
className: "text-muted-foreground text-sm",
|
|
310
|
+
children: [
|
|
311
|
+
agent.modelProvider,
|
|
312
|
+
" / ",
|
|
313
|
+
agent.modelName
|
|
314
|
+
]
|
|
315
|
+
}, undefined, true, undefined, this),
|
|
316
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
317
|
+
className: `rounded-full px-2 py-0.5 font-medium text-xs ${getStatusColor(agent.status)}`,
|
|
318
|
+
children: agent.status
|
|
319
|
+
}, undefined, false, undefined, this)
|
|
320
|
+
]
|
|
321
|
+
}, undefined, true, undefined, this),
|
|
322
|
+
agent.description && /* @__PURE__ */ jsxDEV("p", {
|
|
323
|
+
className: "mt-2 text-muted-foreground text-sm",
|
|
324
|
+
children: agent.description
|
|
424
325
|
}, undefined, false, undefined, this)
|
|
425
326
|
]
|
|
426
327
|
}, undefined, true, undefined, this),
|
|
427
|
-
/* @__PURE__ */
|
|
428
|
-
className: "
|
|
429
|
-
children:
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
children:
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
328
|
+
mode === "menu" && /* @__PURE__ */ jsxDEV("div", {
|
|
329
|
+
className: "space-y-3",
|
|
330
|
+
children: [
|
|
331
|
+
agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV(Button, {
|
|
332
|
+
className: "w-full justify-start",
|
|
333
|
+
variant: "ghost",
|
|
334
|
+
onPress: () => setMode("execute"),
|
|
335
|
+
children: [
|
|
336
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
337
|
+
className: "mr-2",
|
|
338
|
+
children: "▶️"
|
|
339
|
+
}, undefined, false, undefined, this),
|
|
340
|
+
" Execute Agent"
|
|
341
|
+
]
|
|
342
|
+
}, undefined, true, undefined, this),
|
|
343
|
+
(agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxDEV(Button, {
|
|
344
|
+
className: "w-full justify-start",
|
|
345
|
+
variant: "ghost",
|
|
346
|
+
onPress: () => handleStatusChange("activate"),
|
|
347
|
+
disabled: isLoading,
|
|
348
|
+
children: [
|
|
349
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
350
|
+
className: "mr-2",
|
|
351
|
+
children: "\uD83D\uDFE2"
|
|
352
|
+
}, undefined, false, undefined, this),
|
|
353
|
+
" Activate Agent"
|
|
354
|
+
]
|
|
355
|
+
}, undefined, true, undefined, this),
|
|
356
|
+
agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV(Button, {
|
|
357
|
+
className: "w-full justify-start",
|
|
358
|
+
variant: "ghost",
|
|
359
|
+
onPress: () => handleStatusChange("pause"),
|
|
360
|
+
disabled: isLoading,
|
|
361
|
+
children: [
|
|
362
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
363
|
+
className: "mr-2",
|
|
364
|
+
children: "⏸️"
|
|
365
|
+
}, undefined, false, undefined, this),
|
|
366
|
+
" Pause Agent"
|
|
367
|
+
]
|
|
368
|
+
}, undefined, true, undefined, this),
|
|
369
|
+
agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxDEV(Button, {
|
|
370
|
+
className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
|
|
371
|
+
variant: "ghost",
|
|
372
|
+
onPress: () => {
|
|
373
|
+
setConfirmAction("archive");
|
|
374
|
+
setMode("confirm");
|
|
375
|
+
},
|
|
376
|
+
children: [
|
|
377
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
378
|
+
className: "mr-2",
|
|
379
|
+
children: "\uD83D\uDCE6"
|
|
380
|
+
}, undefined, false, undefined, this),
|
|
381
|
+
" Archive Agent"
|
|
382
|
+
]
|
|
383
|
+
}, undefined, true, undefined, this),
|
|
384
|
+
agent.status === "ARCHIVED" && /* @__PURE__ */ jsxDEV(Button, {
|
|
385
|
+
className: "w-full justify-start",
|
|
386
|
+
variant: "ghost",
|
|
387
|
+
onPress: () => handleStatusChange("activate"),
|
|
388
|
+
disabled: isLoading,
|
|
389
|
+
children: [
|
|
390
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
391
|
+
className: "mr-2",
|
|
392
|
+
children: "\uD83D\uDD04"
|
|
393
|
+
}, undefined, false, undefined, this),
|
|
394
|
+
" Restore Agent"
|
|
395
|
+
]
|
|
396
|
+
}, undefined, true, undefined, this),
|
|
397
|
+
error && /* @__PURE__ */ jsxDEV("div", {
|
|
398
|
+
className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
|
|
399
|
+
children: error
|
|
443
400
|
}, undefined, false, undefined, this),
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}, [agent, projectId, options]);
|
|
544
|
-
const updateAgent = useCallback4(async (input) => {
|
|
545
|
-
setUpdateState({ loading: true, error: null, data: null });
|
|
546
|
-
try {
|
|
547
|
-
const result = await agent.updateAgent(input);
|
|
548
|
-
setUpdateState({ loading: false, error: null, data: result });
|
|
549
|
-
options.onSuccess?.();
|
|
550
|
-
return result;
|
|
551
|
-
} catch (err) {
|
|
552
|
-
const error = err instanceof Error ? err : new Error("Failed to update agent");
|
|
553
|
-
setUpdateState({ loading: false, error, data: null });
|
|
554
|
-
options.onError?.(error);
|
|
555
|
-
return null;
|
|
556
|
-
}
|
|
557
|
-
}, [agent, options]);
|
|
558
|
-
const activateAgent = useCallback4(async (agentId) => {
|
|
559
|
-
return updateAgent({ id: agentId, status: "ACTIVE" });
|
|
560
|
-
}, [updateAgent]);
|
|
561
|
-
const pauseAgent = useCallback4(async (agentId) => {
|
|
562
|
-
return updateAgent({ id: agentId, status: "PAUSED" });
|
|
563
|
-
}, [updateAgent]);
|
|
564
|
-
const archiveAgent = useCallback4(async (agentId) => {
|
|
565
|
-
return updateAgent({ id: agentId, status: "ARCHIVED" });
|
|
566
|
-
}, [updateAgent]);
|
|
567
|
-
const executeAgent = useCallback4(async (input) => {
|
|
568
|
-
setExecuteState({ loading: true, error: null, data: null });
|
|
569
|
-
try {
|
|
570
|
-
const result = await agent.executeAgent({
|
|
571
|
-
agentId: input.agentId,
|
|
572
|
-
message: input.message,
|
|
573
|
-
context: { projectId, organizationId: "demo-org" }
|
|
574
|
-
});
|
|
575
|
-
setExecuteState({ loading: false, error: null, data: result });
|
|
576
|
-
options.onSuccess?.();
|
|
577
|
-
return result;
|
|
578
|
-
} catch (err) {
|
|
579
|
-
const error = err instanceof Error ? err : new Error("Failed to execute agent");
|
|
580
|
-
setExecuteState({ loading: false, error, data: null });
|
|
581
|
-
options.onError?.(error);
|
|
582
|
-
return null;
|
|
583
|
-
}
|
|
584
|
-
}, [agent, projectId, options]);
|
|
585
|
-
return {
|
|
586
|
-
createAgent,
|
|
587
|
-
updateAgent,
|
|
588
|
-
activateAgent,
|
|
589
|
-
pauseAgent,
|
|
590
|
-
archiveAgent,
|
|
591
|
-
executeAgent,
|
|
592
|
-
createState,
|
|
593
|
-
updateState,
|
|
594
|
-
executeState,
|
|
595
|
-
isLoading: createState.loading || updateState.loading || executeState.loading
|
|
596
|
-
};
|
|
401
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
402
|
+
className: "border-border border-t pt-3",
|
|
403
|
+
children: /* @__PURE__ */ jsxDEV(Button, {
|
|
404
|
+
className: "w-full",
|
|
405
|
+
variant: "outline",
|
|
406
|
+
onPress: handleClose,
|
|
407
|
+
children: "Close"
|
|
408
|
+
}, undefined, false, undefined, this)
|
|
409
|
+
}, undefined, false, undefined, this)
|
|
410
|
+
]
|
|
411
|
+
}, undefined, true, undefined, this),
|
|
412
|
+
mode === "execute" && /* @__PURE__ */ jsxDEV("div", {
|
|
413
|
+
className: "space-y-4",
|
|
414
|
+
children: [
|
|
415
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
416
|
+
children: [
|
|
417
|
+
/* @__PURE__ */ jsxDEV("label", {
|
|
418
|
+
htmlFor: "execute-message",
|
|
419
|
+
className: "mb-1 block font-medium text-muted-foreground text-sm",
|
|
420
|
+
children: "Message *"
|
|
421
|
+
}, undefined, false, undefined, this),
|
|
422
|
+
/* @__PURE__ */ jsxDEV("textarea", {
|
|
423
|
+
id: "execute-message",
|
|
424
|
+
value: message,
|
|
425
|
+
onChange: (e) => setMessage(e.target.value),
|
|
426
|
+
placeholder: "Enter your message to the agent...",
|
|
427
|
+
rows: 4,
|
|
428
|
+
disabled: isLoading,
|
|
429
|
+
className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
|
|
430
|
+
}, undefined, false, undefined, this)
|
|
431
|
+
]
|
|
432
|
+
}, undefined, true, undefined, this),
|
|
433
|
+
error && /* @__PURE__ */ jsxDEV("div", {
|
|
434
|
+
className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
|
|
435
|
+
children: error
|
|
436
|
+
}, undefined, false, undefined, this),
|
|
437
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
438
|
+
className: "flex justify-end gap-3 pt-2",
|
|
439
|
+
children: [
|
|
440
|
+
/* @__PURE__ */ jsxDEV(Button, {
|
|
441
|
+
variant: "ghost",
|
|
442
|
+
onPress: () => setMode("menu"),
|
|
443
|
+
disabled: isLoading,
|
|
444
|
+
children: "Back"
|
|
445
|
+
}, undefined, false, undefined, this),
|
|
446
|
+
/* @__PURE__ */ jsxDEV(Button, {
|
|
447
|
+
onPress: handleExecute,
|
|
448
|
+
disabled: isLoading,
|
|
449
|
+
children: isLoading ? "Executing..." : "▶️ Execute"
|
|
450
|
+
}, undefined, false, undefined, this)
|
|
451
|
+
]
|
|
452
|
+
}, undefined, true, undefined, this)
|
|
453
|
+
]
|
|
454
|
+
}, undefined, true, undefined, this),
|
|
455
|
+
mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxDEV("div", {
|
|
456
|
+
className: "space-y-4",
|
|
457
|
+
children: [
|
|
458
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
459
|
+
className: "text-muted-foreground",
|
|
460
|
+
children: [
|
|
461
|
+
"Are you sure you want to archive",
|
|
462
|
+
" ",
|
|
463
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
464
|
+
className: "font-medium text-foreground",
|
|
465
|
+
children: agent.name
|
|
466
|
+
}, undefined, false, undefined, this),
|
|
467
|
+
"?"
|
|
468
|
+
]
|
|
469
|
+
}, undefined, true, undefined, this),
|
|
470
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
471
|
+
className: "text-muted-foreground text-sm",
|
|
472
|
+
children: "Archived agents cannot be executed but can be restored later."
|
|
473
|
+
}, undefined, false, undefined, this),
|
|
474
|
+
error && /* @__PURE__ */ jsxDEV("div", {
|
|
475
|
+
className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
|
|
476
|
+
children: error
|
|
477
|
+
}, undefined, false, undefined, this),
|
|
478
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
479
|
+
className: "flex justify-end gap-3 pt-2",
|
|
480
|
+
children: [
|
|
481
|
+
/* @__PURE__ */ jsxDEV(Button, {
|
|
482
|
+
variant: "ghost",
|
|
483
|
+
onPress: () => setMode("menu"),
|
|
484
|
+
disabled: isLoading,
|
|
485
|
+
children: "Cancel"
|
|
486
|
+
}, undefined, false, undefined, this),
|
|
487
|
+
/* @__PURE__ */ jsxDEV(Button, {
|
|
488
|
+
onPress: () => handleStatusChange("archive"),
|
|
489
|
+
disabled: isLoading,
|
|
490
|
+
children: isLoading ? "Archiving..." : "\uD83D\uDCE6 Archive"
|
|
491
|
+
}, undefined, false, undefined, this)
|
|
492
|
+
]
|
|
493
|
+
}, undefined, true, undefined, this)
|
|
494
|
+
]
|
|
495
|
+
}, undefined, true, undefined, this)
|
|
496
|
+
]
|
|
497
|
+
}, undefined, true, undefined, this)
|
|
498
|
+
]
|
|
499
|
+
}, undefined, true, undefined, this);
|
|
597
500
|
}
|
|
598
501
|
|
|
599
502
|
// src/ui/modals/CreateAgentModal.tsx
|
|
600
|
-
import { useState as useState5 } from "react";
|
|
601
503
|
import { Button as Button2, Input } from "@contractspec/lib.design-system";
|
|
602
|
-
import {
|
|
504
|
+
import { useState as useState5 } from "react";
|
|
505
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
603
506
|
"use client";
|
|
604
507
|
var MODEL_PROVIDERS = [
|
|
605
508
|
{
|
|
@@ -680,11 +583,11 @@ function CreateAgentModal({
|
|
|
680
583
|
};
|
|
681
584
|
if (!isOpen)
|
|
682
585
|
return null;
|
|
683
|
-
return /* @__PURE__ */
|
|
586
|
+
return /* @__PURE__ */ jsxDEV2("div", {
|
|
684
587
|
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
685
588
|
children: [
|
|
686
|
-
/* @__PURE__ */
|
|
687
|
-
className: "bg-background/80
|
|
589
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
590
|
+
className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
|
|
688
591
|
onClick: onClose,
|
|
689
592
|
role: "button",
|
|
690
593
|
tabIndex: 0,
|
|
@@ -694,458 +597,555 @@ function CreateAgentModal({
|
|
|
694
597
|
},
|
|
695
598
|
"aria-label": "Close modal"
|
|
696
599
|
}, undefined, false, undefined, this),
|
|
600
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
601
|
+
className: "relative z-10 max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-xl border border-border bg-card p-6 shadow-xl",
|
|
602
|
+
children: [
|
|
603
|
+
/* @__PURE__ */ jsxDEV2("h2", {
|
|
604
|
+
className: "mb-4 font-semibold text-xl",
|
|
605
|
+
children: "Create New Agent"
|
|
606
|
+
}, undefined, false, undefined, this),
|
|
607
|
+
/* @__PURE__ */ jsxDEV2("form", {
|
|
608
|
+
onSubmit: handleSubmit,
|
|
609
|
+
className: "space-y-4",
|
|
610
|
+
children: [
|
|
611
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
612
|
+
children: [
|
|
613
|
+
/* @__PURE__ */ jsxDEV2("label", {
|
|
614
|
+
htmlFor: "agent-name",
|
|
615
|
+
className: "mb-1 block font-medium text-muted-foreground text-sm",
|
|
616
|
+
children: "Agent Name *"
|
|
617
|
+
}, undefined, false, undefined, this),
|
|
618
|
+
/* @__PURE__ */ jsxDEV2(Input, {
|
|
619
|
+
id: "agent-name",
|
|
620
|
+
value: name,
|
|
621
|
+
onChange: (e) => setName(e.target.value),
|
|
622
|
+
placeholder: "e.g., Customer Support Bot",
|
|
623
|
+
disabled: isLoading
|
|
624
|
+
}, undefined, false, undefined, this)
|
|
625
|
+
]
|
|
626
|
+
}, undefined, true, undefined, this),
|
|
627
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
628
|
+
children: [
|
|
629
|
+
/* @__PURE__ */ jsxDEV2("label", {
|
|
630
|
+
htmlFor: "agent-description",
|
|
631
|
+
className: "mb-1 block font-medium text-muted-foreground text-sm",
|
|
632
|
+
children: "Description"
|
|
633
|
+
}, undefined, false, undefined, this),
|
|
634
|
+
/* @__PURE__ */ jsxDEV2("textarea", {
|
|
635
|
+
id: "agent-description",
|
|
636
|
+
value: description,
|
|
637
|
+
onChange: (e) => setDescription(e.target.value),
|
|
638
|
+
placeholder: "Describe what this agent does...",
|
|
639
|
+
rows: 2,
|
|
640
|
+
disabled: isLoading,
|
|
641
|
+
className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
|
|
642
|
+
}, undefined, false, undefined, this)
|
|
643
|
+
]
|
|
644
|
+
}, undefined, true, undefined, this),
|
|
645
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
646
|
+
className: "flex gap-3",
|
|
647
|
+
children: [
|
|
648
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
649
|
+
className: "flex-1",
|
|
650
|
+
children: [
|
|
651
|
+
/* @__PURE__ */ jsxDEV2("label", {
|
|
652
|
+
htmlFor: "model-provider",
|
|
653
|
+
className: "mb-1 block font-medium text-muted-foreground text-sm",
|
|
654
|
+
children: "Provider *"
|
|
655
|
+
}, undefined, false, undefined, this),
|
|
656
|
+
/* @__PURE__ */ jsxDEV2("select", {
|
|
657
|
+
id: "model-provider",
|
|
658
|
+
value: modelProvider,
|
|
659
|
+
onChange: (e) => handleProviderChange(e.target.value),
|
|
660
|
+
disabled: isLoading,
|
|
661
|
+
className: "h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
|
|
662
|
+
children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsxDEV2("option", {
|
|
663
|
+
value: p.value,
|
|
664
|
+
children: p.label
|
|
665
|
+
}, p.value, false, undefined, this))
|
|
666
|
+
}, undefined, false, undefined, this)
|
|
667
|
+
]
|
|
668
|
+
}, undefined, true, undefined, this),
|
|
669
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
670
|
+
className: "flex-1",
|
|
671
|
+
children: [
|
|
672
|
+
/* @__PURE__ */ jsxDEV2("label", {
|
|
673
|
+
htmlFor: "model-name",
|
|
674
|
+
className: "mb-1 block font-medium text-muted-foreground text-sm",
|
|
675
|
+
children: "Model *"
|
|
676
|
+
}, undefined, false, undefined, this),
|
|
677
|
+
/* @__PURE__ */ jsxDEV2("select", {
|
|
678
|
+
id: "model-name",
|
|
679
|
+
value: modelName,
|
|
680
|
+
onChange: (e) => setModelName(e.target.value),
|
|
681
|
+
disabled: isLoading,
|
|
682
|
+
className: "h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
|
|
683
|
+
children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsxDEV2("option", {
|
|
684
|
+
value: m,
|
|
685
|
+
children: m
|
|
686
|
+
}, m, false, undefined, this))
|
|
687
|
+
}, undefined, false, undefined, this)
|
|
688
|
+
]
|
|
689
|
+
}, undefined, true, undefined, this)
|
|
690
|
+
]
|
|
691
|
+
}, undefined, true, undefined, this),
|
|
692
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
693
|
+
children: [
|
|
694
|
+
/* @__PURE__ */ jsxDEV2("label", {
|
|
695
|
+
htmlFor: "system-prompt",
|
|
696
|
+
className: "mb-1 block font-medium text-muted-foreground text-sm",
|
|
697
|
+
children: "System Prompt"
|
|
698
|
+
}, undefined, false, undefined, this),
|
|
699
|
+
/* @__PURE__ */ jsxDEV2("textarea", {
|
|
700
|
+
id: "system-prompt",
|
|
701
|
+
value: systemPrompt,
|
|
702
|
+
onChange: (e) => setSystemPrompt(e.target.value),
|
|
703
|
+
placeholder: "You are a helpful assistant that...",
|
|
704
|
+
rows: 4,
|
|
705
|
+
disabled: isLoading,
|
|
706
|
+
className: "w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
|
|
707
|
+
}, undefined, false, undefined, this),
|
|
708
|
+
/* @__PURE__ */ jsxDEV2("p", {
|
|
709
|
+
className: "mt-1 text-muted-foreground text-xs",
|
|
710
|
+
children: "Instructions that define the agent's behavior"
|
|
711
|
+
}, undefined, false, undefined, this)
|
|
712
|
+
]
|
|
713
|
+
}, undefined, true, undefined, this),
|
|
714
|
+
error && /* @__PURE__ */ jsxDEV2("div", {
|
|
715
|
+
className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
|
|
716
|
+
children: error
|
|
717
|
+
}, undefined, false, undefined, this),
|
|
718
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
719
|
+
className: "flex justify-end gap-3 pt-2",
|
|
720
|
+
children: [
|
|
721
|
+
/* @__PURE__ */ jsxDEV2(Button2, {
|
|
722
|
+
type: "button",
|
|
723
|
+
variant: "ghost",
|
|
724
|
+
onPress: onClose,
|
|
725
|
+
disabled: isLoading,
|
|
726
|
+
children: "Cancel"
|
|
727
|
+
}, undefined, false, undefined, this),
|
|
728
|
+
/* @__PURE__ */ jsxDEV2(Button2, {
|
|
729
|
+
type: "submit",
|
|
730
|
+
disabled: isLoading,
|
|
731
|
+
children: isLoading ? "Creating..." : "Create Agent"
|
|
732
|
+
}, undefined, false, undefined, this)
|
|
733
|
+
]
|
|
734
|
+
}, undefined, true, undefined, this)
|
|
735
|
+
]
|
|
736
|
+
}, undefined, true, undefined, this)
|
|
737
|
+
]
|
|
738
|
+
}, undefined, true, undefined, this)
|
|
739
|
+
]
|
|
740
|
+
}, undefined, true, undefined, this);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// src/ui/views/RunListView.tsx
|
|
744
|
+
import {
|
|
745
|
+
EmptyState,
|
|
746
|
+
ErrorState,
|
|
747
|
+
LoaderBlock,
|
|
748
|
+
StatCard,
|
|
749
|
+
StatCardGroup,
|
|
750
|
+
StatusChip
|
|
751
|
+
} from "@contractspec/lib.design-system";
|
|
752
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
753
|
+
"use client";
|
|
754
|
+
function getStatusTone(status) {
|
|
755
|
+
switch (status) {
|
|
756
|
+
case "COMPLETED":
|
|
757
|
+
return "success";
|
|
758
|
+
case "RUNNING":
|
|
759
|
+
return "warning";
|
|
760
|
+
case "QUEUED":
|
|
761
|
+
return "neutral";
|
|
762
|
+
case "FAILED":
|
|
763
|
+
case "CANCELLED":
|
|
764
|
+
return "danger";
|
|
765
|
+
default:
|
|
766
|
+
return "neutral";
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
function formatDuration(ms) {
|
|
770
|
+
if (!ms)
|
|
771
|
+
return "-";
|
|
772
|
+
if (ms < 1000)
|
|
773
|
+
return `${ms}ms`;
|
|
774
|
+
if (ms < 60000)
|
|
775
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
776
|
+
return `${(ms / 60000).toFixed(1)}m`;
|
|
777
|
+
}
|
|
778
|
+
function formatTokens(tokens) {
|
|
779
|
+
if (tokens < 1000)
|
|
780
|
+
return tokens.toString();
|
|
781
|
+
if (tokens < 1e6)
|
|
782
|
+
return `${(tokens / 1000).toFixed(1)}K`;
|
|
783
|
+
return `${(tokens / 1e6).toFixed(2)}M`;
|
|
784
|
+
}
|
|
785
|
+
function formatCost(cost) {
|
|
786
|
+
if (!cost)
|
|
787
|
+
return "-";
|
|
788
|
+
return `$${cost.toFixed(4)}`;
|
|
789
|
+
}
|
|
790
|
+
function RunListView({ agentId, onRunClick }) {
|
|
791
|
+
const { data, metrics, loading, error, refetch } = useRunList({ agentId });
|
|
792
|
+
if (loading && !data) {
|
|
793
|
+
return /* @__PURE__ */ jsxDEV3(LoaderBlock, {
|
|
794
|
+
label: "Loading runs..."
|
|
795
|
+
}, undefined, false, undefined, this);
|
|
796
|
+
}
|
|
797
|
+
if (error) {
|
|
798
|
+
return /* @__PURE__ */ jsxDEV3(ErrorState, {
|
|
799
|
+
title: "Failed to load runs",
|
|
800
|
+
description: error.message,
|
|
801
|
+
onRetry: refetch,
|
|
802
|
+
retryLabel: "Retry"
|
|
803
|
+
}, undefined, false, undefined, this);
|
|
804
|
+
}
|
|
805
|
+
if (!data?.items.length) {
|
|
806
|
+
return /* @__PURE__ */ jsxDEV3(EmptyState, {
|
|
807
|
+
title: "No runs yet",
|
|
808
|
+
description: "Execute an agent to see run history here."
|
|
809
|
+
}, undefined, false, undefined, this);
|
|
810
|
+
}
|
|
811
|
+
return /* @__PURE__ */ jsxDEV3("div", {
|
|
812
|
+
className: "space-y-6",
|
|
813
|
+
children: [
|
|
814
|
+
metrics && /* @__PURE__ */ jsxDEV3(StatCardGroup, {
|
|
815
|
+
children: [
|
|
816
|
+
/* @__PURE__ */ jsxDEV3(StatCard, {
|
|
817
|
+
label: "Total Runs",
|
|
818
|
+
value: metrics.totalRuns
|
|
819
|
+
}, undefined, false, undefined, this),
|
|
820
|
+
/* @__PURE__ */ jsxDEV3(StatCard, {
|
|
821
|
+
label: "Success Rate",
|
|
822
|
+
value: `${(metrics.successRate * 100).toFixed(1)}%`
|
|
823
|
+
}, undefined, false, undefined, this),
|
|
824
|
+
/* @__PURE__ */ jsxDEV3(StatCard, {
|
|
825
|
+
label: "Total Tokens",
|
|
826
|
+
value: formatTokens(metrics.totalTokens)
|
|
827
|
+
}, undefined, false, undefined, this),
|
|
828
|
+
/* @__PURE__ */ jsxDEV3(StatCard, {
|
|
829
|
+
label: "Total Cost",
|
|
830
|
+
value: `$${metrics.totalCostUsd.toFixed(2)}`
|
|
831
|
+
}, undefined, false, undefined, this)
|
|
832
|
+
]
|
|
833
|
+
}, undefined, true, undefined, this),
|
|
697
834
|
/* @__PURE__ */ jsxDEV3("div", {
|
|
698
|
-
className: "
|
|
699
|
-
children:
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
onSubmit: handleSubmit,
|
|
706
|
-
className: "space-y-4",
|
|
707
|
-
children: [
|
|
708
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
835
|
+
className: "rounded-lg border border-border",
|
|
836
|
+
children: /* @__PURE__ */ jsxDEV3("table", {
|
|
837
|
+
className: "w-full",
|
|
838
|
+
children: [
|
|
839
|
+
/* @__PURE__ */ jsxDEV3("thead", {
|
|
840
|
+
className: "border-border border-b bg-muted/30",
|
|
841
|
+
children: /* @__PURE__ */ jsxDEV3("tr", {
|
|
709
842
|
children: [
|
|
710
|
-
/* @__PURE__ */ jsxDEV3("
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
children: "Agent Name *"
|
|
843
|
+
/* @__PURE__ */ jsxDEV3("th", {
|
|
844
|
+
className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
|
|
845
|
+
children: "Run"
|
|
714
846
|
}, undefined, false, undefined, this),
|
|
715
|
-
/* @__PURE__ */ jsxDEV3(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
onChange: (e) => setName(e.target.value),
|
|
719
|
-
placeholder: "e.g., Customer Support Bot",
|
|
720
|
-
disabled: isLoading
|
|
721
|
-
}, undefined, false, undefined, this)
|
|
722
|
-
]
|
|
723
|
-
}, undefined, true, undefined, this),
|
|
724
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
725
|
-
children: [
|
|
726
|
-
/* @__PURE__ */ jsxDEV3("label", {
|
|
727
|
-
htmlFor: "agent-description",
|
|
728
|
-
className: "text-muted-foreground mb-1 block text-sm font-medium",
|
|
729
|
-
children: "Description"
|
|
847
|
+
/* @__PURE__ */ jsxDEV3("th", {
|
|
848
|
+
className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
|
|
849
|
+
children: "Agent"
|
|
730
850
|
}, undefined, false, undefined, this),
|
|
731
|
-
/* @__PURE__ */ jsxDEV3("
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
851
|
+
/* @__PURE__ */ jsxDEV3("th", {
|
|
852
|
+
className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
|
|
853
|
+
children: "Status"
|
|
854
|
+
}, undefined, false, undefined, this),
|
|
855
|
+
/* @__PURE__ */ jsxDEV3("th", {
|
|
856
|
+
className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
|
|
857
|
+
children: "Tokens"
|
|
858
|
+
}, undefined, false, undefined, this),
|
|
859
|
+
/* @__PURE__ */ jsxDEV3("th", {
|
|
860
|
+
className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
|
|
861
|
+
children: "Duration"
|
|
862
|
+
}, undefined, false, undefined, this),
|
|
863
|
+
/* @__PURE__ */ jsxDEV3("th", {
|
|
864
|
+
className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
|
|
865
|
+
children: "Cost"
|
|
739
866
|
}, undefined, false, undefined, this)
|
|
740
867
|
]
|
|
741
|
-
}, undefined, true, undefined, this)
|
|
742
|
-
|
|
743
|
-
|
|
868
|
+
}, undefined, true, undefined, this)
|
|
869
|
+
}, undefined, false, undefined, this),
|
|
870
|
+
/* @__PURE__ */ jsxDEV3("tbody", {
|
|
871
|
+
className: "divide-y divide-border",
|
|
872
|
+
children: data.items.map((run) => /* @__PURE__ */ jsxDEV3("tr", {
|
|
873
|
+
className: "cursor-pointer transition-colors hover:bg-muted/50",
|
|
874
|
+
onClick: () => onRunClick?.(run.id),
|
|
744
875
|
children: [
|
|
745
|
-
/* @__PURE__ */ jsxDEV3("
|
|
746
|
-
className: "
|
|
876
|
+
/* @__PURE__ */ jsxDEV3("td", {
|
|
877
|
+
className: "px-4 py-3",
|
|
747
878
|
children: [
|
|
748
|
-
/* @__PURE__ */ jsxDEV3("
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
children: "Provider *"
|
|
879
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
880
|
+
className: "font-mono text-sm",
|
|
881
|
+
children: run.id.slice(-8)
|
|
752
882
|
}, undefined, false, undefined, this),
|
|
753
|
-
/* @__PURE__ */ jsxDEV3("
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
onChange: (e) => handleProviderChange(e.target.value),
|
|
757
|
-
disabled: isLoading,
|
|
758
|
-
className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
|
|
759
|
-
children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsxDEV3("option", {
|
|
760
|
-
value: p.value,
|
|
761
|
-
children: p.label
|
|
762
|
-
}, p.value, false, undefined, this))
|
|
883
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
884
|
+
className: "text-muted-foreground text-xs",
|
|
885
|
+
children: run.queuedAt.toLocaleString()
|
|
763
886
|
}, undefined, false, undefined, this)
|
|
764
887
|
]
|
|
765
888
|
}, undefined, true, undefined, this),
|
|
766
|
-
/* @__PURE__ */ jsxDEV3("
|
|
767
|
-
className: "
|
|
768
|
-
children:
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
children: "Model *"
|
|
773
|
-
}, undefined, false, undefined, this),
|
|
774
|
-
/* @__PURE__ */ jsxDEV3("select", {
|
|
775
|
-
id: "model-name",
|
|
776
|
-
value: modelName,
|
|
777
|
-
onChange: (e) => setModelName(e.target.value),
|
|
778
|
-
disabled: isLoading,
|
|
779
|
-
className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
|
|
780
|
-
children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsxDEV3("option", {
|
|
781
|
-
value: m,
|
|
782
|
-
children: m
|
|
783
|
-
}, m, false, undefined, this))
|
|
784
|
-
}, undefined, false, undefined, this)
|
|
785
|
-
]
|
|
786
|
-
}, undefined, true, undefined, this)
|
|
787
|
-
]
|
|
788
|
-
}, undefined, true, undefined, this),
|
|
789
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
790
|
-
children: [
|
|
791
|
-
/* @__PURE__ */ jsxDEV3("label", {
|
|
792
|
-
htmlFor: "system-prompt",
|
|
793
|
-
className: "text-muted-foreground mb-1 block text-sm font-medium",
|
|
794
|
-
children: "System Prompt"
|
|
889
|
+
/* @__PURE__ */ jsxDEV3("td", {
|
|
890
|
+
className: "px-4 py-3",
|
|
891
|
+
children: /* @__PURE__ */ jsxDEV3("span", {
|
|
892
|
+
className: "font-medium",
|
|
893
|
+
children: run.agentName
|
|
894
|
+
}, undefined, false, undefined, this)
|
|
795
895
|
}, undefined, false, undefined, this),
|
|
796
|
-
/* @__PURE__ */ jsxDEV3("
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
disabled: isLoading,
|
|
803
|
-
className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 font-mono text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
|
|
896
|
+
/* @__PURE__ */ jsxDEV3("td", {
|
|
897
|
+
className: "px-4 py-3",
|
|
898
|
+
children: /* @__PURE__ */ jsxDEV3(StatusChip, {
|
|
899
|
+
tone: getStatusTone(run.status),
|
|
900
|
+
label: run.status
|
|
901
|
+
}, undefined, false, undefined, this)
|
|
804
902
|
}, undefined, false, undefined, this),
|
|
805
|
-
/* @__PURE__ */ jsxDEV3("
|
|
806
|
-
className: "
|
|
807
|
-
children:
|
|
808
|
-
}, undefined, false, undefined, this)
|
|
809
|
-
]
|
|
810
|
-
}, undefined, true, undefined, this),
|
|
811
|
-
error && /* @__PURE__ */ jsxDEV3("div", {
|
|
812
|
-
className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
|
|
813
|
-
children: error
|
|
814
|
-
}, undefined, false, undefined, this),
|
|
815
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
816
|
-
className: "flex justify-end gap-3 pt-2",
|
|
817
|
-
children: [
|
|
818
|
-
/* @__PURE__ */ jsxDEV3(Button2, {
|
|
819
|
-
type: "button",
|
|
820
|
-
variant: "ghost",
|
|
821
|
-
onPress: onClose,
|
|
822
|
-
disabled: isLoading,
|
|
823
|
-
children: "Cancel"
|
|
903
|
+
/* @__PURE__ */ jsxDEV3("td", {
|
|
904
|
+
className: "px-4 py-3 text-right font-mono text-sm",
|
|
905
|
+
children: formatTokens(run.totalTokens)
|
|
824
906
|
}, undefined, false, undefined, this),
|
|
825
|
-
/* @__PURE__ */ jsxDEV3(
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
907
|
+
/* @__PURE__ */ jsxDEV3("td", {
|
|
908
|
+
className: "px-4 py-3 text-right font-mono text-sm",
|
|
909
|
+
children: formatDuration(run.durationMs)
|
|
910
|
+
}, undefined, false, undefined, this),
|
|
911
|
+
/* @__PURE__ */ jsxDEV3("td", {
|
|
912
|
+
className: "px-4 py-3 text-right font-mono text-sm",
|
|
913
|
+
children: formatCost(run.estimatedCostUsd)
|
|
829
914
|
}, undefined, false, undefined, this)
|
|
830
915
|
]
|
|
831
|
-
},
|
|
832
|
-
|
|
833
|
-
|
|
916
|
+
}, run.id, true, undefined, this))
|
|
917
|
+
}, undefined, false, undefined, this)
|
|
918
|
+
]
|
|
919
|
+
}, undefined, true, undefined, this)
|
|
920
|
+
}, undefined, false, undefined, this),
|
|
921
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
922
|
+
className: "text-center text-muted-foreground text-sm",
|
|
923
|
+
children: [
|
|
924
|
+
"Showing ",
|
|
925
|
+
data.items.length,
|
|
926
|
+
" of ",
|
|
927
|
+
data.total,
|
|
928
|
+
" runs"
|
|
834
929
|
]
|
|
835
930
|
}, undefined, true, undefined, this)
|
|
836
931
|
]
|
|
837
932
|
}, undefined, true, undefined, this);
|
|
838
933
|
}
|
|
839
934
|
|
|
840
|
-
// src/ui/
|
|
841
|
-
import {
|
|
842
|
-
import {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
|
|
849
|
-
case "DRAFT":
|
|
850
|
-
return "text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30";
|
|
851
|
-
case "PAUSED":
|
|
852
|
-
return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
|
|
853
|
-
case "ARCHIVED":
|
|
854
|
-
return "text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700";
|
|
855
|
-
default:
|
|
856
|
-
return "text-gray-600 bg-gray-100";
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
function AgentActionsModal({
|
|
860
|
-
isOpen,
|
|
861
|
-
agent,
|
|
862
|
-
onClose,
|
|
863
|
-
onActivate,
|
|
864
|
-
onPause,
|
|
865
|
-
onArchive,
|
|
866
|
-
onExecute,
|
|
867
|
-
isLoading = false
|
|
868
|
-
}) {
|
|
869
|
-
const [mode, setMode] = useState6("menu");
|
|
870
|
-
const [message, setMessage] = useState6("");
|
|
871
|
-
const [confirmAction, setConfirmAction] = useState6(null);
|
|
935
|
+
// src/ui/hooks/useToolList.ts
|
|
936
|
+
import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
|
|
937
|
+
import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo2, useState as useState6 } from "react";
|
|
938
|
+
function useToolList(options = {}) {
|
|
939
|
+
const { handlers, projectId } = useTemplateRuntime4();
|
|
940
|
+
const { agent } = handlers;
|
|
941
|
+
const [data, setData] = useState6(null);
|
|
942
|
+
const [loading, setLoading] = useState6(true);
|
|
872
943
|
const [error, setError] = useState6(null);
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
setConfirmAction(null);
|
|
877
|
-
setError(null);
|
|
878
|
-
};
|
|
879
|
-
const handleClose = () => {
|
|
880
|
-
resetForm();
|
|
881
|
-
onClose();
|
|
882
|
-
};
|
|
883
|
-
const handleExecute = async () => {
|
|
884
|
-
if (!agent)
|
|
885
|
-
return;
|
|
886
|
-
setError(null);
|
|
887
|
-
if (!message.trim()) {
|
|
888
|
-
setError("Please enter a message");
|
|
889
|
-
return;
|
|
890
|
-
}
|
|
891
|
-
try {
|
|
892
|
-
await onExecute(agent.id, message.trim());
|
|
893
|
-
handleClose();
|
|
894
|
-
} catch (err) {
|
|
895
|
-
setError(err instanceof Error ? err.message : "Failed to execute agent");
|
|
896
|
-
}
|
|
897
|
-
};
|
|
898
|
-
const handleStatusChange = async (action) => {
|
|
899
|
-
if (!agent)
|
|
900
|
-
return;
|
|
944
|
+
const [page, setPage] = useState6(1);
|
|
945
|
+
const fetchData = useCallback4(async () => {
|
|
946
|
+
setLoading(true);
|
|
901
947
|
setError(null);
|
|
902
948
|
try {
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
break;
|
|
913
|
-
}
|
|
914
|
-
handleClose();
|
|
949
|
+
const result = await agent.listTools({
|
|
950
|
+
projectId,
|
|
951
|
+
search: options.search,
|
|
952
|
+
category: options.category,
|
|
953
|
+
status: options.status === "all" ? undefined : options.status,
|
|
954
|
+
limit: options.limit ?? 50,
|
|
955
|
+
offset: (page - 1) * (options.limit ?? 50)
|
|
956
|
+
});
|
|
957
|
+
setData(result);
|
|
915
958
|
} catch (err) {
|
|
916
|
-
setError(err instanceof Error ? err
|
|
959
|
+
setError(err instanceof Error ? err : new Error("Unknown error"));
|
|
960
|
+
} finally {
|
|
961
|
+
setLoading(false);
|
|
917
962
|
}
|
|
963
|
+
}, [
|
|
964
|
+
agent,
|
|
965
|
+
projectId,
|
|
966
|
+
options.search,
|
|
967
|
+
options.category,
|
|
968
|
+
options.status,
|
|
969
|
+
options.limit,
|
|
970
|
+
page
|
|
971
|
+
]);
|
|
972
|
+
useEffect3(() => {
|
|
973
|
+
fetchData();
|
|
974
|
+
}, [fetchData]);
|
|
975
|
+
const { stats, groupedByCategory, categoryStats } = useMemo2(() => {
|
|
976
|
+
if (!data)
|
|
977
|
+
return { stats: null, groupedByCategory: {}, categoryStats: [] };
|
|
978
|
+
const items = data.items;
|
|
979
|
+
const active = items.filter((t) => t.status === "ACTIVE").length;
|
|
980
|
+
const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
|
|
981
|
+
const disabled = items.filter((t) => t.status === "DISABLED").length;
|
|
982
|
+
const grouped = {};
|
|
983
|
+
const byCategory = {};
|
|
984
|
+
items.forEach((t) => {
|
|
985
|
+
const cat = t.category;
|
|
986
|
+
if (!grouped[cat])
|
|
987
|
+
grouped[cat] = [];
|
|
988
|
+
grouped[cat].push(t);
|
|
989
|
+
byCategory[cat] = (byCategory[cat] || 0) + 1;
|
|
990
|
+
});
|
|
991
|
+
const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
|
|
992
|
+
return {
|
|
993
|
+
stats: {
|
|
994
|
+
total: data.total,
|
|
995
|
+
active,
|
|
996
|
+
deprecated,
|
|
997
|
+
disabled,
|
|
998
|
+
topCategories: catStats.slice(0, 5)
|
|
999
|
+
},
|
|
1000
|
+
groupedByCategory: grouped,
|
|
1001
|
+
categoryStats: catStats
|
|
1002
|
+
};
|
|
1003
|
+
}, [data]);
|
|
1004
|
+
return {
|
|
1005
|
+
data,
|
|
1006
|
+
loading,
|
|
1007
|
+
error,
|
|
1008
|
+
stats,
|
|
1009
|
+
groupedByCategory,
|
|
1010
|
+
categoryStats,
|
|
1011
|
+
page,
|
|
1012
|
+
refetch: fetchData,
|
|
1013
|
+
nextPage: () => setPage((p) => p + 1),
|
|
1014
|
+
prevPage: () => page > 1 && setPage((p) => p - 1)
|
|
918
1015
|
};
|
|
919
|
-
|
|
920
|
-
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// src/ui/views/ToolRegistryView.tsx
|
|
1019
|
+
import {
|
|
1020
|
+
Button as Button3,
|
|
1021
|
+
EmptyState as EmptyState2,
|
|
1022
|
+
EntityCard,
|
|
1023
|
+
ErrorState as ErrorState2,
|
|
1024
|
+
LoaderBlock as LoaderBlock2,
|
|
1025
|
+
StatCard as StatCard2,
|
|
1026
|
+
StatCardGroup as StatCardGroup2,
|
|
1027
|
+
StatusChip as StatusChip2
|
|
1028
|
+
} from "@contractspec/lib.design-system";
|
|
1029
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
1030
|
+
"use client";
|
|
1031
|
+
var categoryIcons = {
|
|
1032
|
+
RETRIEVAL: "\uD83D\uDD0D",
|
|
1033
|
+
COMPUTATION: "\uD83E\uDDEE",
|
|
1034
|
+
COMMUNICATION: "\uD83D\uDCE7",
|
|
1035
|
+
INTEGRATION: "\uD83D\uDD17",
|
|
1036
|
+
UTILITY: "\uD83D\uDEE0️",
|
|
1037
|
+
CUSTOM: "⚙️"
|
|
1038
|
+
};
|
|
1039
|
+
function getStatusTone2(status) {
|
|
1040
|
+
switch (status) {
|
|
1041
|
+
case "ACTIVE":
|
|
1042
|
+
return "success";
|
|
1043
|
+
case "DRAFT":
|
|
1044
|
+
return "neutral";
|
|
1045
|
+
case "DEPRECATED":
|
|
1046
|
+
return "warning";
|
|
1047
|
+
case "DISABLED":
|
|
1048
|
+
return "danger";
|
|
1049
|
+
default:
|
|
1050
|
+
return "neutral";
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
function ToolRegistryView({
|
|
1054
|
+
onToolClick,
|
|
1055
|
+
onCreateTool
|
|
1056
|
+
}) {
|
|
1057
|
+
const { data, loading, error, groupedByCategory, categoryStats, refetch } = useToolList();
|
|
1058
|
+
if (loading && !data) {
|
|
1059
|
+
return /* @__PURE__ */ jsxDEV4(LoaderBlock2, {
|
|
1060
|
+
label: "Loading tools..."
|
|
1061
|
+
}, undefined, false, undefined, this);
|
|
1062
|
+
}
|
|
1063
|
+
if (error) {
|
|
1064
|
+
return /* @__PURE__ */ jsxDEV4(ErrorState2, {
|
|
1065
|
+
title: "Failed to load tools",
|
|
1066
|
+
description: error.message,
|
|
1067
|
+
onRetry: refetch,
|
|
1068
|
+
retryLabel: "Retry"
|
|
1069
|
+
}, undefined, false, undefined, this);
|
|
1070
|
+
}
|
|
1071
|
+
if (!data?.items.length) {
|
|
1072
|
+
return /* @__PURE__ */ jsxDEV4(EmptyState2, {
|
|
1073
|
+
title: "No tools registered",
|
|
1074
|
+
description: "Create your first tool to extend agent capabilities.",
|
|
1075
|
+
primaryAction: onCreateTool ? /* @__PURE__ */ jsxDEV4(Button3, {
|
|
1076
|
+
onPress: onCreateTool,
|
|
1077
|
+
children: "Create Tool"
|
|
1078
|
+
}, undefined, false, undefined, this) : undefined
|
|
1079
|
+
}, undefined, false, undefined, this);
|
|
1080
|
+
}
|
|
921
1081
|
return /* @__PURE__ */ jsxDEV4("div", {
|
|
922
|
-
className: "
|
|
1082
|
+
className: "space-y-8",
|
|
923
1083
|
children: [
|
|
924
|
-
/* @__PURE__ */ jsxDEV4(
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1084
|
+
/* @__PURE__ */ jsxDEV4(StatCardGroup2, {
|
|
1085
|
+
children: [
|
|
1086
|
+
/* @__PURE__ */ jsxDEV4(StatCard2, {
|
|
1087
|
+
label: "Total Tools",
|
|
1088
|
+
value: data.total
|
|
1089
|
+
}, undefined, false, undefined, this),
|
|
1090
|
+
categoryStats.slice(0, 3).map(({ category, count }) => /* @__PURE__ */ jsxDEV4(StatCard2, {
|
|
1091
|
+
label: `${categoryIcons[category] ?? ""} ${category}`,
|
|
1092
|
+
value: count
|
|
1093
|
+
}, category, false, undefined, this))
|
|
1094
|
+
]
|
|
1095
|
+
}, undefined, true, undefined, this),
|
|
1096
|
+
Object.entries(groupedByCategory).map(([category, tools]) => /* @__PURE__ */ jsxDEV4("section", {
|
|
1097
|
+
className: "space-y-4",
|
|
937
1098
|
children: [
|
|
938
1099
|
/* @__PURE__ */ jsxDEV4("div", {
|
|
939
|
-
className: "
|
|
1100
|
+
className: "flex items-center gap-2",
|
|
940
1101
|
children: [
|
|
941
|
-
/* @__PURE__ */ jsxDEV4("
|
|
942
|
-
className: "text-
|
|
943
|
-
children:
|
|
1102
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
1103
|
+
className: "text-2xl",
|
|
1104
|
+
children: categoryIcons[category]
|
|
944
1105
|
}, undefined, false, undefined, this),
|
|
945
|
-
/* @__PURE__ */ jsxDEV4("
|
|
946
|
-
className: "
|
|
947
|
-
children:
|
|
948
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
949
|
-
className: "text-muted-foreground text-sm",
|
|
950
|
-
children: [
|
|
951
|
-
agent.modelProvider,
|
|
952
|
-
" / ",
|
|
953
|
-
agent.modelName
|
|
954
|
-
]
|
|
955
|
-
}, undefined, true, undefined, this),
|
|
956
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
957
|
-
className: `rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(agent.status)}`,
|
|
958
|
-
children: agent.status
|
|
959
|
-
}, undefined, false, undefined, this)
|
|
960
|
-
]
|
|
961
|
-
}, undefined, true, undefined, this),
|
|
962
|
-
agent.description && /* @__PURE__ */ jsxDEV4("p", {
|
|
963
|
-
className: "text-muted-foreground mt-2 text-sm",
|
|
964
|
-
children: agent.description
|
|
965
|
-
}, undefined, false, undefined, this)
|
|
966
|
-
]
|
|
967
|
-
}, undefined, true, undefined, this),
|
|
968
|
-
mode === "menu" && /* @__PURE__ */ jsxDEV4("div", {
|
|
969
|
-
className: "space-y-3",
|
|
970
|
-
children: [
|
|
971
|
-
agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV4(Button3, {
|
|
972
|
-
className: "w-full justify-start",
|
|
973
|
-
variant: "ghost",
|
|
974
|
-
onPress: () => setMode("execute"),
|
|
975
|
-
children: [
|
|
976
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
977
|
-
className: "mr-2",
|
|
978
|
-
children: "▶️"
|
|
979
|
-
}, undefined, false, undefined, this),
|
|
980
|
-
" Execute Agent"
|
|
981
|
-
]
|
|
982
|
-
}, undefined, true, undefined, this),
|
|
983
|
-
(agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxDEV4(Button3, {
|
|
984
|
-
className: "w-full justify-start",
|
|
985
|
-
variant: "ghost",
|
|
986
|
-
onPress: () => handleStatusChange("activate"),
|
|
987
|
-
disabled: isLoading,
|
|
988
|
-
children: [
|
|
989
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
990
|
-
className: "mr-2",
|
|
991
|
-
children: "\uD83D\uDFE2"
|
|
992
|
-
}, undefined, false, undefined, this),
|
|
993
|
-
" Activate Agent"
|
|
994
|
-
]
|
|
995
|
-
}, undefined, true, undefined, this),
|
|
996
|
-
agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV4(Button3, {
|
|
997
|
-
className: "w-full justify-start",
|
|
998
|
-
variant: "ghost",
|
|
999
|
-
onPress: () => handleStatusChange("pause"),
|
|
1000
|
-
disabled: isLoading,
|
|
1001
|
-
children: [
|
|
1002
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
1003
|
-
className: "mr-2",
|
|
1004
|
-
children: "⏸️"
|
|
1005
|
-
}, undefined, false, undefined, this),
|
|
1006
|
-
" Pause Agent"
|
|
1007
|
-
]
|
|
1008
|
-
}, undefined, true, undefined, this),
|
|
1009
|
-
agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxDEV4(Button3, {
|
|
1010
|
-
className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
|
|
1011
|
-
variant: "ghost",
|
|
1012
|
-
onPress: () => {
|
|
1013
|
-
setConfirmAction("archive");
|
|
1014
|
-
setMode("confirm");
|
|
1015
|
-
},
|
|
1016
|
-
children: [
|
|
1017
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
1018
|
-
className: "mr-2",
|
|
1019
|
-
children: "\uD83D\uDCE6"
|
|
1020
|
-
}, undefined, false, undefined, this),
|
|
1021
|
-
" Archive Agent"
|
|
1022
|
-
]
|
|
1023
|
-
}, undefined, true, undefined, this),
|
|
1024
|
-
agent.status === "ARCHIVED" && /* @__PURE__ */ jsxDEV4(Button3, {
|
|
1025
|
-
className: "w-full justify-start",
|
|
1026
|
-
variant: "ghost",
|
|
1027
|
-
onPress: () => handleStatusChange("activate"),
|
|
1028
|
-
disabled: isLoading,
|
|
1029
|
-
children: [
|
|
1030
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
1031
|
-
className: "mr-2",
|
|
1032
|
-
children: "\uD83D\uDD04"
|
|
1033
|
-
}, undefined, false, undefined, this),
|
|
1034
|
-
" Restore Agent"
|
|
1035
|
-
]
|
|
1036
|
-
}, undefined, true, undefined, this),
|
|
1037
|
-
error && /* @__PURE__ */ jsxDEV4("div", {
|
|
1038
|
-
className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
|
|
1039
|
-
children: error
|
|
1106
|
+
/* @__PURE__ */ jsxDEV4("h3", {
|
|
1107
|
+
className: "font-semibold text-lg",
|
|
1108
|
+
children: category
|
|
1040
1109
|
}, undefined, false, undefined, this),
|
|
1041
|
-
/* @__PURE__ */ jsxDEV4("
|
|
1042
|
-
className: "
|
|
1043
|
-
children:
|
|
1044
|
-
className: "w-full",
|
|
1045
|
-
variant: "outline",
|
|
1046
|
-
onPress: handleClose,
|
|
1047
|
-
children: "Close"
|
|
1048
|
-
}, undefined, false, undefined, this)
|
|
1110
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
1111
|
+
className: "rounded-full bg-muted px-2 py-0.5 text-muted-foreground text-xs",
|
|
1112
|
+
children: tools.length
|
|
1049
1113
|
}, undefined, false, undefined, this)
|
|
1050
1114
|
]
|
|
1051
1115
|
}, undefined, true, undefined, this),
|
|
1052
|
-
|
|
1053
|
-
className: "
|
|
1054
|
-
children:
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
htmlFor: "execute-message",
|
|
1059
|
-
className: "text-muted-foreground mb-1 block text-sm font-medium",
|
|
1060
|
-
children: "Message *"
|
|
1061
|
-
}, undefined, false, undefined, this),
|
|
1062
|
-
/* @__PURE__ */ jsxDEV4("textarea", {
|
|
1063
|
-
id: "execute-message",
|
|
1064
|
-
value: message,
|
|
1065
|
-
onChange: (e) => setMessage(e.target.value),
|
|
1066
|
-
placeholder: "Enter your message to the agent...",
|
|
1067
|
-
rows: 4,
|
|
1068
|
-
disabled: isLoading,
|
|
1069
|
-
className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
|
|
1070
|
-
}, undefined, false, undefined, this)
|
|
1071
|
-
]
|
|
1072
|
-
}, undefined, true, undefined, this),
|
|
1073
|
-
error && /* @__PURE__ */ jsxDEV4("div", {
|
|
1074
|
-
className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
|
|
1075
|
-
children: error
|
|
1076
|
-
}, undefined, false, undefined, this),
|
|
1077
|
-
/* @__PURE__ */ jsxDEV4("div", {
|
|
1078
|
-
className: "flex justify-end gap-3 pt-2",
|
|
1079
|
-
children: [
|
|
1080
|
-
/* @__PURE__ */ jsxDEV4(Button3, {
|
|
1081
|
-
variant: "ghost",
|
|
1082
|
-
onPress: () => setMode("menu"),
|
|
1083
|
-
disabled: isLoading,
|
|
1084
|
-
children: "Back"
|
|
1085
|
-
}, undefined, false, undefined, this),
|
|
1086
|
-
/* @__PURE__ */ jsxDEV4(Button3, {
|
|
1087
|
-
onPress: handleExecute,
|
|
1088
|
-
disabled: isLoading,
|
|
1089
|
-
children: isLoading ? "Executing..." : "▶️ Execute"
|
|
1090
|
-
}, undefined, false, undefined, this)
|
|
1091
|
-
]
|
|
1092
|
-
}, undefined, true, undefined, this)
|
|
1093
|
-
]
|
|
1094
|
-
}, undefined, true, undefined, this),
|
|
1095
|
-
mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxDEV4("div", {
|
|
1096
|
-
className: "space-y-4",
|
|
1097
|
-
children: [
|
|
1098
|
-
/* @__PURE__ */ jsxDEV4("p", {
|
|
1099
|
-
className: "text-muted-foreground",
|
|
1100
|
-
children: [
|
|
1101
|
-
"Are you sure you want to archive",
|
|
1102
|
-
" ",
|
|
1103
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
1104
|
-
className: "text-foreground font-medium",
|
|
1105
|
-
children: agent.name
|
|
1106
|
-
}, undefined, false, undefined, this),
|
|
1107
|
-
"?"
|
|
1108
|
-
]
|
|
1109
|
-
}, undefined, true, undefined, this),
|
|
1110
|
-
/* @__PURE__ */ jsxDEV4("p", {
|
|
1116
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
1117
|
+
className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
1118
|
+
children: tools.map((tool) => /* @__PURE__ */ jsxDEV4(EntityCard, {
|
|
1119
|
+
cardTitle: tool.name,
|
|
1120
|
+
cardSubtitle: `v${tool.version}`,
|
|
1121
|
+
meta: /* @__PURE__ */ jsxDEV4("p", {
|
|
1111
1122
|
className: "text-muted-foreground text-sm",
|
|
1112
|
-
children:
|
|
1123
|
+
children: tool.description
|
|
1113
1124
|
}, undefined, false, undefined, this),
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1125
|
+
chips: /* @__PURE__ */ jsxDEV4(StatusChip2, {
|
|
1126
|
+
tone: getStatusTone2(tool.status),
|
|
1127
|
+
label: tool.status
|
|
1117
1128
|
}, undefined, false, undefined, this),
|
|
1118
|
-
/* @__PURE__ */ jsxDEV4("
|
|
1119
|
-
className: "
|
|
1120
|
-
children:
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
children: "Cancel"
|
|
1126
|
-
}, undefined, false, undefined, this),
|
|
1127
|
-
/* @__PURE__ */ jsxDEV4(Button3, {
|
|
1128
|
-
onPress: () => handleStatusChange("archive"),
|
|
1129
|
-
disabled: isLoading,
|
|
1130
|
-
children: isLoading ? "Archiving..." : "\uD83D\uDCE6 Archive"
|
|
1131
|
-
}, undefined, false, undefined, this)
|
|
1132
|
-
]
|
|
1133
|
-
}, undefined, true, undefined, this)
|
|
1134
|
-
]
|
|
1135
|
-
}, undefined, true, undefined, this)
|
|
1129
|
+
footer: /* @__PURE__ */ jsxDEV4("code", {
|
|
1130
|
+
className: "text-muted-foreground text-xs",
|
|
1131
|
+
children: tool.name
|
|
1132
|
+
}, undefined, false, undefined, this),
|
|
1133
|
+
onClick: onToolClick ? () => onToolClick(tool.id) : undefined
|
|
1134
|
+
}, tool.id, false, undefined, this))
|
|
1135
|
+
}, undefined, false, undefined, this)
|
|
1136
1136
|
]
|
|
1137
|
-
},
|
|
1137
|
+
}, category, true, undefined, this))
|
|
1138
1138
|
]
|
|
1139
1139
|
}, undefined, true, undefined, this);
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
1142
1142
|
// src/ui/AgentDashboard.tsx
|
|
1143
|
-
import { useState as useState7, useMemo as useMemo3, useCallback as useCallback5 } from "react";
|
|
1144
1143
|
import {
|
|
1144
|
+
Button as Button4,
|
|
1145
1145
|
StatCard as StatCard3,
|
|
1146
|
-
StatCardGroup as StatCardGroup3
|
|
1147
|
-
Button as Button4
|
|
1146
|
+
StatCardGroup as StatCardGroup3
|
|
1148
1147
|
} from "@contractspec/lib.design-system";
|
|
1148
|
+
import { useCallback as useCallback5, useMemo as useMemo3, useState as useState7 } from "react";
|
|
1149
1149
|
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
1150
1150
|
"use client";
|
|
1151
1151
|
function AgentDashboard() {
|
|
@@ -1210,7 +1210,7 @@ function AgentDashboard() {
|
|
|
1210
1210
|
className: "flex items-center justify-between",
|
|
1211
1211
|
children: [
|
|
1212
1212
|
/* @__PURE__ */ jsxDEV5("h2", {
|
|
1213
|
-
className: "text-2xl
|
|
1213
|
+
className: "font-bold text-2xl",
|
|
1214
1214
|
children: "AI Agent Console"
|
|
1215
1215
|
}, undefined, false, undefined, this),
|
|
1216
1216
|
/* @__PURE__ */ jsxDEV5(Button4, {
|
|
@@ -1233,14 +1233,14 @@ function AgentDashboard() {
|
|
|
1233
1233
|
}, i, false, undefined, this))
|
|
1234
1234
|
}, undefined, false, undefined, this),
|
|
1235
1235
|
/* @__PURE__ */ jsxDEV5("nav", {
|
|
1236
|
-
className: "
|
|
1236
|
+
className: "flex gap-1 rounded-lg bg-muted p-1",
|
|
1237
1237
|
role: "tablist",
|
|
1238
1238
|
children: tabs.map((tab) => /* @__PURE__ */ jsxDEV5("button", {
|
|
1239
1239
|
type: "button",
|
|
1240
1240
|
role: "tab",
|
|
1241
1241
|
"aria-selected": activeTab === tab.id,
|
|
1242
1242
|
onClick: () => setActiveTab(tab.id),
|
|
1243
|
-
className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm
|
|
1243
|
+
className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 font-medium text-sm transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
|
|
1244
1244
|
children: [
|
|
1245
1245
|
/* @__PURE__ */ jsxDEV5("span", {
|
|
1246
1246
|
children: tab.icon
|
|
@@ -1301,13 +1301,13 @@ function AgentListViewWithActions({
|
|
|
1301
1301
|
const { data, loading, error, stats, refetch } = useAgentList();
|
|
1302
1302
|
if (loading && !data) {
|
|
1303
1303
|
return /* @__PURE__ */ jsxDEV5("div", {
|
|
1304
|
-
className: "
|
|
1304
|
+
className: "flex h-64 items-center justify-center text-muted-foreground",
|
|
1305
1305
|
children: "Loading agents..."
|
|
1306
1306
|
}, undefined, false, undefined, this);
|
|
1307
1307
|
}
|
|
1308
1308
|
if (error) {
|
|
1309
1309
|
return /* @__PURE__ */ jsxDEV5("div", {
|
|
1310
|
-
className: "
|
|
1310
|
+
className: "flex h-64 flex-col items-center justify-center text-destructive",
|
|
1311
1311
|
children: [
|
|
1312
1312
|
/* @__PURE__ */ jsxDEV5("p", {
|
|
1313
1313
|
children: [
|
|
@@ -1326,10 +1326,10 @@ function AgentListViewWithActions({
|
|
|
1326
1326
|
}
|
|
1327
1327
|
if (!data?.items.length) {
|
|
1328
1328
|
return /* @__PURE__ */ jsxDEV5("div", {
|
|
1329
|
-
className: "
|
|
1329
|
+
className: "flex h-64 flex-col items-center justify-center text-muted-foreground",
|
|
1330
1330
|
children: [
|
|
1331
1331
|
/* @__PURE__ */ jsxDEV5("p", {
|
|
1332
|
-
className: "text-lg
|
|
1332
|
+
className: "font-medium text-lg",
|
|
1333
1333
|
children: "No agents yet"
|
|
1334
1334
|
}, undefined, false, undefined, this),
|
|
1335
1335
|
/* @__PURE__ */ jsxDEV5("p", {
|
|
@@ -1393,7 +1393,7 @@ function AgentCard({ agent, onClick }) {
|
|
|
1393
1393
|
};
|
|
1394
1394
|
return /* @__PURE__ */ jsxDEV5("div", {
|
|
1395
1395
|
onClick,
|
|
1396
|
-
className: "
|
|
1396
|
+
className: "cursor-pointer rounded-xl border border-border bg-card p-4 transition-all hover:shadow-md",
|
|
1397
1397
|
role: "button",
|
|
1398
1398
|
tabIndex: 0,
|
|
1399
1399
|
onKeyDown: (e) => {
|
|
@@ -1422,13 +1422,13 @@ function AgentCard({ agent, onClick }) {
|
|
|
1422
1422
|
]
|
|
1423
1423
|
}, undefined, true, undefined, this),
|
|
1424
1424
|
/* @__PURE__ */ jsxDEV5("span", {
|
|
1425
|
-
className: `rounded-full px-2 py-0.5 text-xs
|
|
1425
|
+
className: `rounded-full px-2 py-0.5 font-medium text-xs ${statusColors[agent.status]}`,
|
|
1426
1426
|
children: agent.status
|
|
1427
1427
|
}, undefined, false, undefined, this)
|
|
1428
1428
|
]
|
|
1429
1429
|
}, undefined, true, undefined, this),
|
|
1430
1430
|
agent.description && /* @__PURE__ */ jsxDEV5("p", {
|
|
1431
|
-
className: "
|
|
1431
|
+
className: "mt-2 line-clamp-2 text-muted-foreground text-sm",
|
|
1432
1432
|
children: agent.description
|
|
1433
1433
|
}, undefined, false, undefined, this),
|
|
1434
1434
|
/* @__PURE__ */ jsxDEV5("div", {
|
|
@@ -1452,7 +1452,7 @@ function AgentCard({ agent, onClick }) {
|
|
|
1452
1452
|
function MetricsView({ metrics }) {
|
|
1453
1453
|
if (!metrics) {
|
|
1454
1454
|
return /* @__PURE__ */ jsxDEV5("div", {
|
|
1455
|
-
className: "
|
|
1455
|
+
className: "flex h-64 items-center justify-center text-muted-foreground",
|
|
1456
1456
|
children: "Loading metrics..."
|
|
1457
1457
|
}, undefined, false, undefined, this);
|
|
1458
1458
|
}
|
|
@@ -1462,14 +1462,14 @@ function MetricsView({ metrics }) {
|
|
|
1462
1462
|
className: "space-y-6",
|
|
1463
1463
|
children: [
|
|
1464
1464
|
/* @__PURE__ */ jsxDEV5("h3", {
|
|
1465
|
-
className: "text-lg
|
|
1465
|
+
className: "font-semibold text-lg",
|
|
1466
1466
|
children: "Usage Analytics"
|
|
1467
1467
|
}, undefined, false, undefined, this),
|
|
1468
1468
|
/* @__PURE__ */ jsxDEV5("div", {
|
|
1469
1469
|
className: "grid gap-6 md:grid-cols-2",
|
|
1470
1470
|
children: [
|
|
1471
1471
|
/* @__PURE__ */ jsxDEV5("div", {
|
|
1472
|
-
className: "border-border bg-card
|
|
1472
|
+
className: "rounded-xl border border-border bg-card p-4",
|
|
1473
1473
|
children: [
|
|
1474
1474
|
/* @__PURE__ */ jsxDEV5("h4", {
|
|
1475
1475
|
className: "font-medium",
|
|
@@ -1495,7 +1495,7 @@ function MetricsView({ metrics }) {
|
|
|
1495
1495
|
]
|
|
1496
1496
|
}, undefined, true, undefined, this),
|
|
1497
1497
|
/* @__PURE__ */ jsxDEV5("div", {
|
|
1498
|
-
className: "border-border bg-card
|
|
1498
|
+
className: "rounded-xl border border-border bg-card p-4",
|
|
1499
1499
|
children: [
|
|
1500
1500
|
/* @__PURE__ */ jsxDEV5("h4", {
|
|
1501
1501
|
className: "font-medium",
|
|
@@ -1511,7 +1511,7 @@ function MetricsView({ metrics }) {
|
|
|
1511
1511
|
children: "Avg Duration"
|
|
1512
1512
|
}, undefined, false, undefined, this),
|
|
1513
1513
|
/* @__PURE__ */ jsxDEV5("dd", {
|
|
1514
|
-
className: "text-xl
|
|
1514
|
+
className: "font-semibold text-xl",
|
|
1515
1515
|
children: [
|
|
1516
1516
|
(metrics.averageDurationMs / 1000).toFixed(1),
|
|
1517
1517
|
"s"
|
|
@@ -1526,7 +1526,7 @@ function MetricsView({ metrics }) {
|
|
|
1526
1526
|
children: "Success Rate"
|
|
1527
1527
|
}, undefined, false, undefined, this),
|
|
1528
1528
|
/* @__PURE__ */ jsxDEV5("dd", {
|
|
1529
|
-
className: "text-xl
|
|
1529
|
+
className: "font-semibold text-xl",
|
|
1530
1530
|
children: [
|
|
1531
1531
|
(metrics.successRate * 100).toFixed(0),
|
|
1532
1532
|
"%"
|
|
@@ -1541,7 +1541,7 @@ function MetricsView({ metrics }) {
|
|
|
1541
1541
|
]
|
|
1542
1542
|
}, undefined, true, undefined, this),
|
|
1543
1543
|
/* @__PURE__ */ jsxDEV5("div", {
|
|
1544
|
-
className: "border-border bg-card
|
|
1544
|
+
className: "rounded-xl border border-border bg-card p-4",
|
|
1545
1545
|
children: [
|
|
1546
1546
|
/* @__PURE__ */ jsxDEV5("h4", {
|
|
1547
1547
|
className: "font-medium",
|
|
@@ -1557,7 +1557,7 @@ function MetricsView({ metrics }) {
|
|
|
1557
1557
|
children: "Total Runs"
|
|
1558
1558
|
}, undefined, false, undefined, this),
|
|
1559
1559
|
/* @__PURE__ */ jsxDEV5("dd", {
|
|
1560
|
-
className: "text-2xl
|
|
1560
|
+
className: "font-semibold text-2xl",
|
|
1561
1561
|
children: metrics.totalRuns.toLocaleString()
|
|
1562
1562
|
}, undefined, false, undefined, this)
|
|
1563
1563
|
]
|
|
@@ -1569,7 +1569,7 @@ function MetricsView({ metrics }) {
|
|
|
1569
1569
|
children: "Total Tokens"
|
|
1570
1570
|
}, undefined, false, undefined, this),
|
|
1571
1571
|
/* @__PURE__ */ jsxDEV5("dd", {
|
|
1572
|
-
className: "text-2xl
|
|
1572
|
+
className: "font-semibold text-2xl",
|
|
1573
1573
|
children: [
|
|
1574
1574
|
(metrics.totalTokens / 1000).toFixed(0),
|
|
1575
1575
|
"K"
|
|
@@ -1584,7 +1584,7 @@ function MetricsView({ metrics }) {
|
|
|
1584
1584
|
children: "Cost per Run"
|
|
1585
1585
|
}, undefined, false, undefined, this),
|
|
1586
1586
|
/* @__PURE__ */ jsxDEV5("dd", {
|
|
1587
|
-
className: "text-2xl
|
|
1587
|
+
className: "font-semibold text-2xl",
|
|
1588
1588
|
children: [
|
|
1589
1589
|
"$",
|
|
1590
1590
|
metrics.totalRuns > 0 ? (metrics.totalCostUsd / metrics.totalRuns).toFixed(4) : "0"
|
|
@@ -1626,7 +1626,7 @@ function ProgressBar({
|
|
|
1626
1626
|
]
|
|
1627
1627
|
}, undefined, true, undefined, this),
|
|
1628
1628
|
/* @__PURE__ */ jsxDEV5("div", {
|
|
1629
|
-
className: "
|
|
1629
|
+
className: "mt-1 h-2 overflow-hidden rounded-full bg-muted",
|
|
1630
1630
|
children: /* @__PURE__ */ jsxDEV5("div", {
|
|
1631
1631
|
className: `h-full ${color}`,
|
|
1632
1632
|
style: { width: `${pct}%` }
|