@contractspec/example.agent-console 3.7.6 → 3.8.2

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