@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
package/dist/ui/index.js
CHANGED
|
@@ -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
|
-
return "-";
|
|
100
|
-
return `$${cost.toFixed(4)}`;
|
|
101
|
-
}
|
|
102
|
-
function RunListView({ agentId, onRunClick }) {
|
|
103
|
-
const { data, metrics, loading, error, refetch } = useRunList({ agentId });
|
|
104
|
-
if (loading && !data) {
|
|
105
|
-
return /* @__PURE__ */ jsxDEV(LoaderBlock, {
|
|
106
|
-
label: "Loading runs..."
|
|
107
|
-
}, undefined, false, undefined, this);
|
|
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);
|
|
259
238
|
setError(null);
|
|
239
|
+
};
|
|
240
|
+
const handleClose = () => {
|
|
241
|
+
resetForm();
|
|
242
|
+
onClose();
|
|
243
|
+
};
|
|
244
|
+
const handleExecute = async () => {
|
|
245
|
+
if (!agent)
|
|
246
|
+
return;
|
|
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),
|
|
698
|
-
/* @__PURE__ */
|
|
699
|
-
className: "
|
|
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",
|
|
700
603
|
children: [
|
|
701
|
-
/* @__PURE__ */
|
|
702
|
-
className: "mb-4 text-xl
|
|
604
|
+
/* @__PURE__ */ jsxDEV2("h2", {
|
|
605
|
+
className: "mb-4 font-semibold text-xl",
|
|
703
606
|
children: "Create New Agent"
|
|
704
607
|
}, undefined, false, undefined, this),
|
|
705
|
-
/* @__PURE__ */
|
|
706
|
-
onSubmit: handleSubmit,
|
|
707
|
-
className: "space-y-4",
|
|
708
|
-
children: [
|
|
709
|
-
/* @__PURE__ */
|
|
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),
|
|
835
|
+
/* @__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}%` }
|
|
@@ -1643,133 +1643,67 @@ function ProgressBar({
|
|
|
1643
1643
|
// src/ui/AgentToolRegistry.tsx
|
|
1644
1644
|
"use client";
|
|
1645
1645
|
|
|
1646
|
-
// src/ui/views/AgentListView.tsx
|
|
1647
|
-
import {
|
|
1648
|
-
Button as Button5,
|
|
1649
|
-
StatCard as StatCard4,
|
|
1650
|
-
StatCardGroup as StatCardGroup4,
|
|
1651
|
-
EntityCard as EntityCard2,
|
|
1652
|
-
StatusChip as StatusChip3,
|
|
1653
|
-
LoaderBlock as LoaderBlock3,
|
|
1654
|
-
ErrorState as ErrorState3,
|
|
1655
|
-
EmptyState as EmptyState3
|
|
1656
|
-
} from "@contractspec/lib.design-system";
|
|
1657
|
-
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
1658
|
-
"use client";
|
|
1659
|
-
function getStatusTone3(status) {
|
|
1660
|
-
switch (status) {
|
|
1661
|
-
case "ACTIVE":
|
|
1662
|
-
return "success";
|
|
1663
|
-
case "PAUSED":
|
|
1664
|
-
case "DRAFT":
|
|
1665
|
-
return "warning";
|
|
1666
|
-
case "ARCHIVED":
|
|
1667
|
-
return "neutral";
|
|
1668
|
-
default:
|
|
1669
|
-
return "neutral";
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
function AgentListView() {
|
|
1673
|
-
const { data, loading, error, stats, refetch } = useAgentList();
|
|
1674
|
-
if (loading && !data) {
|
|
1675
|
-
return /* @__PURE__ */ jsxDEV6(LoaderBlock3, {
|
|
1676
|
-
label: "Loading agents..."
|
|
1677
|
-
}, undefined, false, undefined, this);
|
|
1678
|
-
}
|
|
1679
|
-
if (error) {
|
|
1680
|
-
return /* @__PURE__ */ jsxDEV6(ErrorState3, {
|
|
1681
|
-
title: "Failed to load agents",
|
|
1682
|
-
description: error.message,
|
|
1683
|
-
onRetry: refetch,
|
|
1684
|
-
retryLabel: "Retry"
|
|
1685
|
-
}, undefined, false, undefined, this);
|
|
1686
|
-
}
|
|
1687
|
-
if (!data?.items.length) {
|
|
1688
|
-
return /* @__PURE__ */ jsxDEV6(EmptyState3, {
|
|
1689
|
-
title: "No agents yet",
|
|
1690
|
-
description: "Create your first AI agent to get started."
|
|
1691
|
-
}, undefined, false, undefined, this);
|
|
1692
|
-
}
|
|
1693
|
-
return /* @__PURE__ */ jsxDEV6("div", {
|
|
1694
|
-
className: "space-y-6",
|
|
1695
|
-
children: [
|
|
1696
|
-
stats && /* @__PURE__ */ jsxDEV6(StatCardGroup4, {
|
|
1697
|
-
children: [
|
|
1698
|
-
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1699
|
-
label: "Total Agents",
|
|
1700
|
-
value: stats.total
|
|
1701
|
-
}, undefined, false, undefined, this),
|
|
1702
|
-
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1703
|
-
label: "Active",
|
|
1704
|
-
value: stats.active
|
|
1705
|
-
}, undefined, false, undefined, this),
|
|
1706
|
-
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1707
|
-
label: "Paused",
|
|
1708
|
-
value: stats.paused
|
|
1709
|
-
}, undefined, false, undefined, this),
|
|
1710
|
-
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1711
|
-
label: "Draft",
|
|
1712
|
-
value: stats.draft
|
|
1713
|
-
}, undefined, false, undefined, this)
|
|
1714
|
-
]
|
|
1715
|
-
}, undefined, true, undefined, this),
|
|
1716
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
1717
|
-
className: "flex items-center justify-between",
|
|
1718
|
-
children: [
|
|
1719
|
-
/* @__PURE__ */ jsxDEV6("h3", {
|
|
1720
|
-
className: "text-lg font-semibold",
|
|
1721
|
-
children: "Agents"
|
|
1722
|
-
}, undefined, false, undefined, this),
|
|
1723
|
-
/* @__PURE__ */ jsxDEV6(Button5, {
|
|
1724
|
-
onPress: () => alert("Create Agent clicked!"),
|
|
1725
|
-
children: "Create Agent"
|
|
1726
|
-
}, undefined, false, undefined, this)
|
|
1727
|
-
]
|
|
1728
|
-
}, undefined, true, undefined, this),
|
|
1729
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
1730
|
-
className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
1731
|
-
children: data.items.map((agent) => /* @__PURE__ */ jsxDEV6(EntityCard2, {
|
|
1732
|
-
cardTitle: agent.name,
|
|
1733
|
-
cardSubtitle: agent.modelName,
|
|
1734
|
-
meta: /* @__PURE__ */ jsxDEV6("p", {
|
|
1735
|
-
className: "text-muted-foreground text-sm",
|
|
1736
|
-
children: agent.description
|
|
1737
|
-
}, undefined, false, undefined, this),
|
|
1738
|
-
chips: /* @__PURE__ */ jsxDEV6(StatusChip3, {
|
|
1739
|
-
tone: getStatusTone3(agent.status),
|
|
1740
|
-
label: agent.status
|
|
1741
|
-
}, undefined, false, undefined, this),
|
|
1742
|
-
footer: /* @__PURE__ */ jsxDEV6("span", {
|
|
1743
|
-
className: "text-muted-foreground text-xs",
|
|
1744
|
-
children: [
|
|
1745
|
-
"Created ",
|
|
1746
|
-
agent.createdAt.toLocaleDateString()
|
|
1747
|
-
]
|
|
1748
|
-
}, undefined, true, undefined, this),
|
|
1749
|
-
onClick: () => alert(`View agent: ${agent.name}`)
|
|
1750
|
-
}, agent.id, false, undefined, this))
|
|
1751
|
-
}, undefined, false, undefined, this)
|
|
1752
|
-
]
|
|
1753
|
-
}, undefined, true, undefined, this);
|
|
1754
|
-
}
|
|
1755
1646
|
// src/ui/hooks/index.ts
|
|
1756
1647
|
"use client";
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1648
|
+
// src/ui/overlays/demo-overlays.ts
|
|
1649
|
+
var agentConsoleDemoOverlay = {
|
|
1650
|
+
overlayId: "agent-console.demo-user",
|
|
1651
|
+
version: "1.0.0",
|
|
1652
|
+
description: "Simplifies agent console for demo users",
|
|
1653
|
+
appliesTo: {
|
|
1654
|
+
feature: "agent-console",
|
|
1655
|
+
role: "demo"
|
|
1656
|
+
},
|
|
1657
|
+
modifications: [
|
|
1658
|
+
{
|
|
1659
|
+
type: "hideField",
|
|
1660
|
+
field: "modelConfig",
|
|
1661
|
+
reason: "Advanced config not relevant for demo"
|
|
1662
|
+
},
|
|
1663
|
+
{
|
|
1664
|
+
type: "hideField",
|
|
1665
|
+
field: "webhookConfig",
|
|
1666
|
+
reason: "Integration not available in demo"
|
|
1667
|
+
},
|
|
1668
|
+
{
|
|
1669
|
+
type: "renameLabel",
|
|
1670
|
+
field: "systemPrompt",
|
|
1671
|
+
newLabel: "Agent Instructions"
|
|
1672
|
+
},
|
|
1673
|
+
{
|
|
1674
|
+
type: "addBadge",
|
|
1675
|
+
position: "header",
|
|
1676
|
+
label: "Demo Mode",
|
|
1677
|
+
variant: "warning"
|
|
1765
1678
|
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1679
|
+
]
|
|
1680
|
+
};
|
|
1681
|
+
var agentConsoleReadOnlyOverlay = {
|
|
1682
|
+
overlayId: "agent-console.read-only",
|
|
1683
|
+
version: "1.0.0",
|
|
1684
|
+
description: "Read-only view for non-admin users",
|
|
1685
|
+
appliesTo: {
|
|
1686
|
+
feature: "agent-console",
|
|
1687
|
+
role: "viewer"
|
|
1688
|
+
},
|
|
1689
|
+
modifications: [
|
|
1690
|
+
{
|
|
1691
|
+
type: "hideField",
|
|
1692
|
+
field: "deleteButton",
|
|
1693
|
+
reason: "No delete permission"
|
|
1694
|
+
},
|
|
1695
|
+
{ type: "hideField", field: "editButton", reason: "No edit permission" },
|
|
1696
|
+
{
|
|
1697
|
+
type: "hideField",
|
|
1698
|
+
field: "createButton",
|
|
1699
|
+
reason: "No create permission"
|
|
1768
1700
|
}
|
|
1769
|
-
|
|
1770
|
-
}
|
|
1701
|
+
]
|
|
1771
1702
|
};
|
|
1772
|
-
|
|
1703
|
+
var agentConsoleOverlays = [
|
|
1704
|
+
agentConsoleDemoOverlay,
|
|
1705
|
+
agentConsoleReadOnlyOverlay
|
|
1706
|
+
];
|
|
1773
1707
|
// src/ui/renderers/agent-list.markdown.ts
|
|
1774
1708
|
import {
|
|
1775
1709
|
mockListAgentsHandler
|
|
@@ -1823,107 +1757,138 @@ var agentListMarkdownRenderer = {
|
|
|
1823
1757
|
}
|
|
1824
1758
|
};
|
|
1825
1759
|
|
|
1826
|
-
// src/ui/
|
|
1827
|
-
import {
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1760
|
+
// src/ui/views/AgentListView.tsx
|
|
1761
|
+
import {
|
|
1762
|
+
Button as Button5,
|
|
1763
|
+
EmptyState as EmptyState3,
|
|
1764
|
+
EntityCard as EntityCard2,
|
|
1765
|
+
ErrorState as ErrorState3,
|
|
1766
|
+
LoaderBlock as LoaderBlock3,
|
|
1767
|
+
StatCard as StatCard4,
|
|
1768
|
+
StatCardGroup as StatCardGroup4,
|
|
1769
|
+
StatusChip as StatusChip3
|
|
1770
|
+
} from "@contractspec/lib.design-system";
|
|
1771
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
1772
|
+
"use client";
|
|
1773
|
+
function getStatusTone3(status) {
|
|
1774
|
+
switch (status) {
|
|
1775
|
+
case "ACTIVE":
|
|
1776
|
+
return "success";
|
|
1777
|
+
case "PAUSED":
|
|
1778
|
+
case "DRAFT":
|
|
1779
|
+
return "warning";
|
|
1780
|
+
case "ARCHIVED":
|
|
1781
|
+
return "neutral";
|
|
1782
|
+
default:
|
|
1783
|
+
return "neutral";
|
|
1784
|
+
}
|
|
1834
1785
|
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
"",
|
|
1853
|
-
"
|
|
1854
|
-
|
|
1855
|
-
"| ID | Agent | Status | Duration | Tokens | Cost |",
|
|
1856
|
-
"| --- | --- | --- | --- | --- | --- |"
|
|
1857
|
-
];
|
|
1858
|
-
for (const run of data.items.slice(0, 10)) {
|
|
1859
|
-
lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration2(run.durationMs) : "-"} | ${run.totalTokens} | $${run.estimatedCostUsd?.toFixed(4) ?? "-"} |`);
|
|
1860
|
-
}
|
|
1861
|
-
return {
|
|
1862
|
-
mimeType: "text/markdown",
|
|
1863
|
-
body: lines.join(`
|
|
1864
|
-
`)
|
|
1865
|
-
};
|
|
1786
|
+
function AgentListView() {
|
|
1787
|
+
const { data, loading, error, stats, refetch } = useAgentList();
|
|
1788
|
+
if (loading && !data) {
|
|
1789
|
+
return /* @__PURE__ */ jsxDEV6(LoaderBlock3, {
|
|
1790
|
+
label: "Loading agents..."
|
|
1791
|
+
}, undefined, false, undefined, this);
|
|
1792
|
+
}
|
|
1793
|
+
if (error) {
|
|
1794
|
+
return /* @__PURE__ */ jsxDEV6(ErrorState3, {
|
|
1795
|
+
title: "Failed to load agents",
|
|
1796
|
+
description: error.message,
|
|
1797
|
+
onRetry: refetch,
|
|
1798
|
+
retryLabel: "Retry"
|
|
1799
|
+
}, undefined, false, undefined, this);
|
|
1800
|
+
}
|
|
1801
|
+
if (!data?.items.length) {
|
|
1802
|
+
return /* @__PURE__ */ jsxDEV6(EmptyState3, {
|
|
1803
|
+
title: "No agents yet",
|
|
1804
|
+
description: "Create your first AI agent to get started."
|
|
1805
|
+
}, undefined, false, undefined, this);
|
|
1866
1806
|
}
|
|
1867
|
-
|
|
1807
|
+
return /* @__PURE__ */ jsxDEV6("div", {
|
|
1808
|
+
className: "space-y-6",
|
|
1809
|
+
children: [
|
|
1810
|
+
stats && /* @__PURE__ */ jsxDEV6(StatCardGroup4, {
|
|
1811
|
+
children: [
|
|
1812
|
+
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1813
|
+
label: "Total Agents",
|
|
1814
|
+
value: stats.total
|
|
1815
|
+
}, undefined, false, undefined, this),
|
|
1816
|
+
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1817
|
+
label: "Active",
|
|
1818
|
+
value: stats.active
|
|
1819
|
+
}, undefined, false, undefined, this),
|
|
1820
|
+
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1821
|
+
label: "Paused",
|
|
1822
|
+
value: stats.paused
|
|
1823
|
+
}, undefined, false, undefined, this),
|
|
1824
|
+
/* @__PURE__ */ jsxDEV6(StatCard4, {
|
|
1825
|
+
label: "Draft",
|
|
1826
|
+
value: stats.draft
|
|
1827
|
+
}, undefined, false, undefined, this)
|
|
1828
|
+
]
|
|
1829
|
+
}, undefined, true, undefined, this),
|
|
1830
|
+
/* @__PURE__ */ jsxDEV6("div", {
|
|
1831
|
+
className: "flex items-center justify-between",
|
|
1832
|
+
children: [
|
|
1833
|
+
/* @__PURE__ */ jsxDEV6("h3", {
|
|
1834
|
+
className: "font-semibold text-lg",
|
|
1835
|
+
children: "Agents"
|
|
1836
|
+
}, undefined, false, undefined, this),
|
|
1837
|
+
/* @__PURE__ */ jsxDEV6(Button5, {
|
|
1838
|
+
onPress: () => alert("Create Agent clicked!"),
|
|
1839
|
+
children: "Create Agent"
|
|
1840
|
+
}, undefined, false, undefined, this)
|
|
1841
|
+
]
|
|
1842
|
+
}, undefined, true, undefined, this),
|
|
1843
|
+
/* @__PURE__ */ jsxDEV6("div", {
|
|
1844
|
+
className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
1845
|
+
children: data.items.map((agent) => /* @__PURE__ */ jsxDEV6(EntityCard2, {
|
|
1846
|
+
cardTitle: agent.name,
|
|
1847
|
+
cardSubtitle: agent.modelName,
|
|
1848
|
+
meta: /* @__PURE__ */ jsxDEV6("p", {
|
|
1849
|
+
className: "text-muted-foreground text-sm",
|
|
1850
|
+
children: agent.description
|
|
1851
|
+
}, undefined, false, undefined, this),
|
|
1852
|
+
chips: /* @__PURE__ */ jsxDEV6(StatusChip3, {
|
|
1853
|
+
tone: getStatusTone3(agent.status),
|
|
1854
|
+
label: agent.status
|
|
1855
|
+
}, undefined, false, undefined, this),
|
|
1856
|
+
footer: /* @__PURE__ */ jsxDEV6("span", {
|
|
1857
|
+
className: "text-muted-foreground text-xs",
|
|
1858
|
+
children: [
|
|
1859
|
+
"Created ",
|
|
1860
|
+
agent.createdAt.toLocaleDateString()
|
|
1861
|
+
]
|
|
1862
|
+
}, undefined, true, undefined, this),
|
|
1863
|
+
onClick: () => alert(`View agent: ${agent.name}`)
|
|
1864
|
+
}, agent.id, false, undefined, this))
|
|
1865
|
+
}, undefined, false, undefined, this)
|
|
1866
|
+
]
|
|
1867
|
+
}, undefined, true, undefined, this);
|
|
1868
|
+
}
|
|
1868
1869
|
|
|
1869
|
-
// src/ui/renderers/
|
|
1870
|
-
import {
|
|
1871
|
-
var
|
|
1872
|
-
target: "
|
|
1870
|
+
// src/ui/renderers/agent-list.renderer.tsx
|
|
1871
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
1872
|
+
var agentListReactRenderer = {
|
|
1873
|
+
target: "react",
|
|
1873
1874
|
render: async (desc) => {
|
|
1874
|
-
if (desc.source.type !== "component"
|
|
1875
|
-
throw new Error("
|
|
1876
|
-
}
|
|
1877
|
-
const data = await mockListToolsHandler({
|
|
1878
|
-
organizationId: "demo-org",
|
|
1879
|
-
limit: 50,
|
|
1880
|
-
offset: 0
|
|
1881
|
-
});
|
|
1882
|
-
const lines = [
|
|
1883
|
-
`# ${desc.meta.description ?? "Tool Registry"}`,
|
|
1884
|
-
"",
|
|
1885
|
-
`> ${desc.meta.key} v${desc.meta.version}`,
|
|
1886
|
-
"",
|
|
1887
|
-
`**Total Tools:** ${data.total}`,
|
|
1888
|
-
""
|
|
1889
|
-
];
|
|
1890
|
-
const byCategory = {};
|
|
1891
|
-
for (const tool of data.items) {
|
|
1892
|
-
const cat = tool.category;
|
|
1893
|
-
if (!byCategory[cat])
|
|
1894
|
-
byCategory[cat] = [];
|
|
1895
|
-
byCategory[cat].push(tool);
|
|
1875
|
+
if (desc.source.type !== "component") {
|
|
1876
|
+
throw new Error("AgentListRenderer: expected component source");
|
|
1896
1877
|
}
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
lines.push("");
|
|
1900
|
-
for (const tool of tools) {
|
|
1901
|
-
const statusIcon = tool.status === "ACTIVE" ? "\u2705" : tool.status === "DEPRECATED" ? "\u26A0\uFE0F" : "\u274C";
|
|
1902
|
-
lines.push(`### ${statusIcon} ${tool.name} v${tool.version}`);
|
|
1903
|
-
lines.push("");
|
|
1904
|
-
lines.push(`> \`${tool.id}\``);
|
|
1905
|
-
lines.push("");
|
|
1906
|
-
if (tool.description) {
|
|
1907
|
-
lines.push(tool.description);
|
|
1908
|
-
lines.push("");
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1878
|
+
if (desc.source.componentKey !== "AgentListView") {
|
|
1879
|
+
throw new Error(`AgentListRenderer: unknown component ${desc.source.componentKey}`);
|
|
1911
1880
|
}
|
|
1912
|
-
return {
|
|
1913
|
-
mimeType: "text/markdown",
|
|
1914
|
-
body: lines.join(`
|
|
1915
|
-
`)
|
|
1916
|
-
};
|
|
1881
|
+
return /* @__PURE__ */ jsxDEV7(AgentListView, {}, undefined, false, undefined, this);
|
|
1917
1882
|
}
|
|
1918
1883
|
};
|
|
1919
1884
|
|
|
1920
1885
|
// src/ui/renderers/dashboard.markdown.ts
|
|
1921
1886
|
import {
|
|
1922
1887
|
mockListAgentsHandler as mockListAgentsHandler2,
|
|
1923
|
-
mockListRunsHandler
|
|
1924
|
-
mockListToolsHandler
|
|
1888
|
+
mockListRunsHandler,
|
|
1889
|
+
mockListToolsHandler
|
|
1925
1890
|
} from "@contractspec/example.agent-console/handlers";
|
|
1926
|
-
function
|
|
1891
|
+
function formatDuration2(ms) {
|
|
1927
1892
|
if (ms < 1000)
|
|
1928
1893
|
return `${ms}ms`;
|
|
1929
1894
|
if (ms < 60000)
|
|
@@ -1941,10 +1906,10 @@ var agentDashboardMarkdownRenderer = {
|
|
|
1941
1906
|
organizationId: "demo-org",
|
|
1942
1907
|
limit: 100
|
|
1943
1908
|
}),
|
|
1944
|
-
|
|
1909
|
+
mockListRunsHandler({
|
|
1945
1910
|
limit: 100
|
|
1946
1911
|
}),
|
|
1947
|
-
|
|
1912
|
+
mockListToolsHandler({
|
|
1948
1913
|
organizationId: "demo-org",
|
|
1949
1914
|
limit: 100
|
|
1950
1915
|
})
|
|
@@ -1998,7 +1963,7 @@ var agentDashboardMarkdownRenderer = {
|
|
|
1998
1963
|
lines.push("| Run ID | Agent | Status | Duration | Tokens | Cost |");
|
|
1999
1964
|
lines.push("|--------|-------|--------|----------|--------|------|");
|
|
2000
1965
|
for (const run of runsData.items.slice(0, 5)) {
|
|
2001
|
-
lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ?
|
|
1966
|
+
lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration2(run.durationMs) : "-"} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`);
|
|
2002
1967
|
}
|
|
2003
1968
|
if (runsData.items.length > 5) {
|
|
2004
1969
|
lines.push(`| ... | ... | ... | ... | ... | _${runsData.total - 5} more_ |`);
|
|
@@ -2031,65 +1996,100 @@ var agentDashboardMarkdownRenderer = {
|
|
|
2031
1996
|
};
|
|
2032
1997
|
}
|
|
2033
1998
|
};
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
{
|
|
2050
|
-
type: "hideField",
|
|
2051
|
-
field: "webhookConfig",
|
|
2052
|
-
reason: "Integration not available in demo"
|
|
2053
|
-
},
|
|
2054
|
-
{
|
|
2055
|
-
type: "renameLabel",
|
|
2056
|
-
field: "systemPrompt",
|
|
2057
|
-
newLabel: "Agent Instructions"
|
|
2058
|
-
},
|
|
2059
|
-
{
|
|
2060
|
-
type: "addBadge",
|
|
2061
|
-
position: "header",
|
|
2062
|
-
label: "Demo Mode",
|
|
2063
|
-
variant: "warning"
|
|
1999
|
+
|
|
2000
|
+
// src/ui/renderers/run-list.markdown.ts
|
|
2001
|
+
import { mockListRunsHandler as mockListRunsHandler2 } from "@contractspec/example.agent-console/handlers";
|
|
2002
|
+
function formatDuration3(ms) {
|
|
2003
|
+
if (ms < 1000)
|
|
2004
|
+
return `${ms}ms`;
|
|
2005
|
+
if (ms < 60000)
|
|
2006
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
2007
|
+
return `${(ms / 60000).toFixed(1)}m`;
|
|
2008
|
+
}
|
|
2009
|
+
var runListMarkdownRenderer = {
|
|
2010
|
+
target: "markdown",
|
|
2011
|
+
render: async (desc) => {
|
|
2012
|
+
if (desc.source.type !== "component" || desc.source.componentKey !== "RunListView") {
|
|
2013
|
+
throw new Error("runListMarkdownRenderer: not RunListView");
|
|
2064
2014
|
}
|
|
2065
|
-
|
|
2015
|
+
const data = await mockListRunsHandler2({
|
|
2016
|
+
organizationId: "demo-org",
|
|
2017
|
+
limit: 20,
|
|
2018
|
+
offset: 0
|
|
2019
|
+
});
|
|
2020
|
+
const lines = [
|
|
2021
|
+
`# ${desc.meta.description ?? "Agent Runs"}`,
|
|
2022
|
+
"",
|
|
2023
|
+
`> ${desc.meta.key} v${desc.meta.version}`,
|
|
2024
|
+
"",
|
|
2025
|
+
`**Total Runs:** ${data.total}`,
|
|
2026
|
+
"",
|
|
2027
|
+
"## Recent Runs",
|
|
2028
|
+
"",
|
|
2029
|
+
"| ID | Agent | Status | Duration | Tokens | Cost |",
|
|
2030
|
+
"| --- | --- | --- | --- | --- | --- |"
|
|
2031
|
+
];
|
|
2032
|
+
for (const run of data.items.slice(0, 10)) {
|
|
2033
|
+
lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration3(run.durationMs) : "-"} | ${run.totalTokens} | $${run.estimatedCostUsd?.toFixed(4) ?? "-"} |`);
|
|
2034
|
+
}
|
|
2035
|
+
return {
|
|
2036
|
+
mimeType: "text/markdown",
|
|
2037
|
+
body: lines.join(`
|
|
2038
|
+
`)
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2066
2041
|
};
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
modifications: [
|
|
2076
|
-
{
|
|
2077
|
-
type: "hideField",
|
|
2078
|
-
field: "deleteButton",
|
|
2079
|
-
reason: "No delete permission"
|
|
2080
|
-
},
|
|
2081
|
-
{ type: "hideField", field: "editButton", reason: "No edit permission" },
|
|
2082
|
-
{
|
|
2083
|
-
type: "hideField",
|
|
2084
|
-
field: "createButton",
|
|
2085
|
-
reason: "No create permission"
|
|
2042
|
+
|
|
2043
|
+
// src/ui/renderers/tool-registry.markdown.ts
|
|
2044
|
+
import { mockListToolsHandler as mockListToolsHandler2 } from "@contractspec/example.agent-console/handlers";
|
|
2045
|
+
var toolRegistryMarkdownRenderer = {
|
|
2046
|
+
target: "markdown",
|
|
2047
|
+
render: async (desc) => {
|
|
2048
|
+
if (desc.source.type !== "component" || desc.source.componentKey !== "ToolRegistryView") {
|
|
2049
|
+
throw new Error("toolRegistryMarkdownRenderer: not ToolRegistryView");
|
|
2086
2050
|
}
|
|
2087
|
-
|
|
2051
|
+
const data = await mockListToolsHandler2({
|
|
2052
|
+
organizationId: "demo-org",
|
|
2053
|
+
limit: 50,
|
|
2054
|
+
offset: 0
|
|
2055
|
+
});
|
|
2056
|
+
const lines = [
|
|
2057
|
+
`# ${desc.meta.description ?? "Tool Registry"}`,
|
|
2058
|
+
"",
|
|
2059
|
+
`> ${desc.meta.key} v${desc.meta.version}`,
|
|
2060
|
+
"",
|
|
2061
|
+
`**Total Tools:** ${data.total}`,
|
|
2062
|
+
""
|
|
2063
|
+
];
|
|
2064
|
+
const byCategory = {};
|
|
2065
|
+
for (const tool of data.items) {
|
|
2066
|
+
const cat = tool.category;
|
|
2067
|
+
if (!byCategory[cat])
|
|
2068
|
+
byCategory[cat] = [];
|
|
2069
|
+
byCategory[cat].push(tool);
|
|
2070
|
+
}
|
|
2071
|
+
for (const [category, tools] of Object.entries(byCategory).sort()) {
|
|
2072
|
+
lines.push(`## ${category} (${tools.length})`);
|
|
2073
|
+
lines.push("");
|
|
2074
|
+
for (const tool of tools) {
|
|
2075
|
+
const statusIcon = tool.status === "ACTIVE" ? "\u2705" : tool.status === "DEPRECATED" ? "\u26A0\uFE0F" : "\u274C";
|
|
2076
|
+
lines.push(`### ${statusIcon} ${tool.name} v${tool.version}`);
|
|
2077
|
+
lines.push("");
|
|
2078
|
+
lines.push(`> \`${tool.id}\``);
|
|
2079
|
+
lines.push("");
|
|
2080
|
+
if (tool.description) {
|
|
2081
|
+
lines.push(tool.description);
|
|
2082
|
+
lines.push("");
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
return {
|
|
2087
|
+
mimeType: "text/markdown",
|
|
2088
|
+
body: lines.join(`
|
|
2089
|
+
`)
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2088
2092
|
};
|
|
2089
|
-
var agentConsoleOverlays = [
|
|
2090
|
-
agentConsoleDemoOverlay,
|
|
2091
|
-
agentConsoleReadOnlyOverlay
|
|
2092
|
-
];
|
|
2093
2093
|
export {
|
|
2094
2094
|
useToolList,
|
|
2095
2095
|
useRunList,
|