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