@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
package/dist/ui/index.js CHANGED
@@ -1,12 +1,561 @@
1
1
  // @bun
2
- // src/ui/hooks/useRunList.ts
3
- import { useCallback, useEffect, useState } from "react";
2
+ // src/visualizations/catalog.ts
3
+ import {
4
+ defineVisualization,
5
+ VisualizationRegistry
6
+ } from "@contractspec/lib.contracts-spec/visualizations";
7
+ var RUN_LIST_REF = { key: "agent.run.list", version: "1.0.0" };
8
+ var META = {
9
+ version: "1.0.0",
10
+ domain: "ai-ops",
11
+ stability: "experimental",
12
+ owners: ["@example.agent-console"],
13
+ tags: ["agent-console", "visualization", "operations"]
14
+ };
15
+ var AgentRunStatusVisualization = defineVisualization({
16
+ meta: {
17
+ ...META,
18
+ key: "agent-console.visualization.run-status",
19
+ title: "Run Status Breakdown",
20
+ description: "Distribution of run outcomes across the current sample.",
21
+ goal: "Make operational success and failure mix visible at a glance.",
22
+ context: "Agent operations overview."
23
+ },
24
+ source: { primary: RUN_LIST_REF, resultPath: "data" },
25
+ visualization: {
26
+ kind: "pie",
27
+ nameDimension: "status",
28
+ valueMeasure: "runs",
29
+ dimensions: [
30
+ { key: "status", label: "Status", dataPath: "status", type: "category" }
31
+ ],
32
+ measures: [
33
+ { key: "runs", label: "Runs", dataPath: "runs", format: "number" }
34
+ ],
35
+ table: { caption: "Run counts by status." }
36
+ }
37
+ });
38
+ var AgentRunActivityVisualization = defineVisualization({
39
+ meta: {
40
+ ...META,
41
+ key: "agent-console.visualization.run-activity",
42
+ title: "Recent Run Activity",
43
+ description: "Daily run volume across the current sample.",
44
+ goal: "Show whether agent activity is rising or slowing down.",
45
+ context: "Operations trend monitoring."
46
+ },
47
+ source: { primary: RUN_LIST_REF, resultPath: "data" },
48
+ visualization: {
49
+ kind: "cartesian",
50
+ variant: "line",
51
+ xDimension: "day",
52
+ yMeasures: ["runs"],
53
+ dimensions: [{ key: "day", label: "Day", dataPath: "day", type: "time" }],
54
+ measures: [
55
+ {
56
+ key: "runs",
57
+ label: "Runs",
58
+ dataPath: "runs",
59
+ format: "number",
60
+ color: "#0f766e"
61
+ }
62
+ ],
63
+ table: { caption: "Daily run counts." }
64
+ }
65
+ });
66
+ var AgentRunEfficiencyVisualization = defineVisualization({
67
+ meta: {
68
+ ...META,
69
+ key: "agent-console.visualization.run-efficiency",
70
+ title: "Duration vs Tokens",
71
+ description: "Scatter chart comparing token consumption and runtime.",
72
+ goal: "Reveal outlier runs that are slow relative to their token usage.",
73
+ context: "Operational performance diagnostics."
74
+ },
75
+ source: { primary: RUN_LIST_REF, resultPath: "data" },
76
+ visualization: {
77
+ kind: "cartesian",
78
+ variant: "scatter",
79
+ xDimension: "totalTokens",
80
+ yMeasures: ["durationMs"],
81
+ dimensions: [
82
+ {
83
+ key: "totalTokens",
84
+ label: "Total Tokens",
85
+ dataPath: "totalTokens",
86
+ type: "number"
87
+ }
88
+ ],
89
+ measures: [
90
+ {
91
+ key: "durationMs",
92
+ label: "Duration",
93
+ dataPath: "durationMs",
94
+ format: "duration",
95
+ color: "#7c3aed"
96
+ },
97
+ {
98
+ key: "estimatedCostUsd",
99
+ label: "Cost",
100
+ dataPath: "estimatedCostUsd",
101
+ format: "currency"
102
+ }
103
+ ],
104
+ series: [
105
+ {
106
+ key: "runs",
107
+ label: "Runs",
108
+ measure: "durationMs",
109
+ type: "scatter",
110
+ color: "#7c3aed"
111
+ }
112
+ ],
113
+ table: { caption: "Run duration versus token usage." }
114
+ }
115
+ });
116
+ var AgentVisualizationSpecs = [
117
+ AgentRunStatusVisualization,
118
+ AgentRunActivityVisualization,
119
+ AgentRunEfficiencyVisualization
120
+ ];
121
+ var AgentVisualizationRegistry = new VisualizationRegistry([
122
+ ...AgentVisualizationSpecs
123
+ ]);
124
+ var AgentVisualizationRefs = AgentVisualizationSpecs.map((spec) => ({
125
+ key: spec.meta.key,
126
+ version: spec.meta.version
127
+ }));
128
+
129
+ // src/visualizations/selectors.ts
130
+ function dayKey(value) {
131
+ if (!value)
132
+ return "unknown";
133
+ return value.toISOString().slice(0, 10);
134
+ }
135
+ function createAgentVisualizationItems(runs) {
136
+ const statusCounts = new Map;
137
+ const activityCounts = new Map;
138
+ for (const run of runs) {
139
+ statusCounts.set(run.status, (statusCounts.get(run.status) ?? 0) + 1);
140
+ activityCounts.set(dayKey(run.startedAt ?? run.queuedAt), (activityCounts.get(dayKey(run.startedAt ?? run.queuedAt)) ?? 0) + 1);
141
+ }
142
+ return [
143
+ {
144
+ key: "run-status",
145
+ spec: AgentRunStatusVisualization,
146
+ data: {
147
+ data: Array.from(statusCounts.entries()).map(([status, count]) => ({
148
+ status,
149
+ runs: count
150
+ }))
151
+ },
152
+ title: "Run Status Breakdown",
153
+ description: "Completed, failed, running, and cancelled runs in the sample.",
154
+ height: 260
155
+ },
156
+ {
157
+ key: "run-activity",
158
+ spec: AgentRunActivityVisualization,
159
+ data: {
160
+ data: Array.from(activityCounts.entries()).sort(([left], [right]) => left.localeCompare(right)).map(([day, count]) => ({ day, runs: count }))
161
+ },
162
+ title: "Recent Run Activity",
163
+ description: "Daily run volume derived from run start times."
164
+ },
165
+ {
166
+ key: "run-efficiency",
167
+ spec: AgentRunEfficiencyVisualization,
168
+ data: {
169
+ data: runs.filter((run) => typeof run.durationMs === "number").map((run) => ({
170
+ totalTokens: run.totalTokens,
171
+ durationMs: run.durationMs ?? 0,
172
+ estimatedCostUsd: run.estimatedCostUsd
173
+ }))
174
+ },
175
+ title: "Duration vs Tokens",
176
+ description: "Operational scatter plot for spotting inefficient runs."
177
+ }
178
+ ];
179
+ }
180
+ // src/shared/mock-agents.ts
181
+ var MOCK_AGENTS = [
182
+ {
183
+ id: "agent-1",
184
+ organizationId: "demo-org",
185
+ name: "Customer Support Bot",
186
+ slug: "customer-support-bot",
187
+ description: "Handles tier-1 customer inquiries and routes complex issues.",
188
+ status: "ACTIVE",
189
+ modelProvider: "OPENAI",
190
+ modelName: "gpt-4o-mini",
191
+ modelConfig: { temperature: 0.7 },
192
+ systemPrompt: "You are a helpful customer support assistant.",
193
+ toolChoice: "auto",
194
+ maxIterations: 10,
195
+ timeoutMs: 120000,
196
+ version: "1.0.0",
197
+ tags: ["support", "tier-1"],
198
+ createdAt: new Date("2024-01-15T10:00:00Z"),
199
+ updatedAt: new Date("2024-03-20T14:30:00Z")
200
+ },
201
+ {
202
+ id: "agent-2",
203
+ organizationId: "demo-org",
204
+ name: "Code Review Assistant",
205
+ slug: "code-review-assistant",
206
+ description: "Reviews pull requests and provides actionable feedback.",
207
+ status: "ACTIVE",
208
+ modelProvider: "ANTHROPIC",
209
+ modelName: "claude-sonnet-4-20250514",
210
+ modelConfig: { temperature: 0.3 },
211
+ systemPrompt: "You are a code review expert.",
212
+ toolChoice: "auto",
213
+ maxIterations: 15,
214
+ timeoutMs: 180000,
215
+ version: "2.1.0",
216
+ tags: ["code", "review", "dev"],
217
+ createdAt: new Date("2024-02-10T09:00:00Z"),
218
+ updatedAt: new Date("2024-04-05T11:15:00Z")
219
+ },
220
+ {
221
+ id: "agent-3",
222
+ organizationId: "demo-org",
223
+ name: "Data Analyst",
224
+ slug: "data-analyst",
225
+ description: "Queries databases and generates insights from data.",
226
+ status: "PAUSED",
227
+ modelProvider: "OPENAI",
228
+ modelName: "gpt-4o",
229
+ modelConfig: { temperature: 0.5 },
230
+ systemPrompt: "You are a data analyst expert in SQL and analytics.",
231
+ toolChoice: "required",
232
+ maxIterations: 20,
233
+ timeoutMs: 300000,
234
+ version: "1.2.0",
235
+ tags: ["data", "analytics", "sql"],
236
+ createdAt: new Date("2024-03-01T08:00:00Z"),
237
+ updatedAt: new Date("2024-04-10T16:45:00Z")
238
+ },
239
+ {
240
+ id: "agent-4",
241
+ organizationId: "demo-org",
242
+ name: "Meeting Scheduler",
243
+ slug: "meeting-scheduler",
244
+ description: "Schedules meetings and manages calendar conflicts.",
245
+ status: "DRAFT",
246
+ modelProvider: "GOOGLE",
247
+ modelName: "gemini-2.0-flash",
248
+ modelConfig: { temperature: 0.2 },
249
+ systemPrompt: "You help schedule and organize meetings efficiently.",
250
+ toolChoice: "auto",
251
+ maxIterations: 5,
252
+ timeoutMs: 60000,
253
+ version: "0.1.0",
254
+ tags: ["calendar", "scheduling"],
255
+ createdAt: new Date("2024-04-01T12:00:00Z"),
256
+ updatedAt: new Date("2024-04-01T12:00:00Z")
257
+ }
258
+ ];
259
+
260
+ // src/shared/mock-tools.ts
261
+ var MOCK_TOOLS = [
262
+ {
263
+ id: "tool-1",
264
+ organizationId: "demo-org",
265
+ name: "Web Search",
266
+ slug: "web-search",
267
+ description: "Search the web for real-time information using Brave API.",
268
+ category: "RETRIEVAL",
269
+ status: "ACTIVE",
270
+ parametersSchema: {
271
+ type: "object",
272
+ properties: {
273
+ query: { type: "string", description: "Search query" },
274
+ numResults: { type: "number", default: 10 }
275
+ },
276
+ required: ["query"]
277
+ },
278
+ outputSchema: { type: "array", items: { type: "object" } },
279
+ implementationType: "http",
280
+ implementationConfig: {
281
+ url: "https://api.brave.com/search",
282
+ method: "GET"
283
+ },
284
+ maxInvocationsPerMinute: 60,
285
+ timeoutMs: 30000,
286
+ version: "1.0.0",
287
+ tags: ["search", "web"],
288
+ createdAt: new Date("2024-01-01T00:00:00Z"),
289
+ updatedAt: new Date("2024-02-15T10:00:00Z")
290
+ },
291
+ {
292
+ id: "tool-2",
293
+ organizationId: "demo-org",
294
+ name: "SQL Query",
295
+ slug: "sql-query",
296
+ description: "Execute read-only SQL queries against the data warehouse.",
297
+ category: "RETRIEVAL",
298
+ status: "ACTIVE",
299
+ parametersSchema: {
300
+ type: "object",
301
+ properties: {
302
+ query: { type: "string", description: "SQL query" },
303
+ maxRows: { type: "number", default: 100 }
304
+ },
305
+ required: ["query"]
306
+ },
307
+ outputSchema: { type: "object" },
308
+ implementationType: "function",
309
+ implementationConfig: { handler: "executeSqlQuery" },
310
+ maxInvocationsPerMinute: 30,
311
+ timeoutMs: 60000,
312
+ version: "1.1.0",
313
+ tags: ["sql", "database"],
314
+ createdAt: new Date("2024-01-05T00:00:00Z"),
315
+ updatedAt: new Date("2024-03-10T14:00:00Z")
316
+ },
317
+ {
318
+ id: "tool-3",
319
+ organizationId: "demo-org",
320
+ name: "Email Sender",
321
+ slug: "email-sender",
322
+ description: "Send emails via SMTP or API.",
323
+ category: "COMMUNICATION",
324
+ status: "ACTIVE",
325
+ parametersSchema: {
326
+ type: "object",
327
+ properties: {
328
+ to: { type: "string" },
329
+ subject: { type: "string" },
330
+ body: { type: "string" }
331
+ },
332
+ required: ["to", "subject", "body"]
333
+ },
334
+ implementationType: "http",
335
+ implementationConfig: { url: "/api/send-email", method: "POST" },
336
+ maxInvocationsPerMinute: 10,
337
+ timeoutMs: 30000,
338
+ version: "1.0.0",
339
+ tags: ["email", "communication"],
340
+ createdAt: new Date("2024-02-01T00:00:00Z"),
341
+ updatedAt: new Date("2024-02-01T00:00:00Z")
342
+ },
343
+ {
344
+ id: "tool-4",
345
+ organizationId: "demo-org",
346
+ name: "GitHub Integration",
347
+ slug: "github-integration",
348
+ description: "Interact with GitHub repositories, PRs, and issues.",
349
+ category: "INTEGRATION",
350
+ status: "ACTIVE",
351
+ parametersSchema: {
352
+ type: "object",
353
+ properties: {
354
+ action: {
355
+ type: "string",
356
+ enum: ["list_prs", "get_pr", "create_comment"]
357
+ },
358
+ repo: { type: "string" },
359
+ params: { type: "object" }
360
+ },
361
+ required: ["action", "repo"]
362
+ },
363
+ implementationType: "http",
364
+ implementationConfig: { url: "https://api.github.com", auth: "token" },
365
+ maxInvocationsPerMinute: 100,
366
+ timeoutMs: 15000,
367
+ version: "2.0.0",
368
+ tags: ["github", "integration", "code"],
369
+ createdAt: new Date("2024-02-20T00:00:00Z"),
370
+ updatedAt: new Date("2024-04-01T09:00:00Z")
371
+ },
372
+ {
373
+ id: "tool-5",
374
+ organizationId: "demo-org",
375
+ name: "Calculator",
376
+ slug: "calculator",
377
+ description: "Perform mathematical calculations.",
378
+ category: "COMPUTATION",
379
+ status: "ACTIVE",
380
+ parametersSchema: {
381
+ type: "object",
382
+ properties: {
383
+ expression: {
384
+ type: "string",
385
+ description: "Math expression to evaluate"
386
+ }
387
+ },
388
+ required: ["expression"]
389
+ },
390
+ outputSchema: {
391
+ type: "object",
392
+ properties: { result: { type: "number" } }
393
+ },
394
+ implementationType: "function",
395
+ implementationConfig: { handler: "evaluateMath" },
396
+ timeoutMs: 5000,
397
+ version: "1.0.0",
398
+ tags: ["math", "utility"],
399
+ createdAt: new Date("2024-01-10T00:00:00Z"),
400
+ updatedAt: new Date("2024-01-10T00:00:00Z")
401
+ }
402
+ ];
403
+
404
+ // src/shared/mock-runs.ts
405
+ var MOCK_RUNS = [
406
+ {
407
+ id: "run-1",
408
+ organizationId: "demo-org",
409
+ projectId: "demo-project",
410
+ agentId: "agent-1",
411
+ agentName: "Customer Support Bot",
412
+ userId: "user-1",
413
+ sessionId: "session-1",
414
+ input: { message: "How do I reset my password?", context: {} },
415
+ output: { response: "You can reset your password by clicking..." },
416
+ status: "COMPLETED",
417
+ totalTokens: 1250,
418
+ promptTokens: 800,
419
+ completionTokens: 450,
420
+ totalIterations: 3,
421
+ durationMs: 4500,
422
+ estimatedCostUsd: 0.0025,
423
+ queuedAt: new Date("2024-04-15T10:00:00Z"),
424
+ startedAt: new Date("2024-04-15T10:00:01Z"),
425
+ completedAt: new Date("2024-04-15T10:00:05Z"),
426
+ steps: [],
427
+ logs: []
428
+ },
429
+ {
430
+ id: "run-2",
431
+ organizationId: "demo-org",
432
+ projectId: "demo-project",
433
+ agentId: "agent-2",
434
+ agentName: "Code Review Assistant",
435
+ userId: "user-2",
436
+ input: { message: "Review PR #123", context: { prNumber: 123 } },
437
+ status: "IN_PROGRESS",
438
+ totalTokens: 3500,
439
+ promptTokens: 3000,
440
+ completionTokens: 500,
441
+ totalIterations: 5,
442
+ queuedAt: new Date("2024-04-15T10:30:00Z"),
443
+ startedAt: new Date("2024-04-15T10:30:02Z"),
444
+ steps: [],
445
+ logs: []
446
+ },
447
+ {
448
+ id: "run-3",
449
+ organizationId: "demo-org",
450
+ projectId: "demo-project",
451
+ agentId: "agent-1",
452
+ agentName: "Customer Support Bot",
453
+ userId: "user-1",
454
+ input: { message: "What are your business hours?" },
455
+ output: { response: "Our business hours are 9 AM to 5 PM EST..." },
456
+ status: "COMPLETED",
457
+ totalTokens: 800,
458
+ promptTokens: 500,
459
+ completionTokens: 300,
460
+ totalIterations: 2,
461
+ durationMs: 2100,
462
+ estimatedCostUsd: 0.0012,
463
+ queuedAt: new Date("2024-04-15T09:00:00Z"),
464
+ startedAt: new Date("2024-04-15T09:00:01Z"),
465
+ completedAt: new Date("2024-04-15T09:00:03Z"),
466
+ steps: [],
467
+ logs: []
468
+ },
469
+ {
470
+ id: "run-4",
471
+ organizationId: "demo-org",
472
+ projectId: "demo-project",
473
+ agentId: "agent-3",
474
+ agentName: "Data Analyst",
475
+ userId: "user-3",
476
+ input: { message: "Generate sales report for Q1" },
477
+ status: "FAILED",
478
+ errorMessage: "Database connection timeout",
479
+ errorCode: "DB_TIMEOUT",
480
+ totalTokens: 2000,
481
+ promptTokens: 1500,
482
+ completionTokens: 500,
483
+ totalIterations: 8,
484
+ durationMs: 45000,
485
+ queuedAt: new Date("2024-04-14T15:00:00Z"),
486
+ startedAt: new Date("2024-04-14T15:00:05Z"),
487
+ completedAt: new Date("2024-04-14T15:00:50Z"),
488
+ steps: [],
489
+ logs: []
490
+ },
491
+ {
492
+ id: "run-5",
493
+ organizationId: "demo-org",
494
+ projectId: "demo-project",
495
+ agentId: "agent-2",
496
+ agentName: "Code Review Assistant",
497
+ userId: "user-2",
498
+ input: { message: "Review PR #120" },
499
+ output: { response: "Code review complete. 3 suggestions..." },
500
+ status: "COMPLETED",
501
+ totalTokens: 5200,
502
+ promptTokens: 4000,
503
+ completionTokens: 1200,
504
+ totalIterations: 7,
505
+ durationMs: 15000,
506
+ estimatedCostUsd: 0.0156,
507
+ queuedAt: new Date("2024-04-14T11:00:00Z"),
508
+ startedAt: new Date("2024-04-14T11:00:03Z"),
509
+ completedAt: new Date("2024-04-14T11:00:18Z"),
510
+ steps: [],
511
+ logs: []
512
+ }
513
+ ];
514
+
515
+ // src/ui/AgentDashboard.visualizations.tsx
516
+ import {
517
+ VisualizationCard,
518
+ VisualizationGrid
519
+ } from "@contractspec/lib.design-system";
520
+ import { jsxDEV } from "react/jsx-dev-runtime";
521
+ "use client";
522
+ function AgentVisualizationOverview({ runs }) {
523
+ const items = createAgentVisualizationItems(runs);
524
+ return /* @__PURE__ */ jsxDEV("section", {
525
+ className: "space-y-3",
526
+ children: [
527
+ /* @__PURE__ */ jsxDEV("div", {
528
+ children: [
529
+ /* @__PURE__ */ jsxDEV("h3", {
530
+ className: "font-semibold text-lg",
531
+ children: "Operational Visualizations"
532
+ }, undefined, false, undefined, this),
533
+ /* @__PURE__ */ jsxDEV("p", {
534
+ className: "text-muted-foreground text-sm",
535
+ children: "Contract-backed charts derived from recent run activity."
536
+ }, undefined, false, undefined, this)
537
+ ]
538
+ }, undefined, true, undefined, this),
539
+ /* @__PURE__ */ jsxDEV(VisualizationGrid, {
540
+ children: items.map((item) => /* @__PURE__ */ jsxDEV(VisualizationCard, {
541
+ data: item.data,
542
+ description: item.description,
543
+ height: item.height,
544
+ spec: item.spec,
545
+ title: item.title
546
+ }, item.key, false, undefined, this))
547
+ }, undefined, false, undefined, this)
548
+ ]
549
+ }, undefined, true, undefined, this);
550
+ }
551
+
552
+ // src/ui/hooks/useAgentList.ts
4
553
  import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
5
- function useRunList(options = {}) {
554
+ import { useCallback, useEffect, useMemo, useState } from "react";
555
+ function useAgentList(options = {}) {
6
556
  const { handlers, projectId } = useTemplateRuntime();
7
557
  const { agent } = handlers;
8
558
  const [data, setData] = useState(null);
9
- const [metrics, setMetrics] = useState(null);
10
559
  const [loading, setLoading] = useState(true);
11
560
  const [error, setError] = useState(null);
12
561
  const [page, setPage] = useState(1);
@@ -14,37 +563,38 @@ function useRunList(options = {}) {
14
563
  setLoading(true);
15
564
  setError(null);
16
565
  try {
17
- const [runsResult, metricsResult] = await Promise.all([
18
- agent.listRuns({
19
- projectId,
20
- agentId: options.agentId,
21
- status: options.status === "all" ? undefined : options.status,
22
- limit: options.limit ?? 20,
23
- offset: (page - 1) * (options.limit ?? 20)
24
- }),
25
- agent.getRunMetrics({
26
- projectId,
27
- agentId: options.agentId,
28
- startDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
29
- endDate: new Date
30
- })
31
- ]);
32
- setData(runsResult);
33
- setMetrics(metricsResult);
566
+ const result = await agent.listAgents({
567
+ projectId,
568
+ search: options.search,
569
+ status: options.status === "all" ? undefined : options.status,
570
+ limit: options.limit ?? 20,
571
+ offset: (page - 1) * (options.limit ?? 20)
572
+ });
573
+ setData(result);
34
574
  } catch (err) {
35
575
  setError(err instanceof Error ? err : new Error("Unknown error"));
36
576
  } finally {
37
577
  setLoading(false);
38
578
  }
39
- }, [agent, projectId, options.agentId, options.status, options.limit, page]);
579
+ }, [agent, projectId, options.search, options.status, options.limit, page]);
40
580
  useEffect(() => {
41
581
  fetchData();
42
582
  }, [fetchData]);
583
+ const stats = useMemo(() => {
584
+ if (!data)
585
+ return null;
586
+ return {
587
+ total: data.total,
588
+ active: data.items.filter((a) => a.status === "ACTIVE").length,
589
+ paused: data.items.filter((a) => a.status === "PAUSED").length,
590
+ draft: data.items.filter((a) => a.status === "DRAFT").length
591
+ };
592
+ }, [data]);
43
593
  return {
44
594
  data,
45
- metrics,
46
595
  loading,
47
596
  error,
597
+ stats,
48
598
  page,
49
599
  refetch: fetchData,
50
600
  nextPage: () => setPage((p) => p + 1),
@@ -52,497 +602,142 @@ function useRunList(options = {}) {
52
602
  };
53
603
  }
54
604
 
55
- // src/ui/views/RunListView.tsx
56
- import {
57
- StatCard,
58
- StatCardGroup,
59
- StatusChip,
60
- EmptyState,
61
- LoaderBlock,
62
- ErrorState
63
- } from "@contractspec/lib.design-system";
64
- import { jsxDEV } from "react/jsx-dev-runtime";
65
- "use client";
66
- function getStatusTone(status) {
67
- switch (status) {
68
- case "COMPLETED":
69
- return "success";
70
- case "RUNNING":
71
- return "warning";
72
- case "QUEUED":
73
- return "neutral";
74
- case "FAILED":
75
- case "CANCELLED":
76
- return "danger";
77
- default:
78
- return "neutral";
79
- }
605
+ // src/ui/hooks/useAgentMutations.ts
606
+ import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
607
+ import { useCallback as useCallback2, useState as useState2 } from "react";
608
+
609
+ // src/shared/demo-runtime-seed.ts
610
+ var AGENT_CONSOLE_DEMO_ORGANIZATION_ID = "demo-org";
611
+ var AGENT_CONSOLE_DEMO_PROJECT_ID = "agent-console-demo";
612
+ function slugify(name) {
613
+ return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
80
614
  }
81
- function formatDuration(ms) {
82
- if (!ms)
83
- return "-";
84
- if (ms < 1000)
85
- return `${ms}ms`;
86
- if (ms < 60000)
87
- return `${(ms / 1000).toFixed(1)}s`;
88
- return `${(ms / 60000).toFixed(1)}m`;
615
+ function cloneAgent(agent) {
616
+ return { ...agent };
89
617
  }
90
- function formatTokens(tokens) {
91
- if (tokens < 1000)
92
- return tokens.toString();
93
- if (tokens < 1e6)
94
- return `${(tokens / 1000).toFixed(1)}K`;
95
- return `${(tokens / 1e6).toFixed(2)}M`;
618
+ function cloneTool(tool) {
619
+ return { ...tool };
96
620
  }
97
- function formatCost(cost) {
98
- if (!cost)
99
- return "-";
100
- return `$${cost.toFixed(4)}`;
621
+ function cloneRun(run) {
622
+ return { ...run };
101
623
  }
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);
259
- setError(null);
260
- try {
261
- const result = await agent.listTools({
262
- projectId,
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);
270
- } catch (err) {
271
- setError(err instanceof Error ? err : new Error("Unknown error"));
272
- } finally {
273
- setLoading(false);
274
- }
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
- };
328
- }
329
-
330
- // src/ui/views/ToolRegistryView.tsx
331
- import {
332
- StatCard as StatCard2,
333
- StatCardGroup as StatCardGroup2,
334
- StatusChip as StatusChip2,
335
- EntityCard,
336
- EmptyState as EmptyState2,
337
- LoaderBlock as LoaderBlock2,
338
- ErrorState as ErrorState2,
339
- Button
340
- } from "@contractspec/lib.design-system";
341
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
342
- "use client";
343
- var categoryIcons = {
344
- RETRIEVAL: "\uD83D\uDD0D",
345
- COMPUTATION: "\uD83E\uDDEE",
346
- COMMUNICATION: "\uD83D\uDCE7",
347
- INTEGRATION: "\uD83D\uDD17",
348
- UTILITY: "\uD83D\uDEE0\uFE0F",
349
- CUSTOM: "\u2699\uFE0F"
350
- };
351
- function getStatusTone2(status) {
352
- switch (status) {
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",
395
- children: [
396
- /* @__PURE__ */ jsxDEV2(StatCardGroup2, {
397
- children: [
398
- /* @__PURE__ */ jsxDEV2(StatCard2, {
399
- label: "Total Tools",
400
- value: data.total
401
- }, undefined, false, undefined, this),
402
- categoryStats.slice(0, 3).map(({ category, count }) => /* @__PURE__ */ jsxDEV2(StatCard2, {
403
- label: `${categoryIcons[category] ?? ""} ${category}`,
404
- value: count
405
- }, category, false, undefined, this))
406
- ]
407
- }, undefined, true, undefined, this),
408
- Object.entries(groupedByCategory).map(([category, tools]) => /* @__PURE__ */ jsxDEV2("section", {
409
- className: "space-y-4",
410
- children: [
411
- /* @__PURE__ */ jsxDEV2("div", {
412
- className: "flex items-center gap-2",
413
- children: [
414
- /* @__PURE__ */ jsxDEV2("span", {
415
- className: "text-2xl",
416
- children: categoryIcons[category]
417
- }, undefined, false, undefined, this),
418
- /* @__PURE__ */ jsxDEV2("h3", {
419
- className: "text-lg font-semibold",
420
- children: category
421
- }, undefined, false, undefined, this),
422
- /* @__PURE__ */ jsxDEV2("span", {
423
- className: "bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-xs",
424
- children: tools.length
425
- }, undefined, false, undefined, this)
426
- ]
427
- }, undefined, true, undefined, this),
428
- /* @__PURE__ */ jsxDEV2("div", {
429
- className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
430
- children: tools.map((tool) => /* @__PURE__ */ jsxDEV2(EntityCard, {
431
- cardTitle: tool.name,
432
- cardSubtitle: `v${tool.version}`,
433
- meta: /* @__PURE__ */ jsxDEV2("p", {
434
- className: "text-muted-foreground text-sm",
435
- children: tool.description
436
- }, undefined, false, undefined, this),
437
- chips: /* @__PURE__ */ jsxDEV2(StatusChip2, {
438
- tone: getStatusTone2(tool.status),
439
- label: tool.status
440
- }, undefined, false, undefined, this),
441
- footer: /* @__PURE__ */ jsxDEV2("code", {
442
- className: "text-muted-foreground text-xs",
443
- children: tool.name
444
- }, undefined, false, undefined, this),
445
- onClick: onToolClick ? () => onToolClick(tool.id) : undefined
446
- }, tool.id, false, undefined, this))
447
- }, undefined, false, undefined, this)
448
- ]
449
- }, category, true, undefined, this))
450
- ]
451
- }, undefined, true, undefined, this);
452
- }
453
-
454
- // src/ui/hooks/useAgentList.ts
455
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react";
456
- import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
457
- function useAgentList(options = {}) {
458
- const { handlers, projectId } = useTemplateRuntime3();
459
- const { agent } = handlers;
460
- const [data, setData] = useState3(null);
461
- const [loading, setLoading] = useState3(true);
462
- const [error, setError] = useState3(null);
463
- const [page, setPage] = useState3(1);
464
- const fetchData = useCallback3(async () => {
465
- setLoading(true);
466
- setError(null);
467
- try {
468
- const result = await agent.listAgents({
469
- projectId,
470
- search: options.search,
471
- status: options.status === "all" ? undefined : options.status,
472
- limit: options.limit ?? 20,
473
- offset: (page - 1) * (options.limit ?? 20)
474
- });
475
- setData(result);
476
- } catch (err) {
477
- setError(err instanceof Error ? err : new Error("Unknown error"));
478
- } finally {
479
- setLoading(false);
480
- }
481
- }, [agent, projectId, options.search, options.status, options.limit, page]);
482
- useEffect3(() => {
483
- fetchData();
484
- }, [fetchData]);
485
- const stats = useMemo2(() => {
486
- if (!data)
487
- return null;
488
- return {
489
- total: data.total,
490
- active: data.items.filter((a) => a.status === "ACTIVE").length,
491
- paused: data.items.filter((a) => a.status === "PAUSED").length,
492
- draft: data.items.filter((a) => a.status === "DRAFT").length
493
- };
494
- }, [data]);
495
- return {
496
- data,
497
- loading,
498
- error,
499
- stats,
500
- page,
501
- refetch: fetchData,
502
- nextPage: () => setPage((p) => p + 1),
503
- prevPage: () => page > 1 && setPage((p) => p - 1)
504
- };
624
+ function createDefaultNow() {
625
+ let tick = 0;
626
+ const base = Date.parse("2026-03-20T09:00:00.000Z");
627
+ return () => new Date(base + tick++ * 60000);
628
+ }
629
+ function normalizeProvider(provider) {
630
+ return provider.toLowerCase();
631
+ }
632
+ function normalizeRunStatus(status) {
633
+ return status === "IN_PROGRESS" ? "RUNNING" : status;
634
+ }
635
+ function createSeedState(projectId, organizationId) {
636
+ const agents = MOCK_AGENTS.map((agent) => ({
637
+ id: agent.id,
638
+ projectId,
639
+ organizationId,
640
+ name: agent.name,
641
+ slug: agent.slug,
642
+ description: agent.description,
643
+ modelProvider: normalizeProvider(agent.modelProvider),
644
+ modelName: agent.modelName,
645
+ systemPrompt: agent.systemPrompt,
646
+ temperature: typeof agent.modelConfig?.temperature === "number" ? agent.modelConfig.temperature : 0.4,
647
+ maxTokens: 8192,
648
+ status: agent.status,
649
+ createdAt: agent.createdAt,
650
+ updatedAt: agent.updatedAt
651
+ }));
652
+ const tools = MOCK_TOOLS.map((tool) => ({
653
+ id: tool.id,
654
+ projectId,
655
+ organizationId,
656
+ name: tool.name,
657
+ description: tool.description,
658
+ version: tool.version,
659
+ category: tool.category,
660
+ status: tool.status,
661
+ inputSchema: JSON.stringify(tool.parametersSchema),
662
+ outputSchema: tool.outputSchema ? JSON.stringify(tool.outputSchema) : undefined,
663
+ endpoint: typeof tool.implementationConfig?.url === "string" ? tool.implementationConfig.url : undefined,
664
+ createdAt: tool.createdAt,
665
+ updatedAt: tool.updatedAt
666
+ }));
667
+ const agentNames = new Map(agents.map((agent) => [agent.id, agent.name]));
668
+ const runs = MOCK_RUNS.map((run) => ({
669
+ id: run.id,
670
+ projectId,
671
+ agentId: run.agentId,
672
+ agentName: agentNames.get(run.agentId) ?? run.agentName ?? "Unknown agent",
673
+ status: normalizeRunStatus(run.status),
674
+ input: JSON.stringify(run.input),
675
+ output: run.output ? JSON.stringify(run.output) : undefined,
676
+ totalTokens: run.totalTokens,
677
+ promptTokens: run.promptTokens,
678
+ completionTokens: run.completionTokens,
679
+ estimatedCostUsd: run.estimatedCostUsd ?? 0,
680
+ durationMs: run.durationMs,
681
+ errorMessage: run.errorMessage,
682
+ queuedAt: run.queuedAt,
683
+ startedAt: run.startedAt,
684
+ completedAt: run.completedAt
685
+ }));
686
+ return { agents, tools, runs };
687
+ }
688
+ function summarizeRunMetrics(runs) {
689
+ const totalRuns = runs.length;
690
+ const completedRuns = runs.filter((run) => run.status === "COMPLETED").length;
691
+ const completedDurations = runs.map((run) => run.durationMs).filter((duration) => typeof duration === "number");
692
+ return {
693
+ totalRuns,
694
+ successRate: totalRuns === 0 ? 0 : completedRuns / totalRuns,
695
+ averageDurationMs: completedDurations.length === 0 ? 0 : Math.round(completedDurations.reduce((sum, duration) => sum + duration, 0) / completedDurations.length),
696
+ totalTokens: runs.reduce((sum, run) => sum + run.totalTokens, 0),
697
+ totalCostUsd: runs.reduce((sum, run) => sum + run.estimatedCostUsd, 0)
698
+ };
505
699
  }
506
700
 
507
701
  // src/ui/hooks/useAgentMutations.ts
508
- import { useCallback as useCallback4, useState as useState4 } from "react";
509
- import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
702
+ function normalizeMutationError(error, fallbackMessage) {
703
+ return error instanceof Error ? error : new Error(fallbackMessage);
704
+ }
510
705
  function useAgentMutations(options = {}) {
511
- const { handlers, projectId } = useTemplateRuntime4();
706
+ const { handlers, projectId } = useTemplateRuntime2();
512
707
  const { agent } = handlers;
513
- const [createState, setCreateState] = useState4({
708
+ const [createState, setCreateState] = useState2({
514
709
  loading: false,
515
710
  error: null,
516
711
  data: null
517
712
  });
518
- const [updateState, setUpdateState] = useState4({
713
+ const [updateState, setUpdateState] = useState2({
519
714
  loading: false,
520
715
  error: null,
521
716
  data: null
522
717
  });
523
- const [executeState, setExecuteState] = useState4({
718
+ const [executeState, setExecuteState] = useState2({
524
719
  loading: false,
525
720
  error: null,
526
721
  data: null
527
722
  });
528
- const createAgent = useCallback4(async (input) => {
723
+ const createAgent = useCallback2(async (input) => {
529
724
  setCreateState({ loading: true, error: null, data: null });
530
725
  try {
531
726
  const result = await agent.createAgent(input, {
532
727
  projectId,
533
- organizationId: "demo-org"
728
+ organizationId: AGENT_CONSOLE_DEMO_ORGANIZATION_ID
534
729
  });
535
730
  setCreateState({ loading: false, error: null, data: result });
536
731
  options.onSuccess?.();
537
732
  return result;
538
733
  } catch (err) {
539
- const error = err instanceof Error ? err : new Error("Failed to create agent");
734
+ const error = normalizeMutationError(err, "Failed to create agent");
540
735
  setCreateState({ loading: false, error, data: null });
541
736
  options.onError?.(error);
542
- return null;
737
+ throw error;
543
738
  }
544
739
  }, [agent, projectId, options]);
545
- const updateAgent = useCallback4(async (input) => {
740
+ const updateAgent = useCallback2(async (input) => {
546
741
  setUpdateState({ loading: true, error: null, data: null });
547
742
  try {
548
743
  const result = await agent.updateAgent(input);
@@ -550,37 +745,40 @@ function useAgentMutations(options = {}) {
550
745
  options.onSuccess?.();
551
746
  return result;
552
747
  } catch (err) {
553
- const error = err instanceof Error ? err : new Error("Failed to update agent");
748
+ const error = normalizeMutationError(err, "Failed to update agent");
554
749
  setUpdateState({ loading: false, error, data: null });
555
750
  options.onError?.(error);
556
- return null;
751
+ throw error;
557
752
  }
558
753
  }, [agent, options]);
559
- const activateAgent = useCallback4(async (agentId) => {
754
+ const activateAgent = useCallback2(async (agentId) => {
560
755
  return updateAgent({ id: agentId, status: "ACTIVE" });
561
756
  }, [updateAgent]);
562
- const pauseAgent = useCallback4(async (agentId) => {
757
+ const pauseAgent = useCallback2(async (agentId) => {
563
758
  return updateAgent({ id: agentId, status: "PAUSED" });
564
759
  }, [updateAgent]);
565
- const archiveAgent = useCallback4(async (agentId) => {
760
+ const archiveAgent = useCallback2(async (agentId) => {
566
761
  return updateAgent({ id: agentId, status: "ARCHIVED" });
567
762
  }, [updateAgent]);
568
- const executeAgent = useCallback4(async (input) => {
763
+ const executeAgent = useCallback2(async (input) => {
569
764
  setExecuteState({ loading: true, error: null, data: null });
570
765
  try {
571
766
  const result = await agent.executeAgent({
572
767
  agentId: input.agentId,
573
768
  message: input.message,
574
- context: { projectId, organizationId: "demo-org" }
769
+ context: {
770
+ projectId,
771
+ organizationId: AGENT_CONSOLE_DEMO_ORGANIZATION_ID
772
+ }
575
773
  });
576
774
  setExecuteState({ loading: false, error: null, data: result });
577
775
  options.onSuccess?.();
578
776
  return result;
579
777
  } catch (err) {
580
- const error = err instanceof Error ? err : new Error("Failed to execute agent");
778
+ const error = normalizeMutationError(err, "Failed to execute agent");
581
779
  setExecuteState({ loading: false, error, data: null });
582
780
  options.onError?.(error);
583
- return null;
781
+ throw error;
584
782
  }
585
783
  }, [agent, projectId, options]);
586
784
  return {
@@ -597,251 +795,78 @@ function useAgentMutations(options = {}) {
597
795
  };
598
796
  }
599
797
 
600
- // src/ui/modals/CreateAgentModal.tsx
601
- import { useState as useState5 } from "react";
602
- import { Button as Button2, Input } from "@contractspec/lib.design-system";
603
- import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
604
- "use client";
605
- var MODEL_PROVIDERS = [
606
- {
607
- value: "openai",
608
- label: "OpenAI",
609
- models: ["gpt-5.4", "gpt-5-mini", "gpt-4o", "gpt-4-turbo", "gpt-3.5-turbo"]
610
- },
611
- {
612
- value: "anthropic",
613
- label: "Anthropic",
614
- models: ["claude-sonnet-4-6", "claude-opus-4-6", "claude-haiku-4-5"]
615
- },
616
- {
617
- value: "google",
618
- label: "Google",
619
- models: [
620
- "gemini-2.5-flash",
621
- "gemini-2.5-pro",
622
- "gemini-pro",
623
- "gemini-ultra"
624
- ]
625
- },
626
- {
627
- value: "mistral",
628
- label: "Mistral",
629
- models: [
630
- "mistral-large-2512",
631
- "mistral-large-latest",
632
- "mistral-medium-latest",
633
- "mistral-small-latest"
634
- ]
635
- }
636
- ];
637
- function CreateAgentModal({
638
- isOpen,
639
- onClose,
640
- onSubmit,
641
- isLoading = false
642
- }) {
643
- const [name, setName] = useState5("");
644
- const [description, setDescription] = useState5("");
645
- const [modelProvider, setModelProvider] = useState5("openai");
646
- const [modelName, setModelName] = useState5("gpt-5.4");
647
- const [systemPrompt, setSystemPrompt] = useState5("");
648
- const [error, setError] = useState5(null);
649
- const selectedProvider = MODEL_PROVIDERS.find((p) => p.value === modelProvider);
650
- const handleSubmit = async (e) => {
651
- e.preventDefault();
798
+ // src/ui/hooks/useRunList.ts
799
+ import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
800
+ import { useCallback as useCallback3, useEffect as useEffect2, useState as useState3 } from "react";
801
+ function useRunList(options = {}) {
802
+ const { handlers, projectId } = useTemplateRuntime3();
803
+ const { agent } = handlers;
804
+ const [data, setData] = useState3(null);
805
+ const [metrics, setMetrics] = useState3(null);
806
+ const [loading, setLoading] = useState3(true);
807
+ const [error, setError] = useState3(null);
808
+ const [internalPageIndex, setInternalPageIndex] = useState3(0);
809
+ const pageSize = options.pageSize ?? options.limit ?? 20;
810
+ const pageIndex = options.pageIndex ?? internalPageIndex;
811
+ const [sort] = options.sorting ?? [];
812
+ const fetchData = useCallback3(async () => {
813
+ setLoading(true);
652
814
  setError(null);
653
- if (!name.trim()) {
654
- setError("Agent name is required");
655
- return;
656
- }
657
815
  try {
658
- await onSubmit({
659
- name: name.trim(),
660
- description: description.trim() || undefined,
661
- modelProvider,
662
- modelName,
663
- systemPrompt: systemPrompt.trim() || undefined
664
- });
665
- setName("");
666
- setDescription("");
667
- setModelProvider("openai");
668
- setModelName("gpt-5.4");
669
- setSystemPrompt("");
670
- onClose();
816
+ const [runsResult, metricsResult] = await Promise.all([
817
+ agent.listRuns({
818
+ projectId,
819
+ agentId: options.agentId,
820
+ status: options.status === "all" ? undefined : options.status,
821
+ sortBy: sort?.id,
822
+ sortDirection: sort ? sort.desc ? "desc" : "asc" : undefined,
823
+ limit: pageSize,
824
+ offset: pageIndex * pageSize
825
+ }),
826
+ agent.getRunMetrics({
827
+ projectId,
828
+ agentId: options.agentId
829
+ })
830
+ ]);
831
+ setData(runsResult);
832
+ setMetrics(metricsResult);
671
833
  } catch (err) {
672
- setError(err instanceof Error ? err.message : "Failed to create agent");
673
- }
674
- };
675
- const handleProviderChange = (provider) => {
676
- setModelProvider(provider);
677
- const providerConfig = MODEL_PROVIDERS.find((p) => p.value === provider);
678
- if (providerConfig) {
679
- setModelName(providerConfig.models[0]);
834
+ setError(err instanceof Error ? err : new Error("Unknown error"));
835
+ } finally {
836
+ setLoading(false);
680
837
  }
838
+ }, [
839
+ agent,
840
+ pageIndex,
841
+ pageSize,
842
+ projectId,
843
+ options.agentId,
844
+ options.status,
845
+ sort?.desc,
846
+ sort?.id
847
+ ]);
848
+ useEffect2(() => {
849
+ fetchData();
850
+ }, [fetchData]);
851
+ const hasControlledPagination = options.pageIndex !== undefined;
852
+ return {
853
+ data,
854
+ metrics,
855
+ loading,
856
+ error,
857
+ page: pageIndex + 1,
858
+ pageIndex,
859
+ pageSize,
860
+ refetch: fetchData,
861
+ nextPage: hasControlledPagination ? undefined : () => setInternalPageIndex((current) => current + 1),
862
+ prevPage: hasControlledPagination ? undefined : () => setInternalPageIndex((current) => Math.max(0, current - 1))
681
863
  };
682
- if (!isOpen)
683
- return null;
684
- return /* @__PURE__ */ jsxDEV3("div", {
685
- className: "fixed inset-0 z-50 flex items-center justify-center",
686
- children: [
687
- /* @__PURE__ */ jsxDEV3("div", {
688
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
689
- onClick: onClose,
690
- role: "button",
691
- tabIndex: 0,
692
- onKeyDown: (e) => {
693
- if (e.key === "Enter" || e.key === " ")
694
- onClose();
695
- },
696
- "aria-label": "Close modal"
697
- }, undefined, false, undefined, this),
698
- /* @__PURE__ */ jsxDEV3("div", {
699
- className: "bg-card border-border relative z-10 max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-xl border p-6 shadow-xl",
700
- children: [
701
- /* @__PURE__ */ jsxDEV3("h2", {
702
- className: "mb-4 text-xl font-semibold",
703
- children: "Create New Agent"
704
- }, undefined, false, undefined, this),
705
- /* @__PURE__ */ jsxDEV3("form", {
706
- onSubmit: handleSubmit,
707
- className: "space-y-4",
708
- children: [
709
- /* @__PURE__ */ jsxDEV3("div", {
710
- children: [
711
- /* @__PURE__ */ jsxDEV3("label", {
712
- htmlFor: "agent-name",
713
- className: "text-muted-foreground mb-1 block text-sm font-medium",
714
- children: "Agent Name *"
715
- }, undefined, false, undefined, this),
716
- /* @__PURE__ */ jsxDEV3(Input, {
717
- id: "agent-name",
718
- value: name,
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"
731
- }, undefined, false, undefined, this),
732
- /* @__PURE__ */ jsxDEV3("textarea", {
733
- id: "agent-description",
734
- value: description,
735
- onChange: (e) => setDescription(e.target.value),
736
- placeholder: "Describe what this agent does...",
737
- rows: 2,
738
- disabled: isLoading,
739
- 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"
740
- }, undefined, false, undefined, this)
741
- ]
742
- }, undefined, true, undefined, this),
743
- /* @__PURE__ */ jsxDEV3("div", {
744
- className: "flex gap-3",
745
- children: [
746
- /* @__PURE__ */ jsxDEV3("div", {
747
- className: "flex-1",
748
- children: [
749
- /* @__PURE__ */ jsxDEV3("label", {
750
- htmlFor: "model-provider",
751
- className: "text-muted-foreground mb-1 block text-sm font-medium",
752
- children: "Provider *"
753
- }, undefined, false, undefined, this),
754
- /* @__PURE__ */ jsxDEV3("select", {
755
- id: "model-provider",
756
- value: modelProvider,
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))
764
- }, undefined, false, undefined, this)
765
- ]
766
- }, undefined, true, undefined, this),
767
- /* @__PURE__ */ jsxDEV3("div", {
768
- className: "flex-1",
769
- children: [
770
- /* @__PURE__ */ jsxDEV3("label", {
771
- htmlFor: "model-name",
772
- className: "text-muted-foreground mb-1 block text-sm font-medium",
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"
796
- }, undefined, false, undefined, this),
797
- /* @__PURE__ */ jsxDEV3("textarea", {
798
- id: "system-prompt",
799
- value: systemPrompt,
800
- onChange: (e) => setSystemPrompt(e.target.value),
801
- placeholder: "You are a helpful assistant that...",
802
- rows: 4,
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"
805
- }, undefined, false, undefined, this),
806
- /* @__PURE__ */ jsxDEV3("p", {
807
- className: "text-muted-foreground mt-1 text-xs",
808
- children: "Instructions that define the agent's behavior"
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"
825
- }, undefined, false, undefined, this),
826
- /* @__PURE__ */ jsxDEV3(Button2, {
827
- type: "submit",
828
- disabled: isLoading,
829
- children: isLoading ? "Creating..." : "Create Agent"
830
- }, undefined, false, undefined, this)
831
- ]
832
- }, undefined, true, undefined, this)
833
- ]
834
- }, undefined, true, undefined, this)
835
- ]
836
- }, undefined, true, undefined, this)
837
- ]
838
- }, undefined, true, undefined, this);
839
864
  }
840
865
 
841
866
  // src/ui/modals/AgentActionsModal.tsx
842
- import { useState as useState6 } from "react";
843
- import { Button as Button3 } from "@contractspec/lib.design-system";
844
- import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
867
+ import { Button } from "@contractspec/lib.design-system";
868
+ import { useState as useState4 } from "react";
869
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
845
870
  "use client";
846
871
  function getStatusColor(status) {
847
872
  switch (status) {
@@ -867,10 +892,10 @@ function AgentActionsModal({
867
892
  onExecute,
868
893
  isLoading = false
869
894
  }) {
870
- const [mode, setMode] = useState6("menu");
871
- const [message, setMessage] = useState6("");
872
- const [confirmAction, setConfirmAction] = useState6(null);
873
- const [error, setError] = useState6(null);
895
+ const [mode, setMode] = useState4("menu");
896
+ const [message, setMessage] = useState4("");
897
+ const [confirmAction, setConfirmAction] = useState4(null);
898
+ const [error, setError] = useState4(null);
874
899
  const resetForm = () => {
875
900
  setMode("menu");
876
901
  setMessage("");
@@ -919,11 +944,11 @@ function AgentActionsModal({
919
944
  };
920
945
  if (!isOpen || !agent)
921
946
  return null;
922
- return /* @__PURE__ */ jsxDEV4("div", {
947
+ return /* @__PURE__ */ jsxDEV2("div", {
923
948
  className: "fixed inset-0 z-50 flex items-center justify-center",
924
949
  children: [
925
- /* @__PURE__ */ jsxDEV4("div", {
926
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
950
+ /* @__PURE__ */ jsxDEV2("div", {
951
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
927
952
  onClick: handleClose,
928
953
  role: "button",
929
954
  tabIndex: 0,
@@ -933,20 +958,20 @@ function AgentActionsModal({
933
958
  },
934
959
  "aria-label": "Close modal"
935
960
  }, undefined, false, undefined, this),
936
- /* @__PURE__ */ jsxDEV4("div", {
937
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
961
+ /* @__PURE__ */ jsxDEV2("div", {
962
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
938
963
  children: [
939
- /* @__PURE__ */ jsxDEV4("div", {
940
- className: "border-border mb-4 border-b pb-4",
964
+ /* @__PURE__ */ jsxDEV2("div", {
965
+ className: "mb-4 border-border border-b pb-4",
941
966
  children: [
942
- /* @__PURE__ */ jsxDEV4("h2", {
943
- className: "text-xl font-semibold",
967
+ /* @__PURE__ */ jsxDEV2("h2", {
968
+ className: "font-semibold text-xl",
944
969
  children: agent.name
945
970
  }, undefined, false, undefined, this),
946
- /* @__PURE__ */ jsxDEV4("div", {
971
+ /* @__PURE__ */ jsxDEV2("div", {
947
972
  className: "mt-1 flex items-center gap-2",
948
973
  children: [
949
- /* @__PURE__ */ jsxDEV4("span", {
974
+ /* @__PURE__ */ jsxDEV2("span", {
950
975
  className: "text-muted-foreground text-sm",
951
976
  children: [
952
977
  agent.modelProvider,
@@ -954,207 +979,1064 @@ function AgentActionsModal({
954
979
  agent.modelName
955
980
  ]
956
981
  }, undefined, true, undefined, this),
957
- /* @__PURE__ */ jsxDEV4("span", {
958
- className: `rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(agent.status)}`,
982
+ /* @__PURE__ */ jsxDEV2("span", {
983
+ className: `rounded-full px-2 py-0.5 font-medium text-xs ${getStatusColor(agent.status)}`,
959
984
  children: agent.status
960
985
  }, undefined, false, undefined, this)
961
986
  ]
962
987
  }, undefined, true, undefined, this),
963
- agent.description && /* @__PURE__ */ jsxDEV4("p", {
964
- className: "text-muted-foreground mt-2 text-sm",
988
+ agent.description && /* @__PURE__ */ jsxDEV2("p", {
989
+ className: "mt-2 text-muted-foreground text-sm",
965
990
  children: agent.description
966
991
  }, undefined, false, undefined, this)
967
992
  ]
968
993
  }, undefined, true, undefined, this),
969
- mode === "menu" && /* @__PURE__ */ jsxDEV4("div", {
994
+ mode === "menu" && /* @__PURE__ */ jsxDEV2("div", {
970
995
  className: "space-y-3",
971
996
  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
997
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV2(Button, {
998
+ className: "w-full justify-start",
999
+ variant: "ghost",
1000
+ onPress: () => setMode("execute"),
1001
+ children: [
1002
+ /* @__PURE__ */ jsxDEV2("span", {
1003
+ className: "mr-2",
1004
+ children: "\u25B6\uFE0F"
1005
+ }, undefined, false, undefined, this),
1006
+ " Execute Agent"
1007
+ ]
1008
+ }, undefined, true, undefined, this),
1009
+ (agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxDEV2(Button, {
1010
+ className: "w-full justify-start",
1011
+ variant: "ghost",
1012
+ onPress: () => handleStatusChange("activate"),
1013
+ disabled: isLoading,
1014
+ children: [
1015
+ /* @__PURE__ */ jsxDEV2("span", {
1016
+ className: "mr-2",
1017
+ children: "\uD83D\uDFE2"
1018
+ }, undefined, false, undefined, this),
1019
+ " Activate Agent"
1020
+ ]
1021
+ }, undefined, true, undefined, this),
1022
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV2(Button, {
1023
+ className: "w-full justify-start",
1024
+ variant: "ghost",
1025
+ onPress: () => handleStatusChange("pause"),
1026
+ disabled: isLoading,
1027
+ children: [
1028
+ /* @__PURE__ */ jsxDEV2("span", {
1029
+ className: "mr-2",
1030
+ children: "\u23F8\uFE0F"
1031
+ }, undefined, false, undefined, this),
1032
+ " Pause Agent"
1033
+ ]
1034
+ }, undefined, true, undefined, this),
1035
+ agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxDEV2(Button, {
1036
+ className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
1037
+ variant: "ghost",
1038
+ onPress: () => {
1039
+ setConfirmAction("archive");
1040
+ setMode("confirm");
1041
+ },
1042
+ children: [
1043
+ /* @__PURE__ */ jsxDEV2("span", {
1044
+ className: "mr-2",
1045
+ children: "\uD83D\uDCE6"
1046
+ }, undefined, false, undefined, this),
1047
+ " Archive Agent"
1048
+ ]
1049
+ }, undefined, true, undefined, this),
1050
+ agent.status === "ARCHIVED" && /* @__PURE__ */ jsxDEV2(Button, {
1051
+ className: "w-full justify-start",
1052
+ variant: "ghost",
1053
+ onPress: () => handleStatusChange("activate"),
1054
+ disabled: isLoading,
1055
+ children: [
1056
+ /* @__PURE__ */ jsxDEV2("span", {
1057
+ className: "mr-2",
1058
+ children: "\uD83D\uDD04"
1059
+ }, undefined, false, undefined, this),
1060
+ " Restore Agent"
1061
+ ]
1062
+ }, undefined, true, undefined, this),
1063
+ error && /* @__PURE__ */ jsxDEV2("div", {
1064
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
1065
+ children: error
1066
+ }, undefined, false, undefined, this),
1067
+ /* @__PURE__ */ jsxDEV2("div", {
1068
+ className: "border-border border-t pt-3",
1069
+ children: /* @__PURE__ */ jsxDEV2(Button, {
1070
+ className: "w-full",
1071
+ variant: "outline",
1072
+ onPress: handleClose,
1073
+ children: "Close"
1074
+ }, undefined, false, undefined, this)
1075
+ }, undefined, false, undefined, this)
1076
+ ]
1077
+ }, undefined, true, undefined, this),
1078
+ mode === "execute" && /* @__PURE__ */ jsxDEV2("div", {
1079
+ className: "space-y-4",
1080
+ children: [
1081
+ /* @__PURE__ */ jsxDEV2("div", {
1082
+ children: [
1083
+ /* @__PURE__ */ jsxDEV2("label", {
1084
+ htmlFor: "execute-message",
1085
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
1086
+ children: "Message *"
1087
+ }, undefined, false, undefined, this),
1088
+ /* @__PURE__ */ jsxDEV2("textarea", {
1089
+ id: "execute-message",
1090
+ value: message,
1091
+ onChange: (e) => setMessage(e.target.value),
1092
+ placeholder: "Enter your message to the agent...",
1093
+ rows: 4,
1094
+ disabled: isLoading,
1095
+ 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"
1096
+ }, undefined, false, undefined, this)
1097
+ ]
1098
+ }, undefined, true, undefined, this),
1099
+ error && /* @__PURE__ */ jsxDEV2("div", {
1100
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
1101
+ children: error
1102
+ }, undefined, false, undefined, this),
1103
+ /* @__PURE__ */ jsxDEV2("div", {
1104
+ className: "flex justify-end gap-3 pt-2",
1105
+ children: [
1106
+ /* @__PURE__ */ jsxDEV2(Button, {
1107
+ variant: "ghost",
1108
+ onPress: () => setMode("menu"),
1109
+ disabled: isLoading,
1110
+ children: "Back"
1111
+ }, undefined, false, undefined, this),
1112
+ /* @__PURE__ */ jsxDEV2(Button, {
1113
+ onPress: handleExecute,
1114
+ disabled: isLoading,
1115
+ children: isLoading ? "Executing..." : "\u25B6\uFE0F Execute"
1116
+ }, undefined, false, undefined, this)
1117
+ ]
1118
+ }, undefined, true, undefined, this)
1119
+ ]
1120
+ }, undefined, true, undefined, this),
1121
+ mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxDEV2("div", {
1122
+ className: "space-y-4",
1123
+ children: [
1124
+ /* @__PURE__ */ jsxDEV2("p", {
1125
+ className: "text-muted-foreground",
1126
+ children: [
1127
+ "Are you sure you want to archive",
1128
+ " ",
1129
+ /* @__PURE__ */ jsxDEV2("span", {
1130
+ className: "font-medium text-foreground",
1131
+ children: agent.name
1132
+ }, undefined, false, undefined, this),
1133
+ "?"
1134
+ ]
1135
+ }, undefined, true, undefined, this),
1136
+ /* @__PURE__ */ jsxDEV2("p", {
1137
+ className: "text-muted-foreground text-sm",
1138
+ children: "Archived agents cannot be executed but can be restored later."
1139
+ }, undefined, false, undefined, this),
1140
+ error && /* @__PURE__ */ jsxDEV2("div", {
1141
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
1142
+ children: error
1143
+ }, undefined, false, undefined, this),
1144
+ /* @__PURE__ */ jsxDEV2("div", {
1145
+ className: "flex justify-end gap-3 pt-2",
1146
+ children: [
1147
+ /* @__PURE__ */ jsxDEV2(Button, {
1148
+ variant: "ghost",
1149
+ onPress: () => setMode("menu"),
1150
+ disabled: isLoading,
1151
+ children: "Cancel"
1152
+ }, undefined, false, undefined, this),
1153
+ /* @__PURE__ */ jsxDEV2(Button, {
1154
+ onPress: () => handleStatusChange("archive"),
1155
+ disabled: isLoading,
1156
+ children: isLoading ? "Archiving..." : "\uD83D\uDCE6 Archive"
1157
+ }, undefined, false, undefined, this)
1158
+ ]
1159
+ }, undefined, true, undefined, this)
1160
+ ]
1161
+ }, undefined, true, undefined, this)
1162
+ ]
1163
+ }, undefined, true, undefined, this)
1164
+ ]
1165
+ }, undefined, true, undefined, this);
1166
+ }
1167
+
1168
+ // src/ui/modals/CreateAgentModal.tsx
1169
+ import { Button as Button2, Input } from "@contractspec/lib.design-system";
1170
+ import { useState as useState5 } from "react";
1171
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
1172
+ "use client";
1173
+ var MODEL_PROVIDERS = [
1174
+ {
1175
+ value: "openai",
1176
+ label: "OpenAI",
1177
+ models: ["gpt-5.4", "gpt-5-mini", "gpt-4o", "gpt-4-turbo", "gpt-3.5-turbo"]
1178
+ },
1179
+ {
1180
+ value: "anthropic",
1181
+ label: "Anthropic",
1182
+ models: ["claude-sonnet-4-6", "claude-opus-4-6", "claude-haiku-4-5"]
1183
+ },
1184
+ {
1185
+ value: "google",
1186
+ label: "Google",
1187
+ models: [
1188
+ "gemini-2.5-flash",
1189
+ "gemini-2.5-pro",
1190
+ "gemini-pro",
1191
+ "gemini-ultra"
1192
+ ]
1193
+ },
1194
+ {
1195
+ value: "mistral",
1196
+ label: "Mistral",
1197
+ models: [
1198
+ "mistral-large-2512",
1199
+ "mistral-large-latest",
1200
+ "mistral-medium-latest",
1201
+ "mistral-small-latest"
1202
+ ]
1203
+ }
1204
+ ];
1205
+ function CreateAgentModal({
1206
+ isOpen,
1207
+ onClose,
1208
+ onSubmit,
1209
+ isLoading = false
1210
+ }) {
1211
+ const [name, setName] = useState5("");
1212
+ const [description, setDescription] = useState5("");
1213
+ const [modelProvider, setModelProvider] = useState5("openai");
1214
+ const [modelName, setModelName] = useState5("gpt-5.4");
1215
+ const [systemPrompt, setSystemPrompt] = useState5("");
1216
+ const [error, setError] = useState5(null);
1217
+ const selectedProvider = MODEL_PROVIDERS.find((p) => p.value === modelProvider);
1218
+ const handleSubmit = async (e) => {
1219
+ e.preventDefault();
1220
+ setError(null);
1221
+ if (!name.trim()) {
1222
+ setError("Agent name is required");
1223
+ return;
1224
+ }
1225
+ try {
1226
+ await onSubmit({
1227
+ name: name.trim(),
1228
+ description: description.trim() || undefined,
1229
+ modelProvider,
1230
+ modelName,
1231
+ systemPrompt: systemPrompt.trim() || undefined
1232
+ });
1233
+ setName("");
1234
+ setDescription("");
1235
+ setModelProvider("openai");
1236
+ setModelName("gpt-5.4");
1237
+ setSystemPrompt("");
1238
+ onClose();
1239
+ } catch (err) {
1240
+ setError(err instanceof Error ? err.message : "Failed to create agent");
1241
+ }
1242
+ };
1243
+ const handleProviderChange = (provider) => {
1244
+ setModelProvider(provider);
1245
+ const providerConfig = MODEL_PROVIDERS.find((p) => p.value === provider);
1246
+ if (providerConfig) {
1247
+ setModelName(providerConfig.models[0]);
1248
+ }
1249
+ };
1250
+ if (!isOpen)
1251
+ return null;
1252
+ return /* @__PURE__ */ jsxDEV3("div", {
1253
+ className: "fixed inset-0 z-50 flex items-center justify-center",
1254
+ children: [
1255
+ /* @__PURE__ */ jsxDEV3("div", {
1256
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
1257
+ onClick: onClose,
1258
+ role: "button",
1259
+ tabIndex: 0,
1260
+ onKeyDown: (e) => {
1261
+ if (e.key === "Enter" || e.key === " ")
1262
+ onClose();
1263
+ },
1264
+ "aria-label": "Close modal"
1265
+ }, undefined, false, undefined, this),
1266
+ /* @__PURE__ */ jsxDEV3("div", {
1267
+ 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",
1268
+ children: [
1269
+ /* @__PURE__ */ jsxDEV3("h2", {
1270
+ className: "mb-4 font-semibold text-xl",
1271
+ children: "Create New Agent"
1272
+ }, undefined, false, undefined, this),
1273
+ /* @__PURE__ */ jsxDEV3("form", {
1274
+ onSubmit: handleSubmit,
1275
+ className: "space-y-4",
1276
+ children: [
1277
+ /* @__PURE__ */ jsxDEV3("div", {
1278
+ children: [
1279
+ /* @__PURE__ */ jsxDEV3("label", {
1280
+ htmlFor: "agent-name",
1281
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
1282
+ children: "Agent Name *"
1283
+ }, undefined, false, undefined, this),
1284
+ /* @__PURE__ */ jsxDEV3(Input, {
1285
+ id: "agent-name",
1286
+ value: name,
1287
+ onChange: (e) => setName(e.target.value),
1288
+ placeholder: "e.g., Customer Support Bot",
1289
+ disabled: isLoading
1290
+ }, undefined, false, undefined, this)
1291
+ ]
1292
+ }, undefined, true, undefined, this),
1293
+ /* @__PURE__ */ jsxDEV3("div", {
1294
+ children: [
1295
+ /* @__PURE__ */ jsxDEV3("label", {
1296
+ htmlFor: "agent-description",
1297
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
1298
+ children: "Description"
1299
+ }, undefined, false, undefined, this),
1300
+ /* @__PURE__ */ jsxDEV3("textarea", {
1301
+ id: "agent-description",
1302
+ value: description,
1303
+ onChange: (e) => setDescription(e.target.value),
1304
+ placeholder: "Describe what this agent does...",
1305
+ rows: 2,
1306
+ disabled: isLoading,
1307
+ 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"
1308
+ }, undefined, false, undefined, this)
1309
+ ]
1310
+ }, undefined, true, undefined, this),
1311
+ /* @__PURE__ */ jsxDEV3("div", {
1312
+ className: "flex gap-3",
1313
+ children: [
1314
+ /* @__PURE__ */ jsxDEV3("div", {
1315
+ className: "flex-1",
1316
+ children: [
1317
+ /* @__PURE__ */ jsxDEV3("label", {
1318
+ htmlFor: "model-provider",
1319
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
1320
+ children: "Provider *"
1321
+ }, undefined, false, undefined, this),
1322
+ /* @__PURE__ */ jsxDEV3("select", {
1323
+ id: "model-provider",
1324
+ value: modelProvider,
1325
+ onChange: (e) => handleProviderChange(e.target.value),
1326
+ disabled: isLoading,
1327
+ 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",
1328
+ children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsxDEV3("option", {
1329
+ value: p.value,
1330
+ children: p.label
1331
+ }, p.value, false, undefined, this))
1332
+ }, undefined, false, undefined, this)
1333
+ ]
1334
+ }, undefined, true, undefined, this),
1335
+ /* @__PURE__ */ jsxDEV3("div", {
1336
+ className: "flex-1",
1337
+ children: [
1338
+ /* @__PURE__ */ jsxDEV3("label", {
1339
+ htmlFor: "model-name",
1340
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
1341
+ children: "Model *"
1342
+ }, undefined, false, undefined, this),
1343
+ /* @__PURE__ */ jsxDEV3("select", {
1344
+ id: "model-name",
1345
+ value: modelName,
1346
+ onChange: (e) => setModelName(e.target.value),
1347
+ disabled: isLoading,
1348
+ 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",
1349
+ children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsxDEV3("option", {
1350
+ value: m,
1351
+ children: m
1352
+ }, m, false, undefined, this))
1353
+ }, undefined, false, undefined, this)
1354
+ ]
1355
+ }, undefined, true, undefined, this)
1356
+ ]
1357
+ }, undefined, true, undefined, this),
1358
+ /* @__PURE__ */ jsxDEV3("div", {
1359
+ children: [
1360
+ /* @__PURE__ */ jsxDEV3("label", {
1361
+ htmlFor: "system-prompt",
1362
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
1363
+ children: "System Prompt"
1364
+ }, undefined, false, undefined, this),
1365
+ /* @__PURE__ */ jsxDEV3("textarea", {
1366
+ id: "system-prompt",
1367
+ value: systemPrompt,
1368
+ onChange: (e) => setSystemPrompt(e.target.value),
1369
+ placeholder: "You are a helpful assistant that...",
1370
+ rows: 4,
1371
+ disabled: isLoading,
1372
+ 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"
1373
+ }, undefined, false, undefined, this),
1374
+ /* @__PURE__ */ jsxDEV3("p", {
1375
+ className: "mt-1 text-muted-foreground text-xs",
1376
+ children: "Instructions that define the agent's behavior"
1377
+ }, undefined, false, undefined, this)
1378
+ ]
1379
+ }, undefined, true, undefined, this),
1380
+ error && /* @__PURE__ */ jsxDEV3("div", {
1381
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
1382
+ children: error
1383
+ }, undefined, false, undefined, this),
1384
+ /* @__PURE__ */ jsxDEV3("div", {
1385
+ className: "flex justify-end gap-3 pt-2",
1386
+ children: [
1387
+ /* @__PURE__ */ jsxDEV3(Button2, {
1388
+ type: "button",
1389
+ variant: "ghost",
1390
+ onPress: onClose,
1391
+ disabled: isLoading,
1392
+ children: "Cancel"
1393
+ }, undefined, false, undefined, this),
1394
+ /* @__PURE__ */ jsxDEV3(Button2, {
1395
+ type: "submit",
1396
+ disabled: isLoading,
1397
+ children: isLoading ? "Creating..." : "Create Agent"
1398
+ }, undefined, false, undefined, this)
1399
+ ]
1400
+ }, undefined, true, undefined, this)
1401
+ ]
1402
+ }, undefined, true, undefined, this)
1403
+ ]
1404
+ }, undefined, true, undefined, this)
1405
+ ]
1406
+ }, undefined, true, undefined, this);
1407
+ }
1408
+
1409
+ // src/ui/views/run-list.shared.tsx
1410
+ import { Button as Button3, StatusChip } from "@contractspec/lib.design-system";
1411
+ import { HStack, VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
1412
+ import { Text } from "@contractspec/lib.ui-kit-web/ui/text";
1413
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
1414
+ "use client";
1415
+ function getStatusTone(status) {
1416
+ switch (status) {
1417
+ case "COMPLETED":
1418
+ return "success";
1419
+ case "RUNNING":
1420
+ return "warning";
1421
+ case "QUEUED":
1422
+ return "neutral";
1423
+ case "FAILED":
1424
+ case "CANCELLED":
1425
+ return "danger";
1426
+ default:
1427
+ return "neutral";
1428
+ }
1429
+ }
1430
+ function formatDuration(ms) {
1431
+ if (!ms)
1432
+ return "-";
1433
+ if (ms < 1000)
1434
+ return `${ms}ms`;
1435
+ if (ms < 60000)
1436
+ return `${(ms / 1000).toFixed(1)}s`;
1437
+ return `${(ms / 60000).toFixed(1)}m`;
1438
+ }
1439
+ function formatTokens(tokens) {
1440
+ if (tokens < 1000)
1441
+ return tokens.toString();
1442
+ if (tokens < 1e6)
1443
+ return `${(tokens / 1000).toFixed(1)}K`;
1444
+ return `${(tokens / 1e6).toFixed(2)}M`;
1445
+ }
1446
+ function formatCost(cost) {
1447
+ if (!cost)
1448
+ return "-";
1449
+ return `$${cost.toFixed(4)}`;
1450
+ }
1451
+ function formatJson(value) {
1452
+ return JSON.stringify(value ?? null, null, 2);
1453
+ }
1454
+ function RunExpandedContent({ run }) {
1455
+ return /* @__PURE__ */ jsxDEV4(VStack, {
1456
+ gap: "sm",
1457
+ className: "py-2",
1458
+ children: [
1459
+ /* @__PURE__ */ jsxDEV4(HStack, {
1460
+ justify: "between",
1461
+ className: "flex-wrap",
1462
+ children: [
1463
+ /* @__PURE__ */ jsxDEV4(StatusChip, {
1464
+ tone: getStatusTone(run.status),
1465
+ label: run.status
1466
+ }, undefined, false, undefined, this),
1467
+ /* @__PURE__ */ jsxDEV4(Text, {
1468
+ className: "text-muted-foreground text-sm",
1469
+ children: [
1470
+ "Queued ",
1471
+ run.queuedAt.toLocaleString()
1472
+ ]
1473
+ }, undefined, true, undefined, this)
1474
+ ]
1475
+ }, undefined, true, undefined, this),
1476
+ /* @__PURE__ */ jsxDEV4(HStack, {
1477
+ gap: "lg",
1478
+ className: "flex-wrap",
1479
+ children: [
1480
+ /* @__PURE__ */ jsxDEV4(Text, {
1481
+ className: "text-muted-foreground text-sm",
1482
+ children: [
1483
+ "Prompt ",
1484
+ formatTokens(run.promptTokens)
1485
+ ]
1486
+ }, undefined, true, undefined, this),
1487
+ /* @__PURE__ */ jsxDEV4(Text, {
1488
+ className: "text-muted-foreground text-sm",
1489
+ children: [
1490
+ "Completion ",
1491
+ formatTokens(run.completionTokens)
1492
+ ]
1493
+ }, undefined, true, undefined, this),
1494
+ /* @__PURE__ */ jsxDEV4(Text, {
1495
+ className: "text-muted-foreground text-sm",
1496
+ children: [
1497
+ "Duration ",
1498
+ formatDuration(run.durationMs)
1499
+ ]
1500
+ }, undefined, true, undefined, this)
1501
+ ]
1502
+ }, undefined, true, undefined, this),
1503
+ /* @__PURE__ */ jsxDEV4(VStack, {
1504
+ gap: "xs",
1505
+ children: [
1506
+ /* @__PURE__ */ jsxDEV4(Text, {
1507
+ className: "font-medium text-sm",
1508
+ children: "Input"
1509
+ }, undefined, false, undefined, this),
1510
+ /* @__PURE__ */ jsxDEV4("pre", {
1511
+ className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
1512
+ children: formatJson(run.input)
1513
+ }, undefined, false, undefined, this)
1514
+ ]
1515
+ }, undefined, true, undefined, this),
1516
+ /* @__PURE__ */ jsxDEV4(VStack, {
1517
+ gap: "xs",
1518
+ children: [
1519
+ /* @__PURE__ */ jsxDEV4(Text, {
1520
+ className: "font-medium text-sm",
1521
+ children: "Output"
1522
+ }, undefined, false, undefined, this),
1523
+ /* @__PURE__ */ jsxDEV4("pre", {
1524
+ className: "overflow-auto rounded-md bg-muted/40 p-3 text-xs",
1525
+ children: formatJson(run.output ?? run.errorMessage ?? "Pending")
1526
+ }, undefined, false, undefined, this)
1527
+ ]
1528
+ }, undefined, true, undefined, this)
1529
+ ]
1530
+ }, undefined, true, undefined, this);
1531
+ }
1532
+ function RunTableToolbar({
1533
+ controller,
1534
+ totalRuns
1535
+ }) {
1536
+ const firstRow = controller.rows[0];
1537
+ const queuedColumn = controller.columns.find((column) => column.id === "queuedAt");
1538
+ const durationColumn = controller.columns.find((column) => column.id === "durationMs");
1539
+ const costColumn = controller.columns.find((column) => column.id === "estimatedCostUsd");
1540
+ return /* @__PURE__ */ jsxDEV4(HStack, {
1541
+ gap: "sm",
1542
+ className: "flex-wrap",
1543
+ children: [
1544
+ /* @__PURE__ */ jsxDEV4(Text, {
1545
+ className: "text-muted-foreground text-sm",
1546
+ children: [
1547
+ totalRuns,
1548
+ " runs"
1549
+ ]
1550
+ }, undefined, true, undefined, this),
1551
+ /* @__PURE__ */ jsxDEV4(Button3, {
1552
+ variant: "outline",
1553
+ size: "sm",
1554
+ onPress: () => firstRow?.toggleExpanded?.(!firstRow?.isExpanded),
1555
+ children: "Expand Latest Run"
1556
+ }, undefined, false, undefined, this),
1557
+ /* @__PURE__ */ jsxDEV4(Button3, {
1558
+ variant: "outline",
1559
+ size: "sm",
1560
+ onPress: () => queuedColumn?.toggleVisibility?.(!queuedColumn?.visible),
1561
+ children: queuedColumn?.visible ? "Hide Time" : "Show Time"
1562
+ }, undefined, false, undefined, this),
1563
+ /* @__PURE__ */ jsxDEV4(Button3, {
1564
+ variant: "outline",
1565
+ size: "sm",
1566
+ onPress: () => durationColumn?.toggleVisibility?.(!durationColumn?.visible),
1567
+ children: durationColumn?.visible ? "Hide Duration" : "Show Duration"
1568
+ }, undefined, false, undefined, this),
1569
+ /* @__PURE__ */ jsxDEV4(Button3, {
1570
+ variant: "outline",
1571
+ size: "sm",
1572
+ onPress: () => costColumn?.toggleVisibility?.(!costColumn?.visible),
1573
+ children: costColumn?.visible ? "Hide Cost" : "Show Cost"
1574
+ }, undefined, false, undefined, this)
1575
+ ]
1576
+ }, undefined, true, undefined, this);
1577
+ }
1578
+
1579
+ // src/ui/views/run-data-table.columns.tsx
1580
+ import { StatusChip as StatusChip2 } from "@contractspec/lib.design-system";
1581
+ import { VStack as VStack2 } from "@contractspec/lib.ui-kit-web/ui/stack";
1582
+ import { Text as Text2 } from "@contractspec/lib.ui-kit-web/ui/text";
1583
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1584
+ "use client";
1585
+ function createRunTableColumns() {
1586
+ return [
1587
+ {
1588
+ id: "queuedAt",
1589
+ header: "Run",
1590
+ label: "Run",
1591
+ accessor: (run) => run.queuedAt.getTime(),
1592
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV5(VStack2, {
1593
+ gap: "xs",
1594
+ children: [
1595
+ /* @__PURE__ */ jsxDEV5(Text2, {
1596
+ className: "font-mono text-sm",
1597
+ children: item.id.slice(-8)
1598
+ }, undefined, false, undefined, this),
1599
+ /* @__PURE__ */ jsxDEV5(Text2, {
1600
+ className: "text-muted-foreground text-xs",
1601
+ children: item.queuedAt.toLocaleString()
1602
+ }, undefined, false, undefined, this)
1603
+ ]
1604
+ }, undefined, true, undefined, this),
1605
+ size: 220,
1606
+ minSize: 180,
1607
+ canSort: true,
1608
+ canHide: true,
1609
+ canResize: true
1610
+ },
1611
+ {
1612
+ id: "agentName",
1613
+ header: "Agent",
1614
+ label: "Agent",
1615
+ accessor: (run) => run.agentName ?? "Unknown Agent",
1616
+ cell: ({ value }) => /* @__PURE__ */ jsxDEV5(Text2, {
1617
+ className: "font-medium",
1618
+ children: typeof value === "string" ? value : "Unknown Agent"
1619
+ }, undefined, false, undefined, this),
1620
+ size: 220,
1621
+ canSort: true,
1622
+ canResize: true
1623
+ },
1624
+ {
1625
+ id: "status",
1626
+ header: "Status",
1627
+ label: "Status",
1628
+ accessorKey: "status",
1629
+ cell: ({ value }) => {
1630
+ const status = typeof value === "string" ? value : "QUEUED";
1631
+ return /* @__PURE__ */ jsxDEV5(StatusChip2, {
1632
+ tone: getStatusTone(status),
1633
+ label: status
1634
+ }, undefined, false, undefined, this);
1635
+ },
1636
+ size: 150,
1637
+ canSort: true,
1638
+ canResize: true
1639
+ },
1640
+ {
1641
+ id: "totalTokens",
1642
+ header: "Tokens",
1643
+ label: "Tokens",
1644
+ accessorKey: "totalTokens",
1645
+ cell: ({ value }) => formatTokens(Number(value ?? 0)),
1646
+ align: "right",
1647
+ size: 140,
1648
+ canSort: true,
1649
+ canResize: true
1650
+ },
1651
+ {
1652
+ id: "durationMs",
1653
+ header: "Duration",
1654
+ label: "Duration",
1655
+ accessorKey: "durationMs",
1656
+ cell: ({ value }) => formatDuration(typeof value === "number" ? value : undefined),
1657
+ align: "right",
1658
+ size: 140,
1659
+ canSort: true,
1660
+ canHide: true,
1661
+ canResize: true
1662
+ },
1663
+ {
1664
+ id: "estimatedCostUsd",
1665
+ header: "Cost",
1666
+ label: "Cost",
1667
+ accessorKey: "estimatedCostUsd",
1668
+ cell: ({ value }) => formatCost(typeof value === "number" ? value : undefined),
1669
+ align: "right",
1670
+ size: 140,
1671
+ canSort: true,
1672
+ canHide: true,
1673
+ canResize: true
1674
+ }
1675
+ ];
1676
+ }
1677
+
1678
+ // src/ui/views/RunDataTable.tsx
1679
+ import { DataTable } from "@contractspec/lib.design-system";
1680
+ import { useContractTable } from "@contractspec/lib.presentation-runtime-react";
1681
+ import * as React from "react";
1682
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
1683
+ "use client";
1684
+ function RunDataTable({
1685
+ runs,
1686
+ totalItems,
1687
+ pageIndex,
1688
+ pageSize,
1689
+ sorting,
1690
+ loading,
1691
+ onSortingChange,
1692
+ onPaginationChange,
1693
+ onRunClick
1694
+ }) {
1695
+ const columns = React.useMemo(() => createRunTableColumns(), []);
1696
+ const controller = useContractTable({
1697
+ data: runs,
1698
+ columns,
1699
+ executionMode: "server",
1700
+ totalItems,
1701
+ state: {
1702
+ sorting,
1703
+ pagination: { pageIndex, pageSize }
1704
+ },
1705
+ onSortingChange,
1706
+ onPaginationChange,
1707
+ initialState: {
1708
+ columnVisibility: { estimatedCostUsd: false }
1709
+ },
1710
+ getRowId: (run) => run.id,
1711
+ renderExpandedContent: (run) => /* @__PURE__ */ jsxDEV6(RunExpandedContent, {
1712
+ run
1713
+ }, undefined, false, undefined, this),
1714
+ getCanExpand: () => true
1715
+ });
1716
+ return /* @__PURE__ */ jsxDEV6(DataTable, {
1717
+ controller,
1718
+ title: "Run History",
1719
+ description: "Server-mode ContractSpec table with shared pagination, sorting, visibility, and expansion.",
1720
+ loading,
1721
+ onRowPress: (row) => onRunClick?.(row.id),
1722
+ toolbar: /* @__PURE__ */ jsxDEV6(RunTableToolbar, {
1723
+ controller,
1724
+ totalRuns: totalItems
1725
+ }, undefined, false, undefined, this),
1726
+ emptyState: /* @__PURE__ */ jsxDEV6("div", {
1727
+ className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
1728
+ children: "No runs yet"
1729
+ }, undefined, false, undefined, this)
1730
+ }, undefined, false, undefined, this);
1731
+ }
1732
+
1733
+ // src/ui/views/RunListView.tsx
1734
+ import {
1735
+ EmptyState,
1736
+ ErrorState,
1737
+ LoaderBlock,
1738
+ StatCard,
1739
+ StatCardGroup
1740
+ } from "@contractspec/lib.design-system";
1741
+ import { useState as useState6 } from "react";
1742
+ import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
1743
+ "use client";
1744
+ function RunListView({ agentId, onRunClick }) {
1745
+ const [sorting, setSorting] = useState6([
1746
+ { id: "queuedAt", desc: true }
1747
+ ]);
1748
+ const [pagination, setPagination] = useState6({
1749
+ pageIndex: 0,
1750
+ pageSize: 3
1751
+ });
1752
+ const { data, metrics, loading, error, refetch } = useRunList({
1753
+ agentId,
1754
+ pageIndex: pagination.pageIndex,
1755
+ pageSize: pagination.pageSize,
1756
+ sorting
1757
+ });
1758
+ if (loading && !data) {
1759
+ return /* @__PURE__ */ jsxDEV7(LoaderBlock, {
1760
+ label: "Loading runs..."
1761
+ }, undefined, false, undefined, this);
1762
+ }
1763
+ if (error) {
1764
+ return /* @__PURE__ */ jsxDEV7(ErrorState, {
1765
+ title: "Failed to load runs",
1766
+ description: error.message,
1767
+ onRetry: refetch,
1768
+ retryLabel: "Retry"
1769
+ }, undefined, false, undefined, this);
1770
+ }
1771
+ if (!data?.items.length) {
1772
+ return /* @__PURE__ */ jsxDEV7(EmptyState, {
1773
+ title: "No runs yet",
1774
+ description: "Execute an agent to see run history here."
1775
+ }, undefined, false, undefined, this);
1776
+ }
1777
+ return /* @__PURE__ */ jsxDEV7("div", {
1778
+ className: "space-y-6",
1779
+ children: [
1780
+ metrics ? /* @__PURE__ */ jsxDEV7(StatCardGroup, {
1781
+ children: [
1782
+ /* @__PURE__ */ jsxDEV7(StatCard, {
1783
+ label: "Total Runs",
1784
+ value: metrics.totalRuns
1785
+ }, undefined, false, undefined, this),
1786
+ /* @__PURE__ */ jsxDEV7(StatCard, {
1787
+ label: "Success Rate",
1788
+ value: `${(metrics.successRate * 100).toFixed(1)}%`
1789
+ }, undefined, false, undefined, this),
1790
+ /* @__PURE__ */ jsxDEV7(StatCard, {
1791
+ label: "Total Tokens",
1792
+ value: formatTokens(metrics.totalTokens)
1793
+ }, undefined, false, undefined, this),
1794
+ /* @__PURE__ */ jsxDEV7(StatCard, {
1795
+ label: "Total Cost",
1796
+ value: `$${metrics.totalCostUsd.toFixed(2)}`
1797
+ }, undefined, false, undefined, this)
1798
+ ]
1799
+ }, undefined, true, undefined, this) : null,
1800
+ /* @__PURE__ */ jsxDEV7(RunDataTable, {
1801
+ runs: data.items,
1802
+ totalItems: data.total,
1803
+ pageIndex: pagination.pageIndex,
1804
+ pageSize: pagination.pageSize,
1805
+ sorting,
1806
+ loading,
1807
+ onSortingChange: (nextSorting) => {
1808
+ setSorting(nextSorting);
1809
+ setPagination((current) => ({ ...current, pageIndex: 0 }));
1810
+ },
1811
+ onPaginationChange: setPagination,
1812
+ onRunClick
1813
+ }, undefined, false, undefined, this)
1814
+ ]
1815
+ }, undefined, true, undefined, this);
1816
+ }
1817
+
1818
+ // src/ui/hooks/useToolList.ts
1819
+ import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
1820
+ import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo3, useState as useState7 } from "react";
1821
+ function useToolList(options = {}) {
1822
+ const { handlers, projectId } = useTemplateRuntime4();
1823
+ const { agent } = handlers;
1824
+ const [data, setData] = useState7(null);
1825
+ const [loading, setLoading] = useState7(true);
1826
+ const [error, setError] = useState7(null);
1827
+ const [page, setPage] = useState7(1);
1828
+ const fetchData = useCallback4(async () => {
1829
+ setLoading(true);
1830
+ setError(null);
1831
+ try {
1832
+ const result = await agent.listTools({
1833
+ projectId,
1834
+ search: options.search,
1835
+ category: options.category,
1836
+ status: options.status === "all" ? undefined : options.status,
1837
+ limit: options.limit ?? 50,
1838
+ offset: (page - 1) * (options.limit ?? 50)
1839
+ });
1840
+ setData(result);
1841
+ } catch (err) {
1842
+ setError(err instanceof Error ? err : new Error("Unknown error"));
1843
+ } finally {
1844
+ setLoading(false);
1845
+ }
1846
+ }, [
1847
+ agent,
1848
+ projectId,
1849
+ options.search,
1850
+ options.category,
1851
+ options.status,
1852
+ options.limit,
1853
+ page
1854
+ ]);
1855
+ useEffect3(() => {
1856
+ fetchData();
1857
+ }, [fetchData]);
1858
+ const { stats, groupedByCategory, categoryStats } = useMemo3(() => {
1859
+ if (!data)
1860
+ return { stats: null, groupedByCategory: {}, categoryStats: [] };
1861
+ const items = data.items;
1862
+ const active = items.filter((t) => t.status === "ACTIVE").length;
1863
+ const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
1864
+ const disabled = items.filter((t) => t.status === "DISABLED").length;
1865
+ const grouped = {};
1866
+ const byCategory = {};
1867
+ items.forEach((t) => {
1868
+ const cat = t.category;
1869
+ if (!grouped[cat])
1870
+ grouped[cat] = [];
1871
+ grouped[cat].push(t);
1872
+ byCategory[cat] = (byCategory[cat] || 0) + 1;
1873
+ });
1874
+ const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
1875
+ return {
1876
+ stats: {
1877
+ total: data.total,
1878
+ active,
1879
+ deprecated,
1880
+ disabled,
1881
+ topCategories: catStats.slice(0, 5)
1882
+ },
1883
+ groupedByCategory: grouped,
1884
+ categoryStats: catStats
1885
+ };
1886
+ }, [data]);
1887
+ return {
1888
+ data,
1889
+ loading,
1890
+ error,
1891
+ stats,
1892
+ groupedByCategory,
1893
+ categoryStats,
1894
+ page,
1895
+ refetch: fetchData,
1896
+ nextPage: () => setPage((p) => p + 1),
1897
+ prevPage: () => page > 1 && setPage((p) => p - 1)
1898
+ };
1899
+ }
1900
+
1901
+ // src/ui/views/ToolRegistryView.tsx
1902
+ import {
1903
+ Button as Button4,
1904
+ EmptyState as EmptyState2,
1905
+ EntityCard,
1906
+ ErrorState as ErrorState2,
1907
+ LoaderBlock as LoaderBlock2,
1908
+ StatCard as StatCard2,
1909
+ StatCardGroup as StatCardGroup2,
1910
+ StatusChip as StatusChip3
1911
+ } from "@contractspec/lib.design-system";
1912
+ import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
1913
+ "use client";
1914
+ var categoryIcons = {
1915
+ RETRIEVAL: "\uD83D\uDD0D",
1916
+ COMPUTATION: "\uD83E\uDDEE",
1917
+ COMMUNICATION: "\uD83D\uDCE7",
1918
+ INTEGRATION: "\uD83D\uDD17",
1919
+ UTILITY: "\uD83D\uDEE0\uFE0F",
1920
+ CUSTOM: "\u2699\uFE0F"
1921
+ };
1922
+ function getStatusTone2(status) {
1923
+ switch (status) {
1924
+ case "ACTIVE":
1925
+ return "success";
1926
+ case "DRAFT":
1927
+ return "neutral";
1928
+ case "DEPRECATED":
1929
+ return "warning";
1930
+ case "DISABLED":
1931
+ return "danger";
1932
+ default:
1933
+ return "neutral";
1934
+ }
1935
+ }
1936
+ function ToolRegistryView({
1937
+ onToolClick,
1938
+ onCreateTool
1939
+ }) {
1940
+ const { data, loading, error, groupedByCategory, categoryStats, refetch } = useToolList();
1941
+ if (loading && !data) {
1942
+ return /* @__PURE__ */ jsxDEV8(LoaderBlock2, {
1943
+ label: "Loading tools..."
1944
+ }, undefined, false, undefined, this);
1945
+ }
1946
+ if (error) {
1947
+ return /* @__PURE__ */ jsxDEV8(ErrorState2, {
1948
+ title: "Failed to load tools",
1949
+ description: error.message,
1950
+ onRetry: refetch,
1951
+ retryLabel: "Retry"
1952
+ }, undefined, false, undefined, this);
1953
+ }
1954
+ if (!data?.items.length) {
1955
+ return /* @__PURE__ */ jsxDEV8(EmptyState2, {
1956
+ title: "No tools registered",
1957
+ description: "Create your first tool to extend agent capabilities.",
1958
+ primaryAction: onCreateTool ? /* @__PURE__ */ jsxDEV8(Button4, {
1959
+ onPress: onCreateTool,
1960
+ children: "Create Tool"
1961
+ }, undefined, false, undefined, this) : undefined
1962
+ }, undefined, false, undefined, this);
1963
+ }
1964
+ return /* @__PURE__ */ jsxDEV8("div", {
1965
+ className: "space-y-8",
1966
+ children: [
1967
+ /* @__PURE__ */ jsxDEV8(StatCardGroup2, {
1968
+ children: [
1969
+ /* @__PURE__ */ jsxDEV8(StatCard2, {
1970
+ label: "Total Tools",
1971
+ value: data.total
1972
+ }, undefined, false, undefined, this),
1973
+ categoryStats.slice(0, 3).map(({ category, count }) => /* @__PURE__ */ jsxDEV8(StatCard2, {
1974
+ label: `${categoryIcons[category] ?? ""} ${category}`,
1975
+ value: count
1976
+ }, category, false, undefined, this))
1977
+ ]
1978
+ }, undefined, true, undefined, this),
1979
+ Object.entries(groupedByCategory).map(([category, tools]) => /* @__PURE__ */ jsxDEV8("section", {
1980
+ className: "space-y-4",
1981
+ children: [
1982
+ /* @__PURE__ */ jsxDEV8("div", {
1983
+ className: "flex items-center gap-2",
1984
+ children: [
1985
+ /* @__PURE__ */ jsxDEV8("span", {
1986
+ className: "text-2xl",
1987
+ children: categoryIcons[category]
1041
1988
  }, undefined, false, undefined, this),
1042
- /* @__PURE__ */ jsxDEV4("div", {
1043
- className: "border-border border-t pt-3",
1044
- children: /* @__PURE__ */ jsxDEV4(Button3, {
1045
- className: "w-full",
1046
- variant: "outline",
1047
- onPress: handleClose,
1048
- children: "Close"
1049
- }, undefined, false, undefined, this)
1050
- }, undefined, false, undefined, this)
1051
- ]
1052
- }, undefined, true, undefined, this),
1053
- mode === "execute" && /* @__PURE__ */ jsxDEV4("div", {
1054
- className: "space-y-4",
1055
- children: [
1056
- /* @__PURE__ */ jsxDEV4("div", {
1057
- children: [
1058
- /* @__PURE__ */ jsxDEV4("label", {
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
1989
+ /* @__PURE__ */ jsxDEV8("h3", {
1990
+ className: "font-semibold text-lg",
1991
+ children: category
1077
1992
  }, 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)
1993
+ /* @__PURE__ */ jsxDEV8("span", {
1994
+ className: "rounded-full bg-muted px-2 py-0.5 text-muted-foreground text-xs",
1995
+ children: tools.length
1996
+ }, undefined, false, undefined, this)
1094
1997
  ]
1095
1998
  }, 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", {
1999
+ /* @__PURE__ */ jsxDEV8("div", {
2000
+ className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
2001
+ children: tools.map((tool) => /* @__PURE__ */ jsxDEV8(EntityCard, {
2002
+ cardTitle: tool.name,
2003
+ cardSubtitle: `v${tool.version}`,
2004
+ meta: /* @__PURE__ */ jsxDEV8("p", {
1112
2005
  className: "text-muted-foreground text-sm",
1113
- children: "Archived agents cannot be executed but can be restored later."
2006
+ children: tool.description
1114
2007
  }, undefined, false, undefined, this),
1115
- error && /* @__PURE__ */ jsxDEV4("div", {
1116
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
1117
- children: error
2008
+ chips: /* @__PURE__ */ jsxDEV8(StatusChip3, {
2009
+ tone: getStatusTone2(tool.status),
2010
+ label: tool.status
1118
2011
  }, undefined, false, undefined, this),
1119
- /* @__PURE__ */ jsxDEV4("div", {
1120
- className: "flex justify-end gap-3 pt-2",
1121
- children: [
1122
- /* @__PURE__ */ jsxDEV4(Button3, {
1123
- variant: "ghost",
1124
- onPress: () => setMode("menu"),
1125
- disabled: isLoading,
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)
2012
+ footer: /* @__PURE__ */ jsxDEV8("code", {
2013
+ className: "text-muted-foreground text-xs",
2014
+ children: tool.name
2015
+ }, undefined, false, undefined, this),
2016
+ onClick: onToolClick ? () => onToolClick(tool.id) : undefined
2017
+ }, tool.id, false, undefined, this))
2018
+ }, undefined, false, undefined, this)
1137
2019
  ]
1138
- }, undefined, true, undefined, this)
2020
+ }, category, true, undefined, this))
1139
2021
  ]
1140
2022
  }, undefined, true, undefined, this);
1141
2023
  }
1142
2024
 
1143
2025
  // src/ui/AgentDashboard.tsx
1144
- import { useState as useState7, useMemo as useMemo3, useCallback as useCallback5 } from "react";
1145
2026
  import {
2027
+ Button as Button5,
1146
2028
  StatCard as StatCard3,
1147
- StatCardGroup as StatCardGroup3,
1148
- Button as Button4
2029
+ StatCardGroup as StatCardGroup3
1149
2030
  } from "@contractspec/lib.design-system";
1150
- import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
2031
+ import { useCallback as useCallback5, useMemo as useMemo4, useState as useState8 } from "react";
2032
+ import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
1151
2033
  "use client";
1152
2034
  function AgentDashboard() {
1153
- const [activeTab, setActiveTab] = useState7("runs");
1154
- const [isCreateModalOpen, setIsCreateModalOpen] = useState7(false);
1155
- const [selectedAgent, setSelectedAgent] = useState7(null);
1156
- const [isAgentActionsOpen, setIsAgentActionsOpen] = useState7(false);
1157
- const { metrics, refetch: refetchRuns } = useRunList();
2035
+ const [activeTab, setActiveTab] = useState8("runs");
2036
+ const [isCreateModalOpen, setIsCreateModalOpen] = useState8(false);
2037
+ const [selectedAgent, setSelectedAgent] = useState8(null);
2038
+ const [isAgentActionsOpen, setIsAgentActionsOpen] = useState8(false);
2039
+ const { data: runData, metrics, refetch: refetchRuns } = useRunList();
1158
2040
  const { refetch: refetchAgents } = useAgentList();
1159
2041
  const mutations = useAgentMutations({
1160
2042
  onSuccess: () => {
@@ -1172,7 +2054,7 @@ function AgentDashboard() {
1172
2054
  { id: "tools", label: "Tools", icon: "\uD83D\uDD27" },
1173
2055
  { id: "metrics", label: "Metrics", icon: "\uD83D\uDCCA" }
1174
2056
  ];
1175
- const summaryStats = useMemo3(() => {
2057
+ const summaryStats = useMemo4(() => {
1176
2058
  if (!metrics) {
1177
2059
  return [
1178
2060
  { label: "Total Runs", value: "-", hint: "Loading..." },
@@ -1204,20 +2086,20 @@ function AgentDashboard() {
1204
2086
  }
1205
2087
  ];
1206
2088
  }, [metrics]);
1207
- return /* @__PURE__ */ jsxDEV5("div", {
2089
+ return /* @__PURE__ */ jsxDEV9("div", {
1208
2090
  className: "space-y-6",
1209
2091
  children: [
1210
- /* @__PURE__ */ jsxDEV5("div", {
2092
+ /* @__PURE__ */ jsxDEV9("div", {
1211
2093
  className: "flex items-center justify-between",
1212
2094
  children: [
1213
- /* @__PURE__ */ jsxDEV5("h2", {
1214
- className: "text-2xl font-bold",
2095
+ /* @__PURE__ */ jsxDEV9("h2", {
2096
+ className: "font-bold text-2xl",
1215
2097
  children: "AI Agent Console"
1216
2098
  }, undefined, false, undefined, this),
1217
- /* @__PURE__ */ jsxDEV5(Button4, {
2099
+ /* @__PURE__ */ jsxDEV9(Button5, {
1218
2100
  onPress: () => setIsCreateModalOpen(true),
1219
2101
  children: [
1220
- /* @__PURE__ */ jsxDEV5("span", {
2102
+ /* @__PURE__ */ jsxDEV9("span", {
1221
2103
  className: "mr-2",
1222
2104
  children: "+"
1223
2105
  }, undefined, false, undefined, this),
@@ -1226,45 +2108,48 @@ function AgentDashboard() {
1226
2108
  }, undefined, true, undefined, this)
1227
2109
  ]
1228
2110
  }, undefined, true, undefined, this),
1229
- /* @__PURE__ */ jsxDEV5(StatCardGroup3, {
1230
- children: summaryStats.map((stat, i) => /* @__PURE__ */ jsxDEV5(StatCard3, {
2111
+ /* @__PURE__ */ jsxDEV9(StatCardGroup3, {
2112
+ children: summaryStats.map((stat, i) => /* @__PURE__ */ jsxDEV9(StatCard3, {
1231
2113
  label: stat.label,
1232
2114
  value: stat.value,
1233
2115
  hint: stat.hint
1234
2116
  }, i, false, undefined, this))
1235
2117
  }, undefined, false, undefined, this),
1236
- /* @__PURE__ */ jsxDEV5("nav", {
1237
- className: "bg-muted flex gap-1 rounded-lg p-1",
2118
+ /* @__PURE__ */ jsxDEV9(AgentVisualizationOverview, {
2119
+ runs: runData?.items ?? []
2120
+ }, undefined, false, undefined, this),
2121
+ /* @__PURE__ */ jsxDEV9("nav", {
2122
+ className: "flex gap-1 rounded-lg bg-muted p-1",
1238
2123
  role: "tablist",
1239
- children: tabs.map((tab) => /* @__PURE__ */ jsxDEV5("button", {
2124
+ children: tabs.map((tab) => /* @__PURE__ */ jsxDEV9("button", {
1240
2125
  type: "button",
1241
2126
  role: "tab",
1242
2127
  "aria-selected": activeTab === tab.id,
1243
2128
  onClick: () => setActiveTab(tab.id),
1244
- className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
2129
+ 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
2130
  children: [
1246
- /* @__PURE__ */ jsxDEV5("span", {
2131
+ /* @__PURE__ */ jsxDEV9("span", {
1247
2132
  children: tab.icon
1248
2133
  }, undefined, false, undefined, this),
1249
2134
  tab.label
1250
2135
  ]
1251
2136
  }, tab.id, true, undefined, this))
1252
2137
  }, undefined, false, undefined, this),
1253
- /* @__PURE__ */ jsxDEV5("div", {
2138
+ /* @__PURE__ */ jsxDEV9("div", {
1254
2139
  className: "min-h-[400px]",
1255
2140
  role: "tabpanel",
1256
2141
  children: [
1257
- activeTab === "runs" && /* @__PURE__ */ jsxDEV5(RunListView, {}, undefined, false, undefined, this),
1258
- activeTab === "agents" && /* @__PURE__ */ jsxDEV5(AgentListViewWithActions, {
2142
+ activeTab === "runs" && /* @__PURE__ */ jsxDEV9(RunListView, {}, undefined, false, undefined, this),
2143
+ activeTab === "agents" && /* @__PURE__ */ jsxDEV9(AgentListViewWithActions, {
1259
2144
  onAgentClick: handleAgentClick
1260
2145
  }, undefined, false, undefined, this),
1261
- activeTab === "tools" && /* @__PURE__ */ jsxDEV5(ToolRegistryView, {}, undefined, false, undefined, this),
1262
- activeTab === "metrics" && /* @__PURE__ */ jsxDEV5(MetricsView, {
2146
+ activeTab === "tools" && /* @__PURE__ */ jsxDEV9(ToolRegistryView, {}, undefined, false, undefined, this),
2147
+ activeTab === "metrics" && /* @__PURE__ */ jsxDEV9(MetricsView, {
1263
2148
  metrics
1264
2149
  }, undefined, false, undefined, this)
1265
2150
  ]
1266
2151
  }, undefined, true, undefined, this),
1267
- /* @__PURE__ */ jsxDEV5(CreateAgentModal, {
2152
+ /* @__PURE__ */ jsxDEV9(CreateAgentModal, {
1268
2153
  isOpen: isCreateModalOpen,
1269
2154
  onClose: () => setIsCreateModalOpen(false),
1270
2155
  onSubmit: async (input) => {
@@ -1272,7 +2157,7 @@ function AgentDashboard() {
1272
2157
  },
1273
2158
  isLoading: mutations.createState.loading
1274
2159
  }, undefined, false, undefined, this),
1275
- /* @__PURE__ */ jsxDEV5(AgentActionsModal, {
2160
+ /* @__PURE__ */ jsxDEV9(AgentActionsModal, {
1276
2161
  isOpen: isAgentActionsOpen,
1277
2162
  agent: selectedAgent,
1278
2163
  onClose: () => {
@@ -1301,22 +2186,22 @@ function AgentListViewWithActions({
1301
2186
  }) {
1302
2187
  const { data, loading, error, stats, refetch } = useAgentList();
1303
2188
  if (loading && !data) {
1304
- return /* @__PURE__ */ jsxDEV5("div", {
1305
- className: "text-muted-foreground flex h-64 items-center justify-center",
2189
+ return /* @__PURE__ */ jsxDEV9("div", {
2190
+ className: "flex h-64 items-center justify-center text-muted-foreground",
1306
2191
  children: "Loading agents..."
1307
2192
  }, undefined, false, undefined, this);
1308
2193
  }
1309
2194
  if (error) {
1310
- return /* @__PURE__ */ jsxDEV5("div", {
1311
- className: "text-destructive flex h-64 flex-col items-center justify-center",
2195
+ return /* @__PURE__ */ jsxDEV9("div", {
2196
+ className: "flex h-64 flex-col items-center justify-center text-destructive",
1312
2197
  children: [
1313
- /* @__PURE__ */ jsxDEV5("p", {
2198
+ /* @__PURE__ */ jsxDEV9("p", {
1314
2199
  children: [
1315
2200
  "Failed to load agents: ",
1316
2201
  error.message
1317
2202
  ]
1318
2203
  }, undefined, true, undefined, this),
1319
- /* @__PURE__ */ jsxDEV5(Button4, {
2204
+ /* @__PURE__ */ jsxDEV9(Button5, {
1320
2205
  variant: "outline",
1321
2206
  onPress: refetch,
1322
2207
  className: "mt-2",
@@ -1326,47 +2211,47 @@ function AgentListViewWithActions({
1326
2211
  }, undefined, true, undefined, this);
1327
2212
  }
1328
2213
  if (!data?.items.length) {
1329
- return /* @__PURE__ */ jsxDEV5("div", {
1330
- className: "text-muted-foreground flex h-64 flex-col items-center justify-center",
2214
+ return /* @__PURE__ */ jsxDEV9("div", {
2215
+ className: "flex h-64 flex-col items-center justify-center text-muted-foreground",
1331
2216
  children: [
1332
- /* @__PURE__ */ jsxDEV5("p", {
1333
- className: "text-lg font-medium",
2217
+ /* @__PURE__ */ jsxDEV9("p", {
2218
+ className: "font-medium text-lg",
1334
2219
  children: "No agents yet"
1335
2220
  }, undefined, false, undefined, this),
1336
- /* @__PURE__ */ jsxDEV5("p", {
2221
+ /* @__PURE__ */ jsxDEV9("p", {
1337
2222
  className: "text-sm",
1338
2223
  children: "Create your first AI agent to get started."
1339
2224
  }, undefined, false, undefined, this)
1340
2225
  ]
1341
2226
  }, undefined, true, undefined, this);
1342
2227
  }
1343
- return /* @__PURE__ */ jsxDEV5("div", {
2228
+ return /* @__PURE__ */ jsxDEV9("div", {
1344
2229
  className: "space-y-4",
1345
2230
  children: [
1346
- stats && /* @__PURE__ */ jsxDEV5("div", {
2231
+ stats && /* @__PURE__ */ jsxDEV9("div", {
1347
2232
  className: "flex gap-4 text-sm",
1348
2233
  children: [
1349
- /* @__PURE__ */ jsxDEV5("span", {
2234
+ /* @__PURE__ */ jsxDEV9("span", {
1350
2235
  children: [
1351
2236
  "Total: ",
1352
2237
  stats.total
1353
2238
  ]
1354
2239
  }, undefined, true, undefined, this),
1355
- /* @__PURE__ */ jsxDEV5("span", {
2240
+ /* @__PURE__ */ jsxDEV9("span", {
1356
2241
  className: "text-green-600",
1357
2242
  children: [
1358
2243
  "Active: ",
1359
2244
  stats.active
1360
2245
  ]
1361
2246
  }, undefined, true, undefined, this),
1362
- /* @__PURE__ */ jsxDEV5("span", {
2247
+ /* @__PURE__ */ jsxDEV9("span", {
1363
2248
  className: "text-yellow-600",
1364
2249
  children: [
1365
2250
  "Paused: ",
1366
2251
  stats.paused
1367
2252
  ]
1368
2253
  }, undefined, true, undefined, this),
1369
- /* @__PURE__ */ jsxDEV5("span", {
2254
+ /* @__PURE__ */ jsxDEV9("span", {
1370
2255
  className: "text-blue-600",
1371
2256
  children: [
1372
2257
  "Draft: ",
@@ -1375,9 +2260,9 @@ function AgentListViewWithActions({
1375
2260
  }, undefined, true, undefined, this)
1376
2261
  ]
1377
2262
  }, undefined, true, undefined, this),
1378
- /* @__PURE__ */ jsxDEV5("div", {
2263
+ /* @__PURE__ */ jsxDEV9("div", {
1379
2264
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
1380
- children: data.items.map((agent) => /* @__PURE__ */ jsxDEV5(AgentCard, {
2265
+ children: data.items.map((agent) => /* @__PURE__ */ jsxDEV9(AgentCard, {
1381
2266
  agent,
1382
2267
  onClick: () => onAgentClick(agent)
1383
2268
  }, agent.id, false, undefined, this))
@@ -1392,9 +2277,9 @@ function AgentCard({ agent, onClick }) {
1392
2277
  PAUSED: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400",
1393
2278
  ARCHIVED: "bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400"
1394
2279
  };
1395
- return /* @__PURE__ */ jsxDEV5("div", {
2280
+ return /* @__PURE__ */ jsxDEV9("div", {
1396
2281
  onClick,
1397
- className: "border-border bg-card cursor-pointer rounded-xl border p-4 transition-all hover:shadow-md",
2282
+ className: "cursor-pointer rounded-xl border border-border bg-card p-4 transition-all hover:shadow-md",
1398
2283
  role: "button",
1399
2284
  tabIndex: 0,
1400
2285
  onKeyDown: (e) => {
@@ -1402,17 +2287,17 @@ function AgentCard({ agent, onClick }) {
1402
2287
  onClick();
1403
2288
  },
1404
2289
  children: [
1405
- /* @__PURE__ */ jsxDEV5("div", {
2290
+ /* @__PURE__ */ jsxDEV9("div", {
1406
2291
  className: "flex items-start justify-between",
1407
2292
  children: [
1408
- /* @__PURE__ */ jsxDEV5("div", {
2293
+ /* @__PURE__ */ jsxDEV9("div", {
1409
2294
  className: "min-w-0 flex-1",
1410
2295
  children: [
1411
- /* @__PURE__ */ jsxDEV5("h3", {
2296
+ /* @__PURE__ */ jsxDEV9("h3", {
1412
2297
  className: "truncate font-semibold",
1413
2298
  children: agent.name
1414
2299
  }, undefined, false, undefined, this),
1415
- /* @__PURE__ */ jsxDEV5("p", {
2300
+ /* @__PURE__ */ jsxDEV9("p", {
1416
2301
  className: "text-muted-foreground text-sm",
1417
2302
  children: [
1418
2303
  agent.modelProvider,
@@ -1422,24 +2307,24 @@ function AgentCard({ agent, onClick }) {
1422
2307
  }, undefined, true, undefined, this)
1423
2308
  ]
1424
2309
  }, undefined, true, undefined, this),
1425
- /* @__PURE__ */ jsxDEV5("span", {
1426
- className: `rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[agent.status]}`,
2310
+ /* @__PURE__ */ jsxDEV9("span", {
2311
+ className: `rounded-full px-2 py-0.5 font-medium text-xs ${statusColors[agent.status]}`,
1427
2312
  children: agent.status
1428
2313
  }, undefined, false, undefined, this)
1429
2314
  ]
1430
2315
  }, undefined, true, undefined, this),
1431
- agent.description && /* @__PURE__ */ jsxDEV5("p", {
1432
- className: "text-muted-foreground mt-2 line-clamp-2 text-sm",
2316
+ agent.description && /* @__PURE__ */ jsxDEV9("p", {
2317
+ className: "mt-2 line-clamp-2 text-muted-foreground text-sm",
1433
2318
  children: agent.description
1434
2319
  }, undefined, false, undefined, this),
1435
- /* @__PURE__ */ jsxDEV5("div", {
2320
+ /* @__PURE__ */ jsxDEV9("div", {
1436
2321
  className: "mt-3 flex items-center justify-between",
1437
2322
  children: [
1438
- /* @__PURE__ */ jsxDEV5("span", {
2323
+ /* @__PURE__ */ jsxDEV9("span", {
1439
2324
  className: "text-muted-foreground text-xs",
1440
2325
  children: agent.modelName
1441
2326
  }, undefined, false, undefined, this),
1442
- /* @__PURE__ */ jsxDEV5(Button4, {
2327
+ /* @__PURE__ */ jsxDEV9(Button5, {
1443
2328
  variant: "ghost",
1444
2329
  size: "sm",
1445
2330
  onPress: onClick,
@@ -1452,40 +2337,40 @@ function AgentCard({ agent, onClick }) {
1452
2337
  }
1453
2338
  function MetricsView({ metrics }) {
1454
2339
  if (!metrics) {
1455
- return /* @__PURE__ */ jsxDEV5("div", {
1456
- className: "text-muted-foreground flex h-64 items-center justify-center",
2340
+ return /* @__PURE__ */ jsxDEV9("div", {
2341
+ className: "flex h-64 items-center justify-center text-muted-foreground",
1457
2342
  children: "Loading metrics..."
1458
2343
  }, undefined, false, undefined, this);
1459
2344
  }
1460
2345
  const completedRuns = Math.round(metrics.totalRuns * metrics.successRate);
1461
2346
  const failedRuns = metrics.totalRuns - completedRuns;
1462
- return /* @__PURE__ */ jsxDEV5("div", {
2347
+ return /* @__PURE__ */ jsxDEV9("div", {
1463
2348
  className: "space-y-6",
1464
2349
  children: [
1465
- /* @__PURE__ */ jsxDEV5("h3", {
1466
- className: "text-lg font-semibold",
2350
+ /* @__PURE__ */ jsxDEV9("h3", {
2351
+ className: "font-semibold text-lg",
1467
2352
  children: "Usage Analytics"
1468
2353
  }, undefined, false, undefined, this),
1469
- /* @__PURE__ */ jsxDEV5("div", {
2354
+ /* @__PURE__ */ jsxDEV9("div", {
1470
2355
  className: "grid gap-6 md:grid-cols-2",
1471
2356
  children: [
1472
- /* @__PURE__ */ jsxDEV5("div", {
1473
- className: "border-border bg-card rounded-xl border p-4",
2357
+ /* @__PURE__ */ jsxDEV9("div", {
2358
+ className: "rounded-xl border border-border bg-card p-4",
1474
2359
  children: [
1475
- /* @__PURE__ */ jsxDEV5("h4", {
2360
+ /* @__PURE__ */ jsxDEV9("h4", {
1476
2361
  className: "font-medium",
1477
2362
  children: "Run Outcomes"
1478
2363
  }, undefined, false, undefined, this),
1479
- /* @__PURE__ */ jsxDEV5("div", {
2364
+ /* @__PURE__ */ jsxDEV9("div", {
1480
2365
  className: "mt-4 space-y-3",
1481
2366
  children: [
1482
- /* @__PURE__ */ jsxDEV5(ProgressBar, {
2367
+ /* @__PURE__ */ jsxDEV9(ProgressBar, {
1483
2368
  label: "Completed",
1484
2369
  value: completedRuns,
1485
2370
  total: metrics.totalRuns,
1486
2371
  color: "bg-green-500"
1487
2372
  }, undefined, false, undefined, this),
1488
- /* @__PURE__ */ jsxDEV5(ProgressBar, {
2373
+ /* @__PURE__ */ jsxDEV9(ProgressBar, {
1489
2374
  label: "Failed",
1490
2375
  value: failedRuns,
1491
2376
  total: metrics.totalRuns,
@@ -1495,24 +2380,24 @@ function MetricsView({ metrics }) {
1495
2380
  }, undefined, true, undefined, this)
1496
2381
  ]
1497
2382
  }, undefined, true, undefined, this),
1498
- /* @__PURE__ */ jsxDEV5("div", {
1499
- className: "border-border bg-card rounded-xl border p-4",
2383
+ /* @__PURE__ */ jsxDEV9("div", {
2384
+ className: "rounded-xl border border-border bg-card p-4",
1500
2385
  children: [
1501
- /* @__PURE__ */ jsxDEV5("h4", {
2386
+ /* @__PURE__ */ jsxDEV9("h4", {
1502
2387
  className: "font-medium",
1503
2388
  children: "Performance"
1504
2389
  }, undefined, false, undefined, this),
1505
- /* @__PURE__ */ jsxDEV5("dl", {
2390
+ /* @__PURE__ */ jsxDEV9("dl", {
1506
2391
  className: "mt-4 grid grid-cols-2 gap-4",
1507
2392
  children: [
1508
- /* @__PURE__ */ jsxDEV5("div", {
2393
+ /* @__PURE__ */ jsxDEV9("div", {
1509
2394
  children: [
1510
- /* @__PURE__ */ jsxDEV5("dt", {
2395
+ /* @__PURE__ */ jsxDEV9("dt", {
1511
2396
  className: "text-muted-foreground text-sm",
1512
2397
  children: "Avg Duration"
1513
2398
  }, undefined, false, undefined, this),
1514
- /* @__PURE__ */ jsxDEV5("dd", {
1515
- className: "text-xl font-semibold",
2399
+ /* @__PURE__ */ jsxDEV9("dd", {
2400
+ className: "font-semibold text-xl",
1516
2401
  children: [
1517
2402
  (metrics.averageDurationMs / 1000).toFixed(1),
1518
2403
  "s"
@@ -1520,14 +2405,14 @@ function MetricsView({ metrics }) {
1520
2405
  }, undefined, true, undefined, this)
1521
2406
  ]
1522
2407
  }, undefined, true, undefined, this),
1523
- /* @__PURE__ */ jsxDEV5("div", {
2408
+ /* @__PURE__ */ jsxDEV9("div", {
1524
2409
  children: [
1525
- /* @__PURE__ */ jsxDEV5("dt", {
2410
+ /* @__PURE__ */ jsxDEV9("dt", {
1526
2411
  className: "text-muted-foreground text-sm",
1527
2412
  children: "Success Rate"
1528
2413
  }, undefined, false, undefined, this),
1529
- /* @__PURE__ */ jsxDEV5("dd", {
1530
- className: "text-xl font-semibold",
2414
+ /* @__PURE__ */ jsxDEV9("dd", {
2415
+ className: "font-semibold text-xl",
1531
2416
  children: [
1532
2417
  (metrics.successRate * 100).toFixed(0),
1533
2418
  "%"
@@ -1541,36 +2426,36 @@ function MetricsView({ metrics }) {
1541
2426
  }, undefined, true, undefined, this)
1542
2427
  ]
1543
2428
  }, undefined, true, undefined, this),
1544
- /* @__PURE__ */ jsxDEV5("div", {
1545
- className: "border-border bg-card rounded-xl border p-4",
2429
+ /* @__PURE__ */ jsxDEV9("div", {
2430
+ className: "rounded-xl border border-border bg-card p-4",
1546
2431
  children: [
1547
- /* @__PURE__ */ jsxDEV5("h4", {
2432
+ /* @__PURE__ */ jsxDEV9("h4", {
1548
2433
  className: "font-medium",
1549
2434
  children: "Key Metrics"
1550
2435
  }, undefined, false, undefined, this),
1551
- /* @__PURE__ */ jsxDEV5("dl", {
2436
+ /* @__PURE__ */ jsxDEV9("dl", {
1552
2437
  className: "mt-4 grid gap-4 sm:grid-cols-3",
1553
2438
  children: [
1554
- /* @__PURE__ */ jsxDEV5("div", {
2439
+ /* @__PURE__ */ jsxDEV9("div", {
1555
2440
  children: [
1556
- /* @__PURE__ */ jsxDEV5("dt", {
2441
+ /* @__PURE__ */ jsxDEV9("dt", {
1557
2442
  className: "text-muted-foreground text-sm",
1558
2443
  children: "Total Runs"
1559
2444
  }, undefined, false, undefined, this),
1560
- /* @__PURE__ */ jsxDEV5("dd", {
1561
- className: "text-2xl font-semibold",
2445
+ /* @__PURE__ */ jsxDEV9("dd", {
2446
+ className: "font-semibold text-2xl",
1562
2447
  children: metrics.totalRuns.toLocaleString()
1563
2448
  }, undefined, false, undefined, this)
1564
2449
  ]
1565
2450
  }, undefined, true, undefined, this),
1566
- /* @__PURE__ */ jsxDEV5("div", {
2451
+ /* @__PURE__ */ jsxDEV9("div", {
1567
2452
  children: [
1568
- /* @__PURE__ */ jsxDEV5("dt", {
2453
+ /* @__PURE__ */ jsxDEV9("dt", {
1569
2454
  className: "text-muted-foreground text-sm",
1570
2455
  children: "Total Tokens"
1571
2456
  }, undefined, false, undefined, this),
1572
- /* @__PURE__ */ jsxDEV5("dd", {
1573
- className: "text-2xl font-semibold",
2457
+ /* @__PURE__ */ jsxDEV9("dd", {
2458
+ className: "font-semibold text-2xl",
1574
2459
  children: [
1575
2460
  (metrics.totalTokens / 1000).toFixed(0),
1576
2461
  "K"
@@ -1578,14 +2463,14 @@ function MetricsView({ metrics }) {
1578
2463
  }, undefined, true, undefined, this)
1579
2464
  ]
1580
2465
  }, undefined, true, undefined, this),
1581
- /* @__PURE__ */ jsxDEV5("div", {
2466
+ /* @__PURE__ */ jsxDEV9("div", {
1582
2467
  children: [
1583
- /* @__PURE__ */ jsxDEV5("dt", {
2468
+ /* @__PURE__ */ jsxDEV9("dt", {
1584
2469
  className: "text-muted-foreground text-sm",
1585
2470
  children: "Cost per Run"
1586
2471
  }, undefined, false, undefined, this),
1587
- /* @__PURE__ */ jsxDEV5("dd", {
1588
- className: "text-2xl font-semibold",
2472
+ /* @__PURE__ */ jsxDEV9("dd", {
2473
+ className: "font-semibold text-2xl",
1589
2474
  children: [
1590
2475
  "$",
1591
2476
  metrics.totalRuns > 0 ? (metrics.totalCostUsd / metrics.totalRuns).toFixed(4) : "0"
@@ -1607,15 +2492,15 @@ function ProgressBar({
1607
2492
  color
1608
2493
  }) {
1609
2494
  const pct = total > 0 ? value / total * 100 : 0;
1610
- return /* @__PURE__ */ jsxDEV5("div", {
2495
+ return /* @__PURE__ */ jsxDEV9("div", {
1611
2496
  children: [
1612
- /* @__PURE__ */ jsxDEV5("div", {
2497
+ /* @__PURE__ */ jsxDEV9("div", {
1613
2498
  className: "flex justify-between text-sm",
1614
2499
  children: [
1615
- /* @__PURE__ */ jsxDEV5("span", {
2500
+ /* @__PURE__ */ jsxDEV9("span", {
1616
2501
  children: label
1617
2502
  }, undefined, false, undefined, this),
1618
- /* @__PURE__ */ jsxDEV5("span", {
2503
+ /* @__PURE__ */ jsxDEV9("span", {
1619
2504
  className: "text-muted-foreground",
1620
2505
  children: [
1621
2506
  value,
@@ -1626,9 +2511,9 @@ function ProgressBar({
1626
2511
  }, undefined, true, undefined, this)
1627
2512
  ]
1628
2513
  }, undefined, true, undefined, this),
1629
- /* @__PURE__ */ jsxDEV5("div", {
1630
- className: "bg-muted mt-1 h-2 overflow-hidden rounded-full",
1631
- children: /* @__PURE__ */ jsxDEV5("div", {
2514
+ /* @__PURE__ */ jsxDEV9("div", {
2515
+ className: "mt-1 h-2 overflow-hidden rounded-full bg-muted",
2516
+ children: /* @__PURE__ */ jsxDEV9("div", {
1632
2517
  className: `h-full ${color}`,
1633
2518
  style: { width: `${pct}%` }
1634
2519
  }, undefined, false, undefined, this)
@@ -1643,18 +2528,141 @@ function ProgressBar({
1643
2528
  // src/ui/AgentToolRegistry.tsx
1644
2529
  "use client";
1645
2530
 
2531
+ // src/ui/hooks/index.ts
2532
+ "use client";
2533
+ // src/ui/overlays/demo-overlays.ts
2534
+ var agentConsoleDemoOverlay = {
2535
+ overlayId: "agent-console.demo-user",
2536
+ version: "1.0.0",
2537
+ description: "Simplifies agent console for demo users",
2538
+ appliesTo: {
2539
+ feature: "agent-console",
2540
+ role: "demo"
2541
+ },
2542
+ modifications: [
2543
+ {
2544
+ type: "hideField",
2545
+ field: "modelConfig",
2546
+ reason: "Advanced config not relevant for demo"
2547
+ },
2548
+ {
2549
+ type: "hideField",
2550
+ field: "webhookConfig",
2551
+ reason: "Integration not available in demo"
2552
+ },
2553
+ {
2554
+ type: "renameLabel",
2555
+ field: "systemPrompt",
2556
+ newLabel: "Agent Instructions"
2557
+ },
2558
+ {
2559
+ type: "addBadge",
2560
+ position: "header",
2561
+ label: "Demo Mode",
2562
+ variant: "warning"
2563
+ }
2564
+ ]
2565
+ };
2566
+ var agentConsoleReadOnlyOverlay = {
2567
+ overlayId: "agent-console.read-only",
2568
+ version: "1.0.0",
2569
+ description: "Read-only view for non-admin users",
2570
+ appliesTo: {
2571
+ feature: "agent-console",
2572
+ role: "viewer"
2573
+ },
2574
+ modifications: [
2575
+ {
2576
+ type: "hideField",
2577
+ field: "deleteButton",
2578
+ reason: "No delete permission"
2579
+ },
2580
+ { type: "hideField", field: "editButton", reason: "No edit permission" },
2581
+ {
2582
+ type: "hideField",
2583
+ field: "createButton",
2584
+ reason: "No create permission"
2585
+ }
2586
+ ]
2587
+ };
2588
+ var agentConsoleOverlays = [
2589
+ agentConsoleDemoOverlay,
2590
+ agentConsoleReadOnlyOverlay
2591
+ ];
2592
+ // src/ui/renderers/agent-list.markdown.ts
2593
+ import {
2594
+ AGENT_CONSOLE_DEMO_ORGANIZATION_ID as AGENT_CONSOLE_DEMO_ORGANIZATION_ID2,
2595
+ AGENT_CONSOLE_DEMO_PROJECT_ID as AGENT_CONSOLE_DEMO_PROJECT_ID2,
2596
+ createAgentConsoleDemoHandlers
2597
+ } from "@contractspec/example.agent-console/shared";
2598
+ var agentListMarkdownRenderer = {
2599
+ target: "markdown",
2600
+ render: async (desc, ctx) => {
2601
+ if (desc.source.type !== "component" || desc.source.componentKey !== "AgentListView") {
2602
+ throw new Error("agentListMarkdownRenderer: not AgentListView");
2603
+ }
2604
+ const data = Array.isArray(ctx?.data) ? {
2605
+ items: ctx.data,
2606
+ total: ctx.data.length,
2607
+ hasMore: false
2608
+ } : await createAgentConsoleDemoHandlers({
2609
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID2
2610
+ }).listAgents({
2611
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID2,
2612
+ organizationId: AGENT_CONSOLE_DEMO_ORGANIZATION_ID2,
2613
+ limit: 50,
2614
+ offset: 0
2615
+ });
2616
+ const lines = [
2617
+ `# ${desc.meta.description ?? "Agent List"}`,
2618
+ "",
2619
+ `> ${desc.meta.key} v${desc.meta.version}`,
2620
+ "",
2621
+ `**Total Agents:** ${data.total}`,
2622
+ "",
2623
+ "## Agents",
2624
+ ""
2625
+ ];
2626
+ const byStatus = {};
2627
+ for (const agent of data.items) {
2628
+ const status = agent.status;
2629
+ if (byStatus[status]) {
2630
+ byStatus[status].push(agent);
2631
+ } else {
2632
+ byStatus[status] = [agent];
2633
+ }
2634
+ }
2635
+ for (const [status, agents] of Object.entries(byStatus)) {
2636
+ lines.push(`### ${status} (${agents.length})`);
2637
+ lines.push("");
2638
+ for (const agent of agents) {
2639
+ lines.push(`- **${agent.name}** (${agent.modelProvider}/${agent.modelName})`);
2640
+ if (agent.description) {
2641
+ lines.push(` > ${agent.description}`);
2642
+ }
2643
+ }
2644
+ lines.push("");
2645
+ }
2646
+ return {
2647
+ mimeType: "text/markdown",
2648
+ body: lines.join(`
2649
+ `)
2650
+ };
2651
+ }
2652
+ };
2653
+
1646
2654
  // src/ui/views/AgentListView.tsx
1647
2655
  import {
1648
- Button as Button5,
1649
- StatCard as StatCard4,
1650
- StatCardGroup as StatCardGroup4,
2656
+ Button as Button6,
2657
+ EmptyState as EmptyState3,
1651
2658
  EntityCard as EntityCard2,
1652
- StatusChip as StatusChip3,
1653
- LoaderBlock as LoaderBlock3,
1654
2659
  ErrorState as ErrorState3,
1655
- EmptyState as EmptyState3
2660
+ LoaderBlock as LoaderBlock3,
2661
+ StatCard as StatCard4,
2662
+ StatCardGroup as StatCardGroup4,
2663
+ StatusChip as StatusChip4
1656
2664
  } from "@contractspec/lib.design-system";
1657
- import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
2665
+ import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
1658
2666
  "use client";
1659
2667
  function getStatusTone3(status) {
1660
2668
  switch (status) {
@@ -1672,12 +2680,12 @@ function getStatusTone3(status) {
1672
2680
  function AgentListView() {
1673
2681
  const { data, loading, error, stats, refetch } = useAgentList();
1674
2682
  if (loading && !data) {
1675
- return /* @__PURE__ */ jsxDEV6(LoaderBlock3, {
2683
+ return /* @__PURE__ */ jsxDEV10(LoaderBlock3, {
1676
2684
  label: "Loading agents..."
1677
2685
  }, undefined, false, undefined, this);
1678
2686
  }
1679
2687
  if (error) {
1680
- return /* @__PURE__ */ jsxDEV6(ErrorState3, {
2688
+ return /* @__PURE__ */ jsxDEV10(ErrorState3, {
1681
2689
  title: "Failed to load agents",
1682
2690
  description: error.message,
1683
2691
  onRetry: refetch,
@@ -1685,61 +2693,61 @@ function AgentListView() {
1685
2693
  }, undefined, false, undefined, this);
1686
2694
  }
1687
2695
  if (!data?.items.length) {
1688
- return /* @__PURE__ */ jsxDEV6(EmptyState3, {
2696
+ return /* @__PURE__ */ jsxDEV10(EmptyState3, {
1689
2697
  title: "No agents yet",
1690
2698
  description: "Create your first AI agent to get started."
1691
2699
  }, undefined, false, undefined, this);
1692
2700
  }
1693
- return /* @__PURE__ */ jsxDEV6("div", {
2701
+ return /* @__PURE__ */ jsxDEV10("div", {
1694
2702
  className: "space-y-6",
1695
2703
  children: [
1696
- stats && /* @__PURE__ */ jsxDEV6(StatCardGroup4, {
2704
+ stats && /* @__PURE__ */ jsxDEV10(StatCardGroup4, {
1697
2705
  children: [
1698
- /* @__PURE__ */ jsxDEV6(StatCard4, {
2706
+ /* @__PURE__ */ jsxDEV10(StatCard4, {
1699
2707
  label: "Total Agents",
1700
2708
  value: stats.total
1701
2709
  }, undefined, false, undefined, this),
1702
- /* @__PURE__ */ jsxDEV6(StatCard4, {
2710
+ /* @__PURE__ */ jsxDEV10(StatCard4, {
1703
2711
  label: "Active",
1704
2712
  value: stats.active
1705
2713
  }, undefined, false, undefined, this),
1706
- /* @__PURE__ */ jsxDEV6(StatCard4, {
2714
+ /* @__PURE__ */ jsxDEV10(StatCard4, {
1707
2715
  label: "Paused",
1708
2716
  value: stats.paused
1709
2717
  }, undefined, false, undefined, this),
1710
- /* @__PURE__ */ jsxDEV6(StatCard4, {
2718
+ /* @__PURE__ */ jsxDEV10(StatCard4, {
1711
2719
  label: "Draft",
1712
2720
  value: stats.draft
1713
2721
  }, undefined, false, undefined, this)
1714
2722
  ]
1715
2723
  }, undefined, true, undefined, this),
1716
- /* @__PURE__ */ jsxDEV6("div", {
2724
+ /* @__PURE__ */ jsxDEV10("div", {
1717
2725
  className: "flex items-center justify-between",
1718
2726
  children: [
1719
- /* @__PURE__ */ jsxDEV6("h3", {
1720
- className: "text-lg font-semibold",
2727
+ /* @__PURE__ */ jsxDEV10("h3", {
2728
+ className: "font-semibold text-lg",
1721
2729
  children: "Agents"
1722
2730
  }, undefined, false, undefined, this),
1723
- /* @__PURE__ */ jsxDEV6(Button5, {
2731
+ /* @__PURE__ */ jsxDEV10(Button6, {
1724
2732
  onPress: () => alert("Create Agent clicked!"),
1725
2733
  children: "Create Agent"
1726
2734
  }, undefined, false, undefined, this)
1727
2735
  ]
1728
2736
  }, undefined, true, undefined, this),
1729
- /* @__PURE__ */ jsxDEV6("div", {
2737
+ /* @__PURE__ */ jsxDEV10("div", {
1730
2738
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
1731
- children: data.items.map((agent) => /* @__PURE__ */ jsxDEV6(EntityCard2, {
2739
+ children: data.items.map((agent) => /* @__PURE__ */ jsxDEV10(EntityCard2, {
1732
2740
  cardTitle: agent.name,
1733
2741
  cardSubtitle: agent.modelName,
1734
- meta: /* @__PURE__ */ jsxDEV6("p", {
2742
+ meta: /* @__PURE__ */ jsxDEV10("p", {
1735
2743
  className: "text-muted-foreground text-sm",
1736
2744
  children: agent.description
1737
2745
  }, undefined, false, undefined, this),
1738
- chips: /* @__PURE__ */ jsxDEV6(StatusChip3, {
2746
+ chips: /* @__PURE__ */ jsxDEV10(StatusChip4, {
1739
2747
  tone: getStatusTone3(agent.status),
1740
2748
  label: agent.status
1741
2749
  }, undefined, false, undefined, this),
1742
- footer: /* @__PURE__ */ jsxDEV6("span", {
2750
+ footer: /* @__PURE__ */ jsxDEV10("span", {
1743
2751
  className: "text-muted-foreground text-xs",
1744
2752
  children: [
1745
2753
  "Created ",
@@ -1752,11 +2760,9 @@ function AgentListView() {
1752
2760
  ]
1753
2761
  }, undefined, true, undefined, this);
1754
2762
  }
1755
- // src/ui/hooks/index.ts
1756
- "use client";
1757
2763
 
1758
2764
  // src/ui/renderers/agent-list.renderer.tsx
1759
- import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
2765
+ import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
1760
2766
  var agentListReactRenderer = {
1761
2767
  target: "react",
1762
2768
  render: async (desc) => {
@@ -1766,54 +2772,109 @@ var agentListReactRenderer = {
1766
2772
  if (desc.source.componentKey !== "AgentListView") {
1767
2773
  throw new Error(`AgentListRenderer: unknown component ${desc.source.componentKey}`);
1768
2774
  }
1769
- return /* @__PURE__ */ jsxDEV7(AgentListView, {}, undefined, false, undefined, this);
2775
+ return /* @__PURE__ */ jsxDEV11(AgentListView, {}, undefined, false, undefined, this);
1770
2776
  }
1771
2777
  };
1772
2778
 
1773
- // src/ui/renderers/agent-list.markdown.ts
2779
+ // src/ui/renderers/dashboard.markdown.ts
1774
2780
  import {
1775
- mockListAgentsHandler
1776
- } from "@contractspec/example.agent-console/handlers";
1777
- var agentListMarkdownRenderer = {
2781
+ getFallbackAgentConsoleDashboardData
2782
+ } from "@contractspec/example.agent-console/shared";
2783
+ function formatDuration2(ms) {
2784
+ if (ms < 1000)
2785
+ return `${ms}ms`;
2786
+ if (ms < 60000)
2787
+ return `${(ms / 1000).toFixed(1)}s`;
2788
+ return `${(ms / 60000).toFixed(1)}m`;
2789
+ }
2790
+ var agentDashboardMarkdownRenderer = {
1778
2791
  target: "markdown",
1779
- render: async (desc) => {
1780
- if (desc.source.type !== "component" || desc.source.componentKey !== "AgentListView") {
1781
- throw new Error("agentListMarkdownRenderer: not AgentListView");
2792
+ render: async (desc, ctx) => {
2793
+ if (desc.source.type !== "component" || desc.source.componentKey !== "AgentConsoleDashboard") {
2794
+ throw new Error("agentDashboardMarkdownRenderer: not AgentConsoleDashboard");
1782
2795
  }
1783
- const data = await mockListAgentsHandler({
1784
- organizationId: "demo-org",
1785
- limit: 50,
1786
- offset: 0
1787
- });
2796
+ const data = ctx?.data ?? await getFallbackAgentConsoleDashboardData();
2797
+ const activeAgents = data.agents.filter((a) => a.status === "ACTIVE").length;
2798
+ const completedRuns = data.runs.filter((r) => r.status === "COMPLETED").length;
2799
+ const failedRuns = data.runs.filter((r) => r.status === "FAILED").length;
2800
+ const totalTokens = data.runs.reduce((sum, r) => sum + (r.totalTokens ?? 0), 0);
2801
+ const totalCost = data.runs.reduce((sum, r) => sum + (r.estimatedCostUsd ?? 0), 0);
2802
+ const activeTools = data.tools.filter((t) => t.status === "ACTIVE").length;
2803
+ const visualizationItems = createAgentVisualizationItems(data.runs);
1788
2804
  const lines = [
1789
- `# ${desc.meta.description ?? "Agent List"}`,
2805
+ "# Agent Console Dashboard",
1790
2806
  "",
1791
- `> ${desc.meta.key} v${desc.meta.version}`,
2807
+ "> AI agent operations overview",
1792
2808
  "",
1793
- `**Total Agents:** ${data.total}`,
2809
+ "## Summary",
2810
+ "",
2811
+ "| Metric | Value |",
2812
+ "|--------|-------|",
2813
+ `| Total Agents | ${data.summary.totalAgents} |`,
2814
+ `| Active Agents | ${activeAgents} |`,
2815
+ `| Total Runs | ${data.summary.totalRuns} |`,
2816
+ `| Completed Runs | ${completedRuns} |`,
2817
+ `| Failed Runs | ${failedRuns} |`,
2818
+ `| Total Tokens | ${totalTokens.toLocaleString()} |`,
2819
+ `| Total Cost | $${totalCost.toFixed(4)} |`,
2820
+ `| Total Tools | ${data.summary.totalTools} |`,
2821
+ `| Active Tools | ${activeTools} |`,
1794
2822
  "",
1795
2823
  "## Agents",
1796
2824
  ""
1797
2825
  ];
1798
- const byStatus = {};
1799
- for (const agent of data.items) {
1800
- const status = agent.status;
1801
- if (byStatus[status]) {
1802
- byStatus[status].push(agent);
1803
- } else {
1804
- byStatus[status] = [agent];
2826
+ if (data.agents.length === 0) {
2827
+ lines.push("_No agents configured._");
2828
+ } else {
2829
+ lines.push("| Agent | Model | Status | Description |");
2830
+ lines.push("|-------|-------|--------|-------------|");
2831
+ for (const agent of data.agents.slice(0, 5)) {
2832
+ lines.push(`| ${agent.name} | ${agent.modelProvider}/${agent.modelName} | ${agent.status} | ${agent.description ?? "-"} |`);
2833
+ }
2834
+ if (data.agents.length > 5) {
2835
+ lines.push(`| ... | ... | ... | _${data.summary.totalAgents - 5} more_ |`);
1805
2836
  }
1806
2837
  }
1807
- for (const [status, agents] of Object.entries(byStatus)) {
1808
- lines.push(`### ${status} (${agents.length})`);
1809
- lines.push("");
1810
- for (const agent of agents) {
1811
- lines.push(`- **${agent.name}** (${agent.modelProvider}/${agent.modelName})`);
1812
- if (agent.description) {
1813
- lines.push(` > ${agent.description}`);
1814
- }
2838
+ lines.push("");
2839
+ lines.push("## Recent Runs");
2840
+ lines.push("");
2841
+ if (data.runs.length === 0) {
2842
+ lines.push("_No runs yet._");
2843
+ } else {
2844
+ lines.push("| Run ID | Agent | Status | Duration | Tokens | Cost |");
2845
+ lines.push("|--------|-------|--------|----------|--------|------|");
2846
+ for (const run of data.runs.slice(0, 5)) {
2847
+ lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration2(run.durationMs) : "-"} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`);
2848
+ }
2849
+ if (data.runs.length > 5) {
2850
+ lines.push(`| ... | ... | ... | ... | ... | _${data.summary.totalRuns - 5} more_ |`);
2851
+ }
2852
+ }
2853
+ lines.push("");
2854
+ lines.push("## Visualization Overview");
2855
+ lines.push("");
2856
+ for (const item of visualizationItems) {
2857
+ lines.push(`- **${item.title}** via \`${item.spec.meta.key}\``);
2858
+ }
2859
+ lines.push("");
2860
+ lines.push("## Tools");
2861
+ lines.push("");
2862
+ const toolsByCategory = {};
2863
+ for (const tool of data.tools) {
2864
+ const cat = tool.category;
2865
+ if (!toolsByCategory[cat])
2866
+ toolsByCategory[cat] = [];
2867
+ toolsByCategory[cat].push(tool);
2868
+ }
2869
+ if (Object.keys(toolsByCategory).length === 0) {
2870
+ lines.push("_No tools registered._");
2871
+ } else {
2872
+ lines.push("| Category | Tools | Active |");
2873
+ lines.push("|----------|-------|--------|");
2874
+ for (const [category, tools] of Object.entries(toolsByCategory).sort()) {
2875
+ const active = tools.filter((t) => t.status === "ACTIVE").length;
2876
+ lines.push(`| ${category} | ${tools.length} | ${active} |`);
1815
2877
  }
1816
- lines.push("");
1817
2878
  }
1818
2879
  return {
1819
2880
  mimeType: "text/markdown",
@@ -1824,8 +2885,11 @@ var agentListMarkdownRenderer = {
1824
2885
  };
1825
2886
 
1826
2887
  // src/ui/renderers/run-list.markdown.ts
1827
- import { mockListRunsHandler } from "@contractspec/example.agent-console/handlers";
1828
- function formatDuration2(ms) {
2888
+ import {
2889
+ AGENT_CONSOLE_DEMO_PROJECT_ID as AGENT_CONSOLE_DEMO_PROJECT_ID3,
2890
+ createAgentConsoleDemoHandlers as createAgentConsoleDemoHandlers2
2891
+ } from "@contractspec/example.agent-console/shared";
2892
+ function formatDuration3(ms) {
1829
2893
  if (ms < 1000)
1830
2894
  return `${ms}ms`;
1831
2895
  if (ms < 60000)
@@ -1834,12 +2898,14 @@ function formatDuration2(ms) {
1834
2898
  }
1835
2899
  var runListMarkdownRenderer = {
1836
2900
  target: "markdown",
1837
- render: async (desc) => {
2901
+ render: async (desc, ctx) => {
1838
2902
  if (desc.source.type !== "component" || desc.source.componentKey !== "RunListView") {
1839
2903
  throw new Error("runListMarkdownRenderer: not RunListView");
1840
2904
  }
1841
- const data = await mockListRunsHandler({
1842
- organizationId: "demo-org",
2905
+ const data = Array.isArray(ctx?.data) ? { items: ctx.data, total: ctx.data.length, hasMore: false } : await createAgentConsoleDemoHandlers2({
2906
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID3
2907
+ }).listRuns({
2908
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID3,
1843
2909
  limit: 20,
1844
2910
  offset: 0
1845
2911
  });
@@ -1856,7 +2922,7 @@ var runListMarkdownRenderer = {
1856
2922
  "| --- | --- | --- | --- | --- | --- |"
1857
2923
  ];
1858
2924
  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) ?? "-"} |`);
2925
+ lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration3(run.durationMs) : "-"} | ${run.totalTokens} | $${run.estimatedCostUsd?.toFixed(4) ?? "-"} |`);
1860
2926
  }
1861
2927
  return {
1862
2928
  mimeType: "text/markdown",
@@ -1867,15 +2933,26 @@ var runListMarkdownRenderer = {
1867
2933
  };
1868
2934
 
1869
2935
  // src/ui/renderers/tool-registry.markdown.ts
1870
- import { mockListToolsHandler } from "@contractspec/example.agent-console/handlers";
2936
+ import {
2937
+ AGENT_CONSOLE_DEMO_ORGANIZATION_ID as AGENT_CONSOLE_DEMO_ORGANIZATION_ID3,
2938
+ AGENT_CONSOLE_DEMO_PROJECT_ID as AGENT_CONSOLE_DEMO_PROJECT_ID4,
2939
+ createAgentConsoleDemoHandlers as createAgentConsoleDemoHandlers3
2940
+ } from "@contractspec/example.agent-console/shared";
1871
2941
  var toolRegistryMarkdownRenderer = {
1872
2942
  target: "markdown",
1873
- render: async (desc) => {
2943
+ render: async (desc, ctx) => {
1874
2944
  if (desc.source.type !== "component" || desc.source.componentKey !== "ToolRegistryView") {
1875
2945
  throw new Error("toolRegistryMarkdownRenderer: not ToolRegistryView");
1876
2946
  }
1877
- const data = await mockListToolsHandler({
1878
- organizationId: "demo-org",
2947
+ const data = Array.isArray(ctx?.data) ? {
2948
+ items: ctx.data,
2949
+ total: ctx.data.length,
2950
+ hasMore: false
2951
+ } : await createAgentConsoleDemoHandlers3({
2952
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID4
2953
+ }).listTools({
2954
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID4,
2955
+ organizationId: AGENT_CONSOLE_DEMO_ORGANIZATION_ID3,
1879
2956
  limit: 50,
1880
2957
  offset: 0
1881
2958
  });
@@ -1916,180 +2993,6 @@ var toolRegistryMarkdownRenderer = {
1916
2993
  };
1917
2994
  }
1918
2995
  };
1919
-
1920
- // src/ui/renderers/dashboard.markdown.ts
1921
- import {
1922
- mockListAgentsHandler as mockListAgentsHandler2,
1923
- mockListRunsHandler as mockListRunsHandler2,
1924
- mockListToolsHandler as mockListToolsHandler2
1925
- } from "@contractspec/example.agent-console/handlers";
1926
- function formatDuration3(ms) {
1927
- if (ms < 1000)
1928
- return `${ms}ms`;
1929
- if (ms < 60000)
1930
- return `${(ms / 1000).toFixed(1)}s`;
1931
- return `${(ms / 60000).toFixed(1)}m`;
1932
- }
1933
- var agentDashboardMarkdownRenderer = {
1934
- target: "markdown",
1935
- render: async (desc) => {
1936
- if (desc.source.type !== "component" || desc.source.componentKey !== "AgentConsoleDashboard") {
1937
- throw new Error("agentDashboardMarkdownRenderer: not AgentConsoleDashboard");
1938
- }
1939
- const [agentsData, runsData, toolsData] = await Promise.all([
1940
- mockListAgentsHandler2({
1941
- organizationId: "demo-org",
1942
- limit: 100
1943
- }),
1944
- mockListRunsHandler2({
1945
- limit: 100
1946
- }),
1947
- mockListToolsHandler2({
1948
- organizationId: "demo-org",
1949
- limit: 100
1950
- })
1951
- ]);
1952
- const activeAgents = agentsData.items.filter((a) => a.status === "ACTIVE").length;
1953
- const completedRuns = runsData.items.filter((r) => r.status === "COMPLETED").length;
1954
- const failedRuns = runsData.items.filter((r) => r.status === "FAILED").length;
1955
- const totalTokens = runsData.items.reduce((sum, r) => sum + (r.totalTokens ?? 0), 0);
1956
- const totalCost = runsData.items.reduce((sum, r) => sum + (r.estimatedCostUsd ?? 0), 0);
1957
- const activeTools = toolsData.items.filter((t) => t.status === "ACTIVE").length;
1958
- const lines = [
1959
- "# Agent Console Dashboard",
1960
- "",
1961
- "> AI agent operations overview",
1962
- "",
1963
- "## Summary",
1964
- "",
1965
- "| Metric | Value |",
1966
- "|--------|-------|",
1967
- `| Total Agents | ${agentsData.total} |`,
1968
- `| Active Agents | ${activeAgents} |`,
1969
- `| Total Runs | ${runsData.total} |`,
1970
- `| Completed Runs | ${completedRuns} |`,
1971
- `| Failed Runs | ${failedRuns} |`,
1972
- `| Total Tokens | ${totalTokens.toLocaleString()} |`,
1973
- `| Total Cost | $${totalCost.toFixed(4)} |`,
1974
- `| Total Tools | ${toolsData.total} |`,
1975
- `| Active Tools | ${activeTools} |`,
1976
- "",
1977
- "## Agents",
1978
- ""
1979
- ];
1980
- if (agentsData.items.length === 0) {
1981
- lines.push("_No agents configured._");
1982
- } else {
1983
- lines.push("| Agent | Model | Status | Description |");
1984
- lines.push("|-------|-------|--------|-------------|");
1985
- for (const agent of agentsData.items.slice(0, 5)) {
1986
- lines.push(`| ${agent.name} | ${agent.modelProvider}/${agent.modelName} | ${agent.status} | ${agent.description ?? "-"} |`);
1987
- }
1988
- if (agentsData.items.length > 5) {
1989
- lines.push(`| ... | ... | ... | _${agentsData.total - 5} more_ |`);
1990
- }
1991
- }
1992
- lines.push("");
1993
- lines.push("## Recent Runs");
1994
- lines.push("");
1995
- if (runsData.items.length === 0) {
1996
- lines.push("_No runs yet._");
1997
- } else {
1998
- lines.push("| Run ID | Agent | Status | Duration | Tokens | Cost |");
1999
- lines.push("|--------|-------|--------|----------|--------|------|");
2000
- for (const run of runsData.items.slice(0, 5)) {
2001
- lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration3(run.durationMs) : "-"} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`);
2002
- }
2003
- if (runsData.items.length > 5) {
2004
- lines.push(`| ... | ... | ... | ... | ... | _${runsData.total - 5} more_ |`);
2005
- }
2006
- }
2007
- lines.push("");
2008
- lines.push("## Tools");
2009
- lines.push("");
2010
- const toolsByCategory = {};
2011
- for (const tool of toolsData.items) {
2012
- const cat = tool.category;
2013
- if (!toolsByCategory[cat])
2014
- toolsByCategory[cat] = [];
2015
- toolsByCategory[cat].push(tool);
2016
- }
2017
- if (Object.keys(toolsByCategory).length === 0) {
2018
- lines.push("_No tools registered._");
2019
- } else {
2020
- lines.push("| Category | Tools | Active |");
2021
- lines.push("|----------|-------|--------|");
2022
- for (const [category, tools] of Object.entries(toolsByCategory).sort()) {
2023
- const active = tools.filter((t) => t.status === "ACTIVE").length;
2024
- lines.push(`| ${category} | ${tools.length} | ${active} |`);
2025
- }
2026
- }
2027
- return {
2028
- mimeType: "text/markdown",
2029
- body: lines.join(`
2030
- `)
2031
- };
2032
- }
2033
- };
2034
- // src/ui/overlays/demo-overlays.ts
2035
- var agentConsoleDemoOverlay = {
2036
- overlayId: "agent-console.demo-user",
2037
- version: "1.0.0",
2038
- description: "Simplifies agent console for demo users",
2039
- appliesTo: {
2040
- feature: "agent-console",
2041
- role: "demo"
2042
- },
2043
- modifications: [
2044
- {
2045
- type: "hideField",
2046
- field: "modelConfig",
2047
- reason: "Advanced config not relevant for demo"
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"
2064
- }
2065
- ]
2066
- };
2067
- var agentConsoleReadOnlyOverlay = {
2068
- overlayId: "agent-console.read-only",
2069
- version: "1.0.0",
2070
- description: "Read-only view for non-admin users",
2071
- appliesTo: {
2072
- feature: "agent-console",
2073
- role: "viewer"
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"
2086
- }
2087
- ]
2088
- };
2089
- var agentConsoleOverlays = [
2090
- agentConsoleDemoOverlay,
2091
- agentConsoleReadOnlyOverlay
2092
- ];
2093
2996
  export {
2094
2997
  useToolList,
2095
2998
  useRunList,