@contractspec/example.agent-console 3.7.6 → 3.8.2

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.
Files changed (288) hide show
  1. package/.turbo/turbo-build.log +126 -105
  2. package/AGENTS.md +52 -31
  3. package/CHANGELOG.md +29 -0
  4. package/README.md +112 -83
  5. package/dist/agent/agent.event.js +1 -1
  6. package/dist/agent/agent.handler.d.ts +3 -0
  7. package/dist/agent/agent.handler.js +730 -1
  8. package/dist/agent/agent.operation.js +1 -1
  9. package/dist/agent/index.d.ts +5 -5
  10. package/dist/agent/index.js +74 -73
  11. package/dist/agent.feature.js +179 -0
  12. package/dist/browser/agent/agent.event.js +1 -1
  13. package/dist/browser/agent/agent.handler.js +730 -1
  14. package/dist/browser/agent/agent.operation.js +1 -1
  15. package/dist/browser/agent/index.js +74 -73
  16. package/dist/browser/agent.feature.js +179 -0
  17. package/dist/browser/docs/agent-console.docblock.js +11 -8
  18. package/dist/browser/docs/index.js +11 -8
  19. package/dist/browser/example.js +2 -3
  20. package/dist/browser/handlers/agent.handlers.js +1883 -2
  21. package/dist/browser/handlers/index.js +2142 -8
  22. package/dist/browser/index.js +4075 -3161
  23. package/dist/browser/presentations/index.js +51 -51
  24. package/dist/browser/run/index.js +380 -374
  25. package/dist/browser/run/run.event.js +2 -2
  26. package/dist/browser/run/run.handler.js +666 -1
  27. package/dist/browser/run/run.presentation.js +2 -2
  28. package/dist/browser/shared/index.js +293 -1
  29. package/dist/browser/shared/mock-runs.js +5 -0
  30. package/dist/browser/tool/index.js +161 -161
  31. package/dist/browser/tool/tool.event.js +1 -1
  32. package/dist/browser/tool/tool.handler.js +479 -3
  33. package/dist/browser/tool/tool.presentation.js +2 -2
  34. package/dist/browser/ui/AgentDashboard.js +1816 -931
  35. package/dist/browser/ui/AgentDashboard.visualizations.js +217 -0
  36. package/dist/browser/ui/AgentRunList.js +360 -128
  37. package/dist/browser/ui/AgentToolRegistry.js +9 -9
  38. package/dist/browser/ui/hooks/index.js +611 -161
  39. package/dist/browser/ui/hooks/useAgentList.js +1 -1
  40. package/dist/browser/ui/hooks/useAgentMutations.js +444 -9
  41. package/dist/browser/ui/hooks/useRunList.js +26 -11
  42. package/dist/browser/ui/hooks/useToolList.js +1 -1
  43. package/dist/browser/ui/index.js +2161 -1258
  44. package/dist/browser/ui/modals/AgentActionsModal.js +13 -13
  45. package/dist/browser/ui/modals/CreateAgentModal.js +15 -15
  46. package/dist/browser/ui/modals/index.js +297 -297
  47. package/dist/browser/ui/renderers/agent-list.markdown.js +14 -5
  48. package/dist/browser/ui/renderers/agent-list.renderer.js +7 -7
  49. package/dist/browser/ui/renderers/dashboard.markdown.js +207 -36
  50. package/dist/browser/ui/renderers/index.js +359 -163
  51. package/dist/browser/ui/renderers/run-list.markdown.js +9 -4
  52. package/dist/browser/ui/renderers/tool-registry.markdown.js +15 -4
  53. package/dist/browser/ui/views/AgentListView.js +7 -7
  54. package/dist/browser/ui/views/RunDataTable.js +326 -0
  55. package/dist/browser/ui/views/RunListView.js +360 -128
  56. package/dist/browser/ui/views/ToolRegistryView.js +9 -9
  57. package/dist/browser/ui/views/index.js +478 -246
  58. package/dist/browser/ui/views/run-data-table.columns.js +271 -0
  59. package/dist/browser/ui/views/run-list.shared.js +177 -0
  60. package/dist/browser/visualizations/catalog.js +134 -0
  61. package/dist/browser/visualizations/index.js +187 -0
  62. package/dist/browser/visualizations/selectors.js +181 -0
  63. package/dist/docs/agent-console.docblock.js +11 -8
  64. package/dist/docs/index.js +11 -8
  65. package/dist/example.js +2 -3
  66. package/dist/example.test.d.ts +1 -0
  67. package/dist/handlers/agent.handlers.d.ts +2 -0
  68. package/dist/handlers/agent.handlers.js +1883 -2
  69. package/dist/handlers/index.d.ts +2 -4
  70. package/dist/handlers/index.js +2142 -8
  71. package/dist/handlers/mock-handlers.test.d.ts +1 -0
  72. package/dist/index.d.ts +6 -4
  73. package/dist/index.js +4075 -3161
  74. package/dist/node/agent/agent.event.js +1 -1
  75. package/dist/node/agent/agent.handler.js +730 -1
  76. package/dist/node/agent/agent.operation.js +1 -1
  77. package/dist/node/agent/index.js +74 -73
  78. package/dist/node/agent.feature.js +179 -0
  79. package/dist/node/docs/agent-console.docblock.js +11 -8
  80. package/dist/node/docs/index.js +11 -8
  81. package/dist/node/example.js +2 -3
  82. package/dist/node/handlers/agent.handlers.js +1883 -2
  83. package/dist/node/handlers/index.js +2142 -8
  84. package/dist/node/index.js +4075 -3161
  85. package/dist/node/presentations/index.js +51 -51
  86. package/dist/node/run/index.js +380 -374
  87. package/dist/node/run/run.event.js +2 -2
  88. package/dist/node/run/run.handler.js +666 -1
  89. package/dist/node/run/run.presentation.js +2 -2
  90. package/dist/node/shared/index.js +293 -1
  91. package/dist/node/shared/mock-runs.js +5 -0
  92. package/dist/node/tool/index.js +161 -161
  93. package/dist/node/tool/tool.event.js +1 -1
  94. package/dist/node/tool/tool.handler.js +479 -3
  95. package/dist/node/tool/tool.presentation.js +2 -2
  96. package/dist/node/ui/AgentDashboard.js +1816 -931
  97. package/dist/node/ui/AgentDashboard.visualizations.js +217 -0
  98. package/dist/node/ui/AgentRunList.js +360 -128
  99. package/dist/node/ui/AgentToolRegistry.js +9 -9
  100. package/dist/node/ui/hooks/index.js +611 -161
  101. package/dist/node/ui/hooks/useAgentList.js +1 -1
  102. package/dist/node/ui/hooks/useAgentMutations.js +444 -9
  103. package/dist/node/ui/hooks/useRunList.js +26 -11
  104. package/dist/node/ui/hooks/useToolList.js +1 -1
  105. package/dist/node/ui/index.js +2161 -1258
  106. package/dist/node/ui/modals/AgentActionsModal.js +13 -13
  107. package/dist/node/ui/modals/CreateAgentModal.js +15 -15
  108. package/dist/node/ui/modals/index.js +297 -297
  109. package/dist/node/ui/renderers/agent-list.markdown.js +14 -5
  110. package/dist/node/ui/renderers/agent-list.renderer.js +7 -7
  111. package/dist/node/ui/renderers/dashboard.markdown.js +207 -36
  112. package/dist/node/ui/renderers/index.js +359 -163
  113. package/dist/node/ui/renderers/run-list.markdown.js +9 -4
  114. package/dist/node/ui/renderers/tool-registry.markdown.js +15 -4
  115. package/dist/node/ui/views/AgentListView.js +7 -7
  116. package/dist/node/ui/views/RunDataTable.js +326 -0
  117. package/dist/node/ui/views/RunListView.js +360 -128
  118. package/dist/node/ui/views/ToolRegistryView.js +9 -9
  119. package/dist/node/ui/views/index.js +478 -246
  120. package/dist/node/ui/views/run-data-table.columns.js +271 -0
  121. package/dist/node/ui/views/run-list.shared.js +177 -0
  122. package/dist/node/visualizations/catalog.js +134 -0
  123. package/dist/node/visualizations/index.js +187 -0
  124. package/dist/node/visualizations/selectors.js +181 -0
  125. package/dist/presentations/index.d.ts +3 -5
  126. package/dist/presentations/index.js +51 -51
  127. package/dist/proof/index.d.ts +2 -0
  128. package/dist/proof/meetup-proof.d.ts +10 -0
  129. package/dist/proof/meetup-proof.runtime.d.ts +22 -0
  130. package/dist/proof/meetup-proof.scenario.d.ts +2 -0
  131. package/dist/proof/meetup-proof.suite.d.ts +1 -0
  132. package/dist/proof/meetup-proof.test.d.ts +1 -0
  133. package/dist/run/index.d.ts +7 -7
  134. package/dist/run/index.js +380 -374
  135. package/dist/run/run.event.js +2 -2
  136. package/dist/run/run.handler.d.ts +7 -0
  137. package/dist/run/run.handler.js +666 -1
  138. package/dist/run/run.presentation.js +2 -2
  139. package/dist/shared/demo-dashboard-data.d.ts +16 -0
  140. package/dist/shared/demo-runtime-seed.d.ts +17 -0
  141. package/dist/shared/demo-runtime.d.ts +8 -0
  142. package/dist/shared/demo-runtime.test.d.ts +1 -0
  143. package/dist/shared/index.d.ts +4 -1
  144. package/dist/shared/index.js +293 -1
  145. package/dist/shared/mock-runs.d.ts +4 -0
  146. package/dist/shared/mock-runs.js +5 -0
  147. package/dist/tool/index.d.ts +7 -7
  148. package/dist/tool/index.js +161 -161
  149. package/dist/tool/tool.event.js +1 -1
  150. package/dist/tool/tool.handler.d.ts +3 -0
  151. package/dist/tool/tool.handler.js +479 -3
  152. package/dist/tool/tool.presentation.js +2 -2
  153. package/dist/ui/AgentDashboard.js +1816 -931
  154. package/dist/ui/AgentDashboard.sandbox.test.d.ts +1 -0
  155. package/dist/ui/AgentDashboard.visualizations.d.ts +4 -0
  156. package/dist/ui/AgentDashboard.visualizations.js +218 -0
  157. package/dist/ui/AgentRunList.js +360 -128
  158. package/dist/ui/AgentToolRegistry.js +9 -9
  159. package/dist/ui/hooks/index.d.ts +4 -4
  160. package/dist/ui/hooks/index.js +611 -161
  161. package/dist/ui/hooks/useAgentList.d.ts +5 -0
  162. package/dist/ui/hooks/useAgentList.js +1 -1
  163. package/dist/ui/hooks/useAgentMutations.d.ts +9 -2
  164. package/dist/ui/hooks/useAgentMutations.js +444 -9
  165. package/dist/ui/hooks/useRunList.d.ts +13 -2
  166. package/dist/ui/hooks/useRunList.js +26 -11
  167. package/dist/ui/hooks/useToolList.d.ts +5 -0
  168. package/dist/ui/hooks/useToolList.js +1 -1
  169. package/dist/ui/index.d.ts +3 -3
  170. package/dist/ui/index.js +2161 -1258
  171. package/dist/ui/modals/AgentActionsModal.js +13 -13
  172. package/dist/ui/modals/CreateAgentModal.js +15 -15
  173. package/dist/ui/modals/index.d.ts +1 -1
  174. package/dist/ui/modals/index.js +297 -297
  175. package/dist/ui/renderers/agent-list.markdown.d.ts +5 -0
  176. package/dist/ui/renderers/agent-list.markdown.js +14 -5
  177. package/dist/ui/renderers/agent-list.renderer.js +7 -7
  178. package/dist/ui/renderers/dashboard.markdown.d.ts +5 -0
  179. package/dist/ui/renderers/dashboard.markdown.js +207 -36
  180. package/dist/ui/renderers/index.d.ts +2 -2
  181. package/dist/ui/renderers/index.js +359 -163
  182. package/dist/ui/renderers/run-list.markdown.d.ts +5 -0
  183. package/dist/ui/renderers/run-list.markdown.js +9 -4
  184. package/dist/ui/renderers/tool-registry.markdown.d.ts +6 -1
  185. package/dist/ui/renderers/tool-registry.markdown.js +15 -4
  186. package/dist/ui/views/AgentListView.js +7 -7
  187. package/dist/ui/views/RunDataTable.d.ts +18 -0
  188. package/dist/ui/views/RunDataTable.js +327 -0
  189. package/dist/ui/views/RunListView.js +360 -128
  190. package/dist/ui/views/ToolRegistryView.js +9 -9
  191. package/dist/ui/views/index.js +478 -246
  192. package/dist/ui/views/run-data-table.columns.d.ts +3 -0
  193. package/dist/ui/views/run-data-table.columns.js +272 -0
  194. package/dist/ui/views/run-list.shared.d.ts +14 -0
  195. package/dist/ui/views/run-list.shared.js +178 -0
  196. package/dist/visualizations/catalog.d.ts +10 -0
  197. package/dist/visualizations/catalog.js +135 -0
  198. package/dist/visualizations/index.d.ts +2 -0
  199. package/dist/visualizations/index.js +188 -0
  200. package/dist/visualizations/selectors.d.ts +3 -0
  201. package/dist/visualizations/selectors.js +182 -0
  202. package/dist/visualizations/selectors.test.d.ts +1 -0
  203. package/package.json +114 -12
  204. package/proofs/agent-console-meetup.replay.json +220 -0
  205. package/src/agent/agent.entity.ts +111 -111
  206. package/src/agent/agent.enum.ts +12 -12
  207. package/src/agent/agent.event.ts +91 -91
  208. package/src/agent/agent.handler.ts +144 -127
  209. package/src/agent/agent.operation.ts +400 -400
  210. package/src/agent/agent.presentation.ts +62 -62
  211. package/src/agent/agent.schema.ts +175 -175
  212. package/src/agent/agent.test-spec.ts +48 -48
  213. package/src/agent/index.ts +46 -51
  214. package/src/agent.capability.ts +11 -11
  215. package/src/agent.feature.ts +134 -131
  216. package/src/docs/agent-console.docblock.ts +52 -49
  217. package/src/example.test.ts +75 -0
  218. package/src/example.ts +34 -35
  219. package/src/handlers/agent.handlers.ts +576 -522
  220. package/src/handlers/index.ts +30 -14
  221. package/src/handlers/mock-handlers.test.ts +77 -0
  222. package/src/index.ts +10 -9
  223. package/src/presentations/index.ts +11 -13
  224. package/src/proof/index.ts +2 -0
  225. package/src/proof/meetup-proof.runtime.ts +196 -0
  226. package/src/proof/meetup-proof.scenario.ts +99 -0
  227. package/src/proof/meetup-proof.suite.ts +29 -0
  228. package/src/proof/meetup-proof.test.ts +28 -0
  229. package/src/proof/meetup-proof.ts +130 -0
  230. package/src/run/index.ts +49 -54
  231. package/src/run/run.entity.ts +137 -137
  232. package/src/run/run.enum.ts +18 -18
  233. package/src/run/run.event.ts +174 -174
  234. package/src/run/run.handler.ts +113 -96
  235. package/src/run/run.operation.ts +474 -474
  236. package/src/run/run.presentation.ts +42 -42
  237. package/src/run/run.schema.ts +126 -126
  238. package/src/run/run.test-spec.ts +48 -48
  239. package/src/seeders/index.ts +21 -21
  240. package/src/shared/demo-dashboard-data.ts +58 -0
  241. package/src/shared/demo-runtime-seed.ts +139 -0
  242. package/src/shared/demo-runtime.test.ts +169 -0
  243. package/src/shared/demo-runtime.ts +260 -0
  244. package/src/shared/index.ts +12 -1
  245. package/src/shared/mock-agents.ts +76 -76
  246. package/src/shared/mock-runs.ts +107 -102
  247. package/src/shared/mock-tools.ts +140 -140
  248. package/src/shared/overlay-types.ts +23 -23
  249. package/src/tool/index.ts +39 -44
  250. package/src/tool/tool.entity.ts +73 -73
  251. package/src/tool/tool.enum.ts +13 -13
  252. package/src/tool/tool.event.ts +80 -80
  253. package/src/tool/tool.handler.ts +124 -107
  254. package/src/tool/tool.operation.ts +328 -328
  255. package/src/tool/tool.presentation.ts +43 -43
  256. package/src/tool/tool.schema.ts +106 -106
  257. package/src/tool/tool.test-spec.ts +48 -48
  258. package/src/ui/AgentDashboard.sandbox.test.tsx +312 -0
  259. package/src/ui/AgentDashboard.tsx +351 -348
  260. package/src/ui/AgentDashboard.visualizations.tsx +35 -0
  261. package/src/ui/hooks/index.ts +7 -7
  262. package/src/ui/hooks/useAgentList.ts +57 -56
  263. package/src/ui/hooks/useAgentMutations.ts +168 -159
  264. package/src/ui/hooks/useRunList.ts +90 -57
  265. package/src/ui/hooks/useToolList.ts +102 -101
  266. package/src/ui/index.ts +6 -9
  267. package/src/ui/modals/AgentActionsModal.tsx +262 -262
  268. package/src/ui/modals/CreateAgentModal.tsx +232 -232
  269. package/src/ui/modals/index.ts +1 -1
  270. package/src/ui/overlays/demo-overlays.ts +52 -52
  271. package/src/ui/renderers/agent-list.markdown.ts +81 -61
  272. package/src/ui/renderers/agent-list.renderer.tsx +14 -14
  273. package/src/ui/renderers/dashboard.markdown.ts +135 -139
  274. package/src/ui/renderers/index.ts +3 -4
  275. package/src/ui/renderers/run-list.markdown.ts +56 -47
  276. package/src/ui/renderers/tool-registry.markdown.ts +79 -66
  277. package/src/ui/views/AgentListView.tsx +90 -90
  278. package/src/ui/views/RunDataTable.tsx +74 -0
  279. package/src/ui/views/RunListView.tsx +84 -158
  280. package/src/ui/views/ToolRegistryView.tsx +113 -113
  281. package/src/ui/views/run-data-table.columns.tsx +102 -0
  282. package/src/ui/views/run-list.shared.tsx +139 -0
  283. package/src/visualizations/catalog.ts +132 -0
  284. package/src/visualizations/index.ts +2 -0
  285. package/src/visualizations/selectors.test.ts +12 -0
  286. package/src/visualizations/selectors.ts +70 -0
  287. package/tsconfig.json +7 -8
  288. package/tsdown.config.js +24 -3
@@ -1,173 +1,99 @@
1
1
  'use client';
2
2
 
3
- /**
4
- * Run List View - Shows agent execution runs with stats
5
- */
6
3
  import {
7
- StatCard,
8
- StatCardGroup,
9
- StatusChip,
10
- EmptyState,
11
- LoaderBlock,
12
- ErrorState,
4
+ EmptyState,
5
+ ErrorState,
6
+ LoaderBlock,
7
+ StatCard,
8
+ StatCardGroup,
13
9
  } from '@contractspec/lib.design-system';
14
- import { useRunList, type Run } from '../hooks/useRunList';
10
+ /**
11
+ * Run List View - Shows agent execution runs with shared ContractSpec table primitives
12
+ */
13
+ import type { ContractTableSort } from '@contractspec/lib.presentation-runtime-core';
14
+ import { useState } from 'react';
15
+ import { useRunList } from '../hooks/useRunList';
16
+ import { RunDataTable } from './RunDataTable';
17
+ import { formatTokens } from './run-list.shared';
15
18
 
16
19
  interface RunListViewProps {
17
- agentId?: string;
18
- onRunClick?: (runId: string) => void;
19
- }
20
-
21
- function getStatusTone(
22
- status: Run['status']
23
- ): 'success' | 'warning' | 'neutral' | 'danger' {
24
- switch (status) {
25
- case 'COMPLETED':
26
- return 'success';
27
- case 'RUNNING':
28
- return 'warning';
29
- case 'QUEUED':
30
- return 'neutral';
31
- case 'FAILED':
32
- case 'CANCELLED':
33
- return 'danger';
34
- default:
35
- return 'neutral';
36
- }
37
- }
38
-
39
- function formatDuration(ms?: number): string {
40
- if (!ms) return '-';
41
- if (ms < 1000) return `${ms}ms`;
42
- if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
43
- return `${(ms / 60000).toFixed(1)}m`;
44
- }
45
-
46
- function formatTokens(tokens: number): string {
47
- if (tokens < 1000) return tokens.toString();
48
- if (tokens < 1000000) return `${(tokens / 1000).toFixed(1)}K`;
49
- return `${(tokens / 1000000).toFixed(2)}M`;
50
- }
51
-
52
- function formatCost(cost?: number): string {
53
- if (!cost) return '-';
54
- return `$${cost.toFixed(4)}`;
20
+ agentId?: string;
21
+ onRunClick?: (runId: string) => void;
55
22
  }
56
23
 
57
24
  export function RunListView({ agentId, onRunClick }: RunListViewProps) {
58
- const { data, metrics, loading, error, refetch } = useRunList({ agentId });
59
-
60
- if (loading && !data) {
61
- return <LoaderBlock label="Loading runs..." />;
62
- }
25
+ const [sorting, setSorting] = useState<ContractTableSort[]>([
26
+ { id: 'queuedAt', desc: true },
27
+ ]);
28
+ const [pagination, setPagination] = useState({
29
+ pageIndex: 0,
30
+ pageSize: 3,
31
+ });
32
+ const { data, metrics, loading, error, refetch } = useRunList({
33
+ agentId,
34
+ pageIndex: pagination.pageIndex,
35
+ pageSize: pagination.pageSize,
36
+ sorting,
37
+ });
63
38
 
64
- if (error) {
65
- return (
66
- <ErrorState
67
- title="Failed to load runs"
68
- description={error.message}
69
- onRetry={refetch}
70
- retryLabel="Retry"
71
- />
72
- );
73
- }
39
+ if (loading && !data) {
40
+ return <LoaderBlock label="Loading runs..." />;
41
+ }
74
42
 
75
- if (!data?.items.length) {
76
- return (
77
- <EmptyState
78
- title="No runs yet"
79
- description="Execute an agent to see run history here."
80
- />
81
- );
82
- }
43
+ if (error) {
44
+ return (
45
+ <ErrorState
46
+ title="Failed to load runs"
47
+ description={error.message}
48
+ onRetry={refetch}
49
+ retryLabel="Retry"
50
+ />
51
+ );
52
+ }
83
53
 
84
- return (
85
- <div className="space-y-6">
86
- {/* Metrics Stats */}
87
- {metrics && (
88
- <StatCardGroup>
89
- <StatCard label="Total Runs" value={metrics.totalRuns} />
90
- <StatCard
91
- label="Success Rate"
92
- value={`${(metrics.successRate * 100).toFixed(1)}%`}
93
- />
94
- <StatCard
95
- label="Total Tokens"
96
- value={formatTokens(metrics.totalTokens)}
97
- />
98
- <StatCard
99
- label="Total Cost"
100
- value={`$${metrics.totalCostUsd.toFixed(2)}`}
101
- />
102
- </StatCardGroup>
103
- )}
54
+ if (!data?.items.length) {
55
+ return (
56
+ <EmptyState
57
+ title="No runs yet"
58
+ description="Execute an agent to see run history here."
59
+ />
60
+ );
61
+ }
104
62
 
105
- {/* Run List */}
106
- <div className="border-border rounded-lg border">
107
- <table className="w-full">
108
- <thead className="border-border bg-muted/30 border-b">
109
- <tr>
110
- <th className="text-muted-foreground px-4 py-3 text-left text-sm font-medium">
111
- Run
112
- </th>
113
- <th className="text-muted-foreground px-4 py-3 text-left text-sm font-medium">
114
- Agent
115
- </th>
116
- <th className="text-muted-foreground px-4 py-3 text-left text-sm font-medium">
117
- Status
118
- </th>
119
- <th className="text-muted-foreground px-4 py-3 text-right text-sm font-medium">
120
- Tokens
121
- </th>
122
- <th className="text-muted-foreground px-4 py-3 text-right text-sm font-medium">
123
- Duration
124
- </th>
125
- <th className="text-muted-foreground px-4 py-3 text-right text-sm font-medium">
126
- Cost
127
- </th>
128
- </tr>
129
- </thead>
130
- <tbody className="divide-border divide-y">
131
- {data.items.map((run: Run) => (
132
- <tr
133
- key={run.id}
134
- className="hover:bg-muted/50 cursor-pointer transition-colors"
135
- onClick={() => onRunClick?.(run.id)}
136
- >
137
- <td className="px-4 py-3">
138
- <div className="font-mono text-sm">{run.id.slice(-8)}</div>
139
- <div className="text-muted-foreground text-xs">
140
- {run.queuedAt.toLocaleString()}
141
- </div>
142
- </td>
143
- <td className="px-4 py-3">
144
- <span className="font-medium">{run.agentName}</span>
145
- </td>
146
- <td className="px-4 py-3">
147
- <StatusChip
148
- tone={getStatusTone(run.status)}
149
- label={run.status}
150
- />
151
- </td>
152
- <td className="px-4 py-3 text-right font-mono text-sm">
153
- {formatTokens(run.totalTokens)}
154
- </td>
155
- <td className="px-4 py-3 text-right font-mono text-sm">
156
- {formatDuration(run.durationMs)}
157
- </td>
158
- <td className="px-4 py-3 text-right font-mono text-sm">
159
- {formatCost(run.estimatedCostUsd)}
160
- </td>
161
- </tr>
162
- ))}
163
- </tbody>
164
- </table>
165
- </div>
63
+ return (
64
+ <div className="space-y-6">
65
+ {metrics ? (
66
+ <StatCardGroup>
67
+ <StatCard label="Total Runs" value={metrics.totalRuns} />
68
+ <StatCard
69
+ label="Success Rate"
70
+ value={`${(metrics.successRate * 100).toFixed(1)}%`}
71
+ />
72
+ <StatCard
73
+ label="Total Tokens"
74
+ value={formatTokens(metrics.totalTokens)}
75
+ />
76
+ <StatCard
77
+ label="Total Cost"
78
+ value={`$${metrics.totalCostUsd.toFixed(2)}`}
79
+ />
80
+ </StatCardGroup>
81
+ ) : null}
166
82
 
167
- {/* Pagination */}
168
- <div className="text-muted-foreground text-center text-sm">
169
- Showing {data.items.length} of {data.total} runs
170
- </div>
171
- </div>
172
- );
83
+ <RunDataTable
84
+ runs={data.items}
85
+ totalItems={data.total}
86
+ pageIndex={pagination.pageIndex}
87
+ pageSize={pagination.pageSize}
88
+ sorting={sorting}
89
+ loading={loading}
90
+ onSortingChange={(nextSorting) => {
91
+ setSorting(nextSorting);
92
+ setPagination((current) => ({ ...current, pageIndex: 0 }));
93
+ }}
94
+ onPaginationChange={setPagination}
95
+ onRunClick={onRunClick}
96
+ />
97
+ </div>
98
+ );
173
99
  }
@@ -4,137 +4,137 @@
4
4
  * Tool Registry View - Shows available tools organized by category
5
5
  */
6
6
  import {
7
- StatCard,
8
- StatCardGroup,
9
- StatusChip,
10
- EntityCard,
11
- EmptyState,
12
- LoaderBlock,
13
- ErrorState,
14
- Button,
7
+ Button,
8
+ EmptyState,
9
+ EntityCard,
10
+ ErrorState,
11
+ LoaderBlock,
12
+ StatCard,
13
+ StatCardGroup,
14
+ StatusChip,
15
15
  } from '@contractspec/lib.design-system';
16
- import { useToolList, type Tool } from '../hooks/useToolList';
16
+ import { type Tool, useToolList } from '../hooks/useToolList';
17
17
 
18
18
  interface ToolRegistryViewProps {
19
- onToolClick?: (toolId: string) => void;
20
- onCreateTool?: () => void;
19
+ onToolClick?: (toolId: string) => void;
20
+ onCreateTool?: () => void;
21
21
  }
22
22
 
23
23
  const categoryIcons: Record<string, string> = {
24
- RETRIEVAL: '🔍',
25
- COMPUTATION: '🧮',
26
- COMMUNICATION: '📧',
27
- INTEGRATION: '🔗',
28
- UTILITY: '🛠️',
29
- CUSTOM: '⚙️',
24
+ RETRIEVAL: '🔍',
25
+ COMPUTATION: '🧮',
26
+ COMMUNICATION: '📧',
27
+ INTEGRATION: '🔗',
28
+ UTILITY: '🛠️',
29
+ CUSTOM: '⚙️',
30
30
  };
31
31
 
32
32
  function getStatusTone(
33
- status: Tool['status']
33
+ status: Tool['status']
34
34
  ): 'success' | 'warning' | 'neutral' | 'danger' {
35
- switch (status) {
36
- case 'ACTIVE':
37
- return 'success';
38
- case 'DRAFT':
39
- return 'neutral';
40
- case 'DEPRECATED':
41
- return 'warning';
42
- case 'DISABLED':
43
- return 'danger';
44
- default:
45
- return 'neutral';
46
- }
35
+ switch (status) {
36
+ case 'ACTIVE':
37
+ return 'success';
38
+ case 'DRAFT':
39
+ return 'neutral';
40
+ case 'DEPRECATED':
41
+ return 'warning';
42
+ case 'DISABLED':
43
+ return 'danger';
44
+ default:
45
+ return 'neutral';
46
+ }
47
47
  }
48
48
 
49
49
  export function ToolRegistryView({
50
- onToolClick,
51
- onCreateTool,
50
+ onToolClick,
51
+ onCreateTool,
52
52
  }: ToolRegistryViewProps) {
53
- const { data, loading, error, groupedByCategory, categoryStats, refetch } =
54
- useToolList();
53
+ const { data, loading, error, groupedByCategory, categoryStats, refetch } =
54
+ useToolList();
55
55
 
56
- if (loading && !data) {
57
- return <LoaderBlock label="Loading tools..." />;
58
- }
56
+ if (loading && !data) {
57
+ return <LoaderBlock label="Loading tools..." />;
58
+ }
59
59
 
60
- if (error) {
61
- return (
62
- <ErrorState
63
- title="Failed to load tools"
64
- description={error.message}
65
- onRetry={refetch}
66
- retryLabel="Retry"
67
- />
68
- );
69
- }
60
+ if (error) {
61
+ return (
62
+ <ErrorState
63
+ title="Failed to load tools"
64
+ description={error.message}
65
+ onRetry={refetch}
66
+ retryLabel="Retry"
67
+ />
68
+ );
69
+ }
70
70
 
71
- if (!data?.items.length) {
72
- return (
73
- <EmptyState
74
- title="No tools registered"
75
- description="Create your first tool to extend agent capabilities."
76
- primaryAction={
77
- onCreateTool ? (
78
- <Button onPress={onCreateTool}>Create Tool</Button>
79
- ) : undefined
80
- }
81
- />
82
- );
83
- }
71
+ if (!data?.items.length) {
72
+ return (
73
+ <EmptyState
74
+ title="No tools registered"
75
+ description="Create your first tool to extend agent capabilities."
76
+ primaryAction={
77
+ onCreateTool ? (
78
+ <Button onPress={onCreateTool}>Create Tool</Button>
79
+ ) : undefined
80
+ }
81
+ />
82
+ );
83
+ }
84
84
 
85
- return (
86
- <div className="space-y-8">
87
- {/* Category Stats */}
88
- <StatCardGroup>
89
- <StatCard label="Total Tools" value={data.total} />
90
- {categoryStats.slice(0, 3).map(({ category, count }) => (
91
- <StatCard
92
- key={category}
93
- label={`${categoryIcons[category] ?? ''} ${category}`}
94
- value={count}
95
- />
96
- ))}
97
- </StatCardGroup>
85
+ return (
86
+ <div className="space-y-8">
87
+ {/* Category Stats */}
88
+ <StatCardGroup>
89
+ <StatCard label="Total Tools" value={data.total} />
90
+ {categoryStats.slice(0, 3).map(({ category, count }) => (
91
+ <StatCard
92
+ key={category}
93
+ label={`${categoryIcons[category] ?? ''} ${category}`}
94
+ value={count}
95
+ />
96
+ ))}
97
+ </StatCardGroup>
98
98
 
99
- {/* Tools by Category */}
100
- {Object.entries(groupedByCategory).map(([category, tools]) => (
101
- <section key={category} className="space-y-4">
102
- <div className="flex items-center gap-2">
103
- <span className="text-2xl">{categoryIcons[category]}</span>
104
- <h3 className="text-lg font-semibold">{category}</h3>
105
- <span className="bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-xs">
106
- {(tools as Tool[]).length}
107
- </span>
108
- </div>
99
+ {/* Tools by Category */}
100
+ {Object.entries(groupedByCategory).map(([category, tools]) => (
101
+ <section key={category} className="space-y-4">
102
+ <div className="flex items-center gap-2">
103
+ <span className="text-2xl">{categoryIcons[category]}</span>
104
+ <h3 className="font-semibold text-lg">{category}</h3>
105
+ <span className="rounded-full bg-muted px-2 py-0.5 text-muted-foreground text-xs">
106
+ {(tools as Tool[]).length}
107
+ </span>
108
+ </div>
109
109
 
110
- <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
111
- {(tools as Tool[]).map((tool) => (
112
- <EntityCard
113
- key={tool.id}
114
- cardTitle={tool.name}
115
- cardSubtitle={`v${tool.version}`}
116
- meta={
117
- <p className="text-muted-foreground text-sm">
118
- {tool.description}
119
- </p>
120
- }
121
- chips={
122
- <StatusChip
123
- tone={getStatusTone(tool.status)}
124
- label={tool.status}
125
- />
126
- }
127
- footer={
128
- <code className="text-muted-foreground text-xs">
129
- {tool.name}
130
- </code>
131
- }
132
- onClick={onToolClick ? () => onToolClick(tool.id) : undefined}
133
- />
134
- ))}
135
- </div>
136
- </section>
137
- ))}
138
- </div>
139
- );
110
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
111
+ {(tools as Tool[]).map((tool) => (
112
+ <EntityCard
113
+ key={tool.id}
114
+ cardTitle={tool.name}
115
+ cardSubtitle={`v${tool.version}`}
116
+ meta={
117
+ <p className="text-muted-foreground text-sm">
118
+ {tool.description}
119
+ </p>
120
+ }
121
+ chips={
122
+ <StatusChip
123
+ tone={getStatusTone(tool.status)}
124
+ label={tool.status}
125
+ />
126
+ }
127
+ footer={
128
+ <code className="text-muted-foreground text-xs">
129
+ {tool.name}
130
+ </code>
131
+ }
132
+ onClick={onToolClick ? () => onToolClick(tool.id) : undefined}
133
+ />
134
+ ))}
135
+ </div>
136
+ </section>
137
+ ))}
138
+ </div>
139
+ );
140
140
  }
@@ -0,0 +1,102 @@
1
+ 'use client';
2
+
3
+ import { StatusChip } from '@contractspec/lib.design-system';
4
+ import type { ContractTableColumnDef } from '@contractspec/lib.presentation-runtime-react';
5
+ import { VStack } from '@contractspec/lib.ui-kit-web/ui/stack';
6
+ import { Text } from '@contractspec/lib.ui-kit-web/ui/text';
7
+ import type { Run } from '../hooks/useRunList';
8
+ import {
9
+ formatCost,
10
+ formatDuration,
11
+ formatTokens,
12
+ getStatusTone,
13
+ } from './run-list.shared';
14
+
15
+ export function createRunTableColumns(): readonly ContractTableColumnDef<Run>[] {
16
+ return [
17
+ {
18
+ id: 'queuedAt',
19
+ header: 'Run',
20
+ label: 'Run',
21
+ accessor: (run: Run) => run.queuedAt.getTime(),
22
+ cell: ({ item }) => (
23
+ <VStack gap="xs">
24
+ <Text className="font-mono text-sm">{item.id.slice(-8)}</Text>
25
+ <Text className="text-muted-foreground text-xs">
26
+ {item.queuedAt.toLocaleString()}
27
+ </Text>
28
+ </VStack>
29
+ ),
30
+ size: 220,
31
+ minSize: 180,
32
+ canSort: true,
33
+ canHide: true,
34
+ canResize: true,
35
+ },
36
+ {
37
+ id: 'agentName',
38
+ header: 'Agent',
39
+ label: 'Agent',
40
+ accessor: (run: Run) => run.agentName ?? 'Unknown Agent',
41
+ cell: ({ value }) => (
42
+ <Text className="font-medium">
43
+ {typeof value === 'string' ? value : 'Unknown Agent'}
44
+ </Text>
45
+ ),
46
+ size: 220,
47
+ canSort: true,
48
+ canResize: true,
49
+ },
50
+ {
51
+ id: 'status',
52
+ header: 'Status',
53
+ label: 'Status',
54
+ accessorKey: 'status',
55
+ cell: ({ value }) => {
56
+ const status =
57
+ typeof value === 'string' ? (value as Run['status']) : 'QUEUED';
58
+ return <StatusChip tone={getStatusTone(status)} label={status} />;
59
+ },
60
+ size: 150,
61
+ canSort: true,
62
+ canResize: true,
63
+ },
64
+ {
65
+ id: 'totalTokens',
66
+ header: 'Tokens',
67
+ label: 'Tokens',
68
+ accessorKey: 'totalTokens',
69
+ cell: ({ value }) => formatTokens(Number(value ?? 0)),
70
+ align: 'right' as const,
71
+ size: 140,
72
+ canSort: true,
73
+ canResize: true,
74
+ },
75
+ {
76
+ id: 'durationMs',
77
+ header: 'Duration',
78
+ label: 'Duration',
79
+ accessorKey: 'durationMs',
80
+ cell: ({ value }) =>
81
+ formatDuration(typeof value === 'number' ? value : undefined),
82
+ align: 'right' as const,
83
+ size: 140,
84
+ canSort: true,
85
+ canHide: true,
86
+ canResize: true,
87
+ },
88
+ {
89
+ id: 'estimatedCostUsd',
90
+ header: 'Cost',
91
+ label: 'Cost',
92
+ accessorKey: 'estimatedCostUsd',
93
+ cell: ({ value }) =>
94
+ formatCost(typeof value === 'number' ? value : undefined),
95
+ align: 'right' as const,
96
+ size: 140,
97
+ canSort: true,
98
+ canHide: true,
99
+ canResize: true,
100
+ },
101
+ ];
102
+ }