@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,151 +1,350 @@
1
1
  // @bun
2
- // src/ui/hooks/useRunList.ts
3
- import { useCallback, useEffect, useState } from "react";
2
+ // src/shared/mock-agents.ts
3
+ var MOCK_AGENTS = [
4
+ {
5
+ id: "agent-1",
6
+ organizationId: "demo-org",
7
+ name: "Customer Support Bot",
8
+ slug: "customer-support-bot",
9
+ description: "Handles tier-1 customer inquiries and routes complex issues.",
10
+ status: "ACTIVE",
11
+ modelProvider: "OPENAI",
12
+ modelName: "gpt-4o-mini",
13
+ modelConfig: { temperature: 0.7 },
14
+ systemPrompt: "You are a helpful customer support assistant.",
15
+ toolChoice: "auto",
16
+ maxIterations: 10,
17
+ timeoutMs: 120000,
18
+ version: "1.0.0",
19
+ tags: ["support", "tier-1"],
20
+ createdAt: new Date("2024-01-15T10:00:00Z"),
21
+ updatedAt: new Date("2024-03-20T14:30:00Z")
22
+ },
23
+ {
24
+ id: "agent-2",
25
+ organizationId: "demo-org",
26
+ name: "Code Review Assistant",
27
+ slug: "code-review-assistant",
28
+ description: "Reviews pull requests and provides actionable feedback.",
29
+ status: "ACTIVE",
30
+ modelProvider: "ANTHROPIC",
31
+ modelName: "claude-sonnet-4-20250514",
32
+ modelConfig: { temperature: 0.3 },
33
+ systemPrompt: "You are a code review expert.",
34
+ toolChoice: "auto",
35
+ maxIterations: 15,
36
+ timeoutMs: 180000,
37
+ version: "2.1.0",
38
+ tags: ["code", "review", "dev"],
39
+ createdAt: new Date("2024-02-10T09:00:00Z"),
40
+ updatedAt: new Date("2024-04-05T11:15:00Z")
41
+ },
42
+ {
43
+ id: "agent-3",
44
+ organizationId: "demo-org",
45
+ name: "Data Analyst",
46
+ slug: "data-analyst",
47
+ description: "Queries databases and generates insights from data.",
48
+ status: "PAUSED",
49
+ modelProvider: "OPENAI",
50
+ modelName: "gpt-4o",
51
+ modelConfig: { temperature: 0.5 },
52
+ systemPrompt: "You are a data analyst expert in SQL and analytics.",
53
+ toolChoice: "required",
54
+ maxIterations: 20,
55
+ timeoutMs: 300000,
56
+ version: "1.2.0",
57
+ tags: ["data", "analytics", "sql"],
58
+ createdAt: new Date("2024-03-01T08:00:00Z"),
59
+ updatedAt: new Date("2024-04-10T16:45:00Z")
60
+ },
61
+ {
62
+ id: "agent-4",
63
+ organizationId: "demo-org",
64
+ name: "Meeting Scheduler",
65
+ slug: "meeting-scheduler",
66
+ description: "Schedules meetings and manages calendar conflicts.",
67
+ status: "DRAFT",
68
+ modelProvider: "GOOGLE",
69
+ modelName: "gemini-2.0-flash",
70
+ modelConfig: { temperature: 0.2 },
71
+ systemPrompt: "You help schedule and organize meetings efficiently.",
72
+ toolChoice: "auto",
73
+ maxIterations: 5,
74
+ timeoutMs: 60000,
75
+ version: "0.1.0",
76
+ tags: ["calendar", "scheduling"],
77
+ createdAt: new Date("2024-04-01T12:00:00Z"),
78
+ updatedAt: new Date("2024-04-01T12:00:00Z")
79
+ }
80
+ ];
81
+
82
+ // src/shared/mock-tools.ts
83
+ var MOCK_TOOLS = [
84
+ {
85
+ id: "tool-1",
86
+ organizationId: "demo-org",
87
+ name: "Web Search",
88
+ slug: "web-search",
89
+ description: "Search the web for real-time information using Brave API.",
90
+ category: "RETRIEVAL",
91
+ status: "ACTIVE",
92
+ parametersSchema: {
93
+ type: "object",
94
+ properties: {
95
+ query: { type: "string", description: "Search query" },
96
+ numResults: { type: "number", default: 10 }
97
+ },
98
+ required: ["query"]
99
+ },
100
+ outputSchema: { type: "array", items: { type: "object" } },
101
+ implementationType: "http",
102
+ implementationConfig: {
103
+ url: "https://api.brave.com/search",
104
+ method: "GET"
105
+ },
106
+ maxInvocationsPerMinute: 60,
107
+ timeoutMs: 30000,
108
+ version: "1.0.0",
109
+ tags: ["search", "web"],
110
+ createdAt: new Date("2024-01-01T00:00:00Z"),
111
+ updatedAt: new Date("2024-02-15T10:00:00Z")
112
+ },
113
+ {
114
+ id: "tool-2",
115
+ organizationId: "demo-org",
116
+ name: "SQL Query",
117
+ slug: "sql-query",
118
+ description: "Execute read-only SQL queries against the data warehouse.",
119
+ category: "RETRIEVAL",
120
+ status: "ACTIVE",
121
+ parametersSchema: {
122
+ type: "object",
123
+ properties: {
124
+ query: { type: "string", description: "SQL query" },
125
+ maxRows: { type: "number", default: 100 }
126
+ },
127
+ required: ["query"]
128
+ },
129
+ outputSchema: { type: "object" },
130
+ implementationType: "function",
131
+ implementationConfig: { handler: "executeSqlQuery" },
132
+ maxInvocationsPerMinute: 30,
133
+ timeoutMs: 60000,
134
+ version: "1.1.0",
135
+ tags: ["sql", "database"],
136
+ createdAt: new Date("2024-01-05T00:00:00Z"),
137
+ updatedAt: new Date("2024-03-10T14:00:00Z")
138
+ },
139
+ {
140
+ id: "tool-3",
141
+ organizationId: "demo-org",
142
+ name: "Email Sender",
143
+ slug: "email-sender",
144
+ description: "Send emails via SMTP or API.",
145
+ category: "COMMUNICATION",
146
+ status: "ACTIVE",
147
+ parametersSchema: {
148
+ type: "object",
149
+ properties: {
150
+ to: { type: "string" },
151
+ subject: { type: "string" },
152
+ body: { type: "string" }
153
+ },
154
+ required: ["to", "subject", "body"]
155
+ },
156
+ implementationType: "http",
157
+ implementationConfig: { url: "/api/send-email", method: "POST" },
158
+ maxInvocationsPerMinute: 10,
159
+ timeoutMs: 30000,
160
+ version: "1.0.0",
161
+ tags: ["email", "communication"],
162
+ createdAt: new Date("2024-02-01T00:00:00Z"),
163
+ updatedAt: new Date("2024-02-01T00:00:00Z")
164
+ },
165
+ {
166
+ id: "tool-4",
167
+ organizationId: "demo-org",
168
+ name: "GitHub Integration",
169
+ slug: "github-integration",
170
+ description: "Interact with GitHub repositories, PRs, and issues.",
171
+ category: "INTEGRATION",
172
+ status: "ACTIVE",
173
+ parametersSchema: {
174
+ type: "object",
175
+ properties: {
176
+ action: {
177
+ type: "string",
178
+ enum: ["list_prs", "get_pr", "create_comment"]
179
+ },
180
+ repo: { type: "string" },
181
+ params: { type: "object" }
182
+ },
183
+ required: ["action", "repo"]
184
+ },
185
+ implementationType: "http",
186
+ implementationConfig: { url: "https://api.github.com", auth: "token" },
187
+ maxInvocationsPerMinute: 100,
188
+ timeoutMs: 15000,
189
+ version: "2.0.0",
190
+ tags: ["github", "integration", "code"],
191
+ createdAt: new Date("2024-02-20T00:00:00Z"),
192
+ updatedAt: new Date("2024-04-01T09:00:00Z")
193
+ },
194
+ {
195
+ id: "tool-5",
196
+ organizationId: "demo-org",
197
+ name: "Calculator",
198
+ slug: "calculator",
199
+ description: "Perform mathematical calculations.",
200
+ category: "COMPUTATION",
201
+ status: "ACTIVE",
202
+ parametersSchema: {
203
+ type: "object",
204
+ properties: {
205
+ expression: {
206
+ type: "string",
207
+ description: "Math expression to evaluate"
208
+ }
209
+ },
210
+ required: ["expression"]
211
+ },
212
+ outputSchema: {
213
+ type: "object",
214
+ properties: { result: { type: "number" } }
215
+ },
216
+ implementationType: "function",
217
+ implementationConfig: { handler: "evaluateMath" },
218
+ timeoutMs: 5000,
219
+ version: "1.0.0",
220
+ tags: ["math", "utility"],
221
+ createdAt: new Date("2024-01-10T00:00:00Z"),
222
+ updatedAt: new Date("2024-01-10T00:00:00Z")
223
+ }
224
+ ];
225
+
226
+ // src/shared/mock-runs.ts
227
+ var MOCK_RUNS = [
228
+ {
229
+ id: "run-1",
230
+ organizationId: "demo-org",
231
+ projectId: "demo-project",
232
+ agentId: "agent-1",
233
+ agentName: "Customer Support Bot",
234
+ userId: "user-1",
235
+ sessionId: "session-1",
236
+ input: { message: "How do I reset my password?", context: {} },
237
+ output: { response: "You can reset your password by clicking..." },
238
+ status: "COMPLETED",
239
+ totalTokens: 1250,
240
+ promptTokens: 800,
241
+ completionTokens: 450,
242
+ totalIterations: 3,
243
+ durationMs: 4500,
244
+ estimatedCostUsd: 0.0025,
245
+ queuedAt: new Date("2024-04-15T10:00:00Z"),
246
+ startedAt: new Date("2024-04-15T10:00:01Z"),
247
+ completedAt: new Date("2024-04-15T10:00:05Z"),
248
+ steps: [],
249
+ logs: []
250
+ },
251
+ {
252
+ id: "run-2",
253
+ organizationId: "demo-org",
254
+ projectId: "demo-project",
255
+ agentId: "agent-2",
256
+ agentName: "Code Review Assistant",
257
+ userId: "user-2",
258
+ input: { message: "Review PR #123", context: { prNumber: 123 } },
259
+ status: "IN_PROGRESS",
260
+ totalTokens: 3500,
261
+ promptTokens: 3000,
262
+ completionTokens: 500,
263
+ totalIterations: 5,
264
+ queuedAt: new Date("2024-04-15T10:30:00Z"),
265
+ startedAt: new Date("2024-04-15T10:30:02Z"),
266
+ steps: [],
267
+ logs: []
268
+ },
269
+ {
270
+ id: "run-3",
271
+ organizationId: "demo-org",
272
+ projectId: "demo-project",
273
+ agentId: "agent-1",
274
+ agentName: "Customer Support Bot",
275
+ userId: "user-1",
276
+ input: { message: "What are your business hours?" },
277
+ output: { response: "Our business hours are 9 AM to 5 PM EST..." },
278
+ status: "COMPLETED",
279
+ totalTokens: 800,
280
+ promptTokens: 500,
281
+ completionTokens: 300,
282
+ totalIterations: 2,
283
+ durationMs: 2100,
284
+ estimatedCostUsd: 0.0012,
285
+ queuedAt: new Date("2024-04-15T09:00:00Z"),
286
+ startedAt: new Date("2024-04-15T09:00:01Z"),
287
+ completedAt: new Date("2024-04-15T09:00:03Z"),
288
+ steps: [],
289
+ logs: []
290
+ },
291
+ {
292
+ id: "run-4",
293
+ organizationId: "demo-org",
294
+ projectId: "demo-project",
295
+ agentId: "agent-3",
296
+ agentName: "Data Analyst",
297
+ userId: "user-3",
298
+ input: { message: "Generate sales report for Q1" },
299
+ status: "FAILED",
300
+ errorMessage: "Database connection timeout",
301
+ errorCode: "DB_TIMEOUT",
302
+ totalTokens: 2000,
303
+ promptTokens: 1500,
304
+ completionTokens: 500,
305
+ totalIterations: 8,
306
+ durationMs: 45000,
307
+ queuedAt: new Date("2024-04-14T15:00:00Z"),
308
+ startedAt: new Date("2024-04-14T15:00:05Z"),
309
+ completedAt: new Date("2024-04-14T15:00:50Z"),
310
+ steps: [],
311
+ logs: []
312
+ },
313
+ {
314
+ id: "run-5",
315
+ organizationId: "demo-org",
316
+ projectId: "demo-project",
317
+ agentId: "agent-2",
318
+ agentName: "Code Review Assistant",
319
+ userId: "user-2",
320
+ input: { message: "Review PR #120" },
321
+ output: { response: "Code review complete. 3 suggestions..." },
322
+ status: "COMPLETED",
323
+ totalTokens: 5200,
324
+ promptTokens: 4000,
325
+ completionTokens: 1200,
326
+ totalIterations: 7,
327
+ durationMs: 15000,
328
+ estimatedCostUsd: 0.0156,
329
+ queuedAt: new Date("2024-04-14T11:00:00Z"),
330
+ startedAt: new Date("2024-04-14T11:00:03Z"),
331
+ completedAt: new Date("2024-04-14T11:00:18Z"),
332
+ steps: [],
333
+ logs: []
334
+ }
335
+ ];
336
+
337
+ // src/ui/hooks/useAgentList.ts
4
338
  import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
5
- function useRunList(options = {}) {
339
+ import { useCallback, useEffect, useMemo, useState } from "react";
340
+ function useAgentList(options = {}) {
6
341
  const { handlers, projectId } = useTemplateRuntime();
7
342
  const { agent } = handlers;
8
343
  const [data, setData] = useState(null);
9
- const [metrics, setMetrics] = useState(null);
10
344
  const [loading, setLoading] = useState(true);
11
345
  const [error, setError] = useState(null);
12
346
  const [page, setPage] = useState(1);
13
347
  const fetchData = useCallback(async () => {
14
- setLoading(true);
15
- setError(null);
16
- try {
17
- const [runsResult, metricsResult] = await Promise.all([
18
- agent.listRuns({
19
- projectId,
20
- agentId: options.agentId,
21
- status: options.status === "all" ? undefined : options.status,
22
- limit: options.limit ?? 20,
23
- offset: (page - 1) * (options.limit ?? 20)
24
- }),
25
- agent.getRunMetrics({
26
- projectId,
27
- agentId: options.agentId,
28
- startDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
29
- endDate: new Date
30
- })
31
- ]);
32
- setData(runsResult);
33
- setMetrics(metricsResult);
34
- } catch (err) {
35
- setError(err instanceof Error ? err : new Error("Unknown error"));
36
- } finally {
37
- setLoading(false);
38
- }
39
- }, [agent, projectId, options.agentId, options.status, options.limit, page]);
40
- useEffect(() => {
41
- fetchData();
42
- }, [fetchData]);
43
- return {
44
- data,
45
- metrics,
46
- loading,
47
- error,
48
- page,
49
- refetch: fetchData,
50
- nextPage: () => setPage((p) => p + 1),
51
- prevPage: () => page > 1 && setPage((p) => p - 1)
52
- };
53
- }
54
-
55
- // src/ui/hooks/useToolList.ts
56
- import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
57
- import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
58
- function useToolList(options = {}) {
59
- const { handlers, projectId } = useTemplateRuntime2();
60
- const { agent } = handlers;
61
- const [data, setData] = useState2(null);
62
- const [loading, setLoading] = useState2(true);
63
- const [error, setError] = useState2(null);
64
- const [page, setPage] = useState2(1);
65
- const fetchData = useCallback2(async () => {
66
- setLoading(true);
67
- setError(null);
68
- try {
69
- const result = await agent.listTools({
70
- projectId,
71
- search: options.search,
72
- category: options.category,
73
- status: options.status === "all" ? undefined : options.status,
74
- limit: options.limit ?? 50,
75
- offset: (page - 1) * (options.limit ?? 50)
76
- });
77
- setData(result);
78
- } catch (err) {
79
- setError(err instanceof Error ? err : new Error("Unknown error"));
80
- } finally {
81
- setLoading(false);
82
- }
83
- }, [
84
- agent,
85
- projectId,
86
- options.search,
87
- options.category,
88
- options.status,
89
- options.limit,
90
- page
91
- ]);
92
- useEffect2(() => {
93
- fetchData();
94
- }, [fetchData]);
95
- const { stats, groupedByCategory, categoryStats } = useMemo(() => {
96
- if (!data)
97
- return { stats: null, groupedByCategory: {}, categoryStats: [] };
98
- const items = data.items;
99
- const active = items.filter((t) => t.status === "ACTIVE").length;
100
- const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
101
- const disabled = items.filter((t) => t.status === "DISABLED").length;
102
- const grouped = {};
103
- const byCategory = {};
104
- items.forEach((t) => {
105
- const cat = t.category;
106
- if (!grouped[cat])
107
- grouped[cat] = [];
108
- grouped[cat].push(t);
109
- byCategory[cat] = (byCategory[cat] || 0) + 1;
110
- });
111
- const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
112
- return {
113
- stats: {
114
- total: data.total,
115
- active,
116
- deprecated,
117
- disabled,
118
- topCategories: catStats.slice(0, 5)
119
- },
120
- groupedByCategory: grouped,
121
- categoryStats: catStats
122
- };
123
- }, [data]);
124
- return {
125
- data,
126
- loading,
127
- error,
128
- stats,
129
- groupedByCategory,
130
- categoryStats,
131
- page,
132
- refetch: fetchData,
133
- nextPage: () => setPage((p) => p + 1),
134
- prevPage: () => page > 1 && setPage((p) => p - 1)
135
- };
136
- }
137
-
138
- // src/ui/hooks/useAgentList.ts
139
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react";
140
- import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
141
- function useAgentList(options = {}) {
142
- const { handlers, projectId } = useTemplateRuntime3();
143
- const { agent } = handlers;
144
- const [data, setData] = useState3(null);
145
- const [loading, setLoading] = useState3(true);
146
- const [error, setError] = useState3(null);
147
- const [page, setPage] = useState3(1);
148
- const fetchData = useCallback3(async () => {
149
348
  setLoading(true);
150
349
  setError(null);
151
350
  try {
@@ -163,10 +362,10 @@ function useAgentList(options = {}) {
163
362
  setLoading(false);
164
363
  }
165
364
  }, [agent, projectId, options.search, options.status, options.limit, page]);
166
- useEffect3(() => {
365
+ useEffect(() => {
167
366
  fetchData();
168
367
  }, [fetchData]);
169
- const stats = useMemo2(() => {
368
+ const stats = useMemo(() => {
170
369
  if (!data)
171
370
  return null;
172
371
  return {
@@ -189,44 +388,141 @@ function useAgentList(options = {}) {
189
388
  }
190
389
 
191
390
  // src/ui/hooks/useAgentMutations.ts
192
- import { useCallback as useCallback4, useState as useState4 } from "react";
193
- import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
391
+ import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
392
+ import { useCallback as useCallback2, useState as useState2 } from "react";
393
+
394
+ // src/shared/demo-runtime-seed.ts
395
+ var AGENT_CONSOLE_DEMO_ORGANIZATION_ID = "demo-org";
396
+ var AGENT_CONSOLE_DEMO_PROJECT_ID = "agent-console-demo";
397
+ function slugify(name) {
398
+ return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
399
+ }
400
+ function cloneAgent(agent) {
401
+ return { ...agent };
402
+ }
403
+ function cloneTool(tool) {
404
+ return { ...tool };
405
+ }
406
+ function cloneRun(run) {
407
+ return { ...run };
408
+ }
409
+ function createDefaultNow() {
410
+ let tick = 0;
411
+ const base = Date.parse("2026-03-20T09:00:00.000Z");
412
+ return () => new Date(base + tick++ * 60000);
413
+ }
414
+ function normalizeProvider(provider) {
415
+ return provider.toLowerCase();
416
+ }
417
+ function normalizeRunStatus(status) {
418
+ return status === "IN_PROGRESS" ? "RUNNING" : status;
419
+ }
420
+ function createSeedState(projectId, organizationId) {
421
+ const agents = MOCK_AGENTS.map((agent) => ({
422
+ id: agent.id,
423
+ projectId,
424
+ organizationId,
425
+ name: agent.name,
426
+ slug: agent.slug,
427
+ description: agent.description,
428
+ modelProvider: normalizeProvider(agent.modelProvider),
429
+ modelName: agent.modelName,
430
+ systemPrompt: agent.systemPrompt,
431
+ temperature: typeof agent.modelConfig?.temperature === "number" ? agent.modelConfig.temperature : 0.4,
432
+ maxTokens: 8192,
433
+ status: agent.status,
434
+ createdAt: agent.createdAt,
435
+ updatedAt: agent.updatedAt
436
+ }));
437
+ const tools = MOCK_TOOLS.map((tool) => ({
438
+ id: tool.id,
439
+ projectId,
440
+ organizationId,
441
+ name: tool.name,
442
+ description: tool.description,
443
+ version: tool.version,
444
+ category: tool.category,
445
+ status: tool.status,
446
+ inputSchema: JSON.stringify(tool.parametersSchema),
447
+ outputSchema: tool.outputSchema ? JSON.stringify(tool.outputSchema) : undefined,
448
+ endpoint: typeof tool.implementationConfig?.url === "string" ? tool.implementationConfig.url : undefined,
449
+ createdAt: tool.createdAt,
450
+ updatedAt: tool.updatedAt
451
+ }));
452
+ const agentNames = new Map(agents.map((agent) => [agent.id, agent.name]));
453
+ const runs = MOCK_RUNS.map((run) => ({
454
+ id: run.id,
455
+ projectId,
456
+ agentId: run.agentId,
457
+ agentName: agentNames.get(run.agentId) ?? run.agentName ?? "Unknown agent",
458
+ status: normalizeRunStatus(run.status),
459
+ input: JSON.stringify(run.input),
460
+ output: run.output ? JSON.stringify(run.output) : undefined,
461
+ totalTokens: run.totalTokens,
462
+ promptTokens: run.promptTokens,
463
+ completionTokens: run.completionTokens,
464
+ estimatedCostUsd: run.estimatedCostUsd ?? 0,
465
+ durationMs: run.durationMs,
466
+ errorMessage: run.errorMessage,
467
+ queuedAt: run.queuedAt,
468
+ startedAt: run.startedAt,
469
+ completedAt: run.completedAt
470
+ }));
471
+ return { agents, tools, runs };
472
+ }
473
+ function summarizeRunMetrics(runs) {
474
+ const totalRuns = runs.length;
475
+ const completedRuns = runs.filter((run) => run.status === "COMPLETED").length;
476
+ const completedDurations = runs.map((run) => run.durationMs).filter((duration) => typeof duration === "number");
477
+ return {
478
+ totalRuns,
479
+ successRate: totalRuns === 0 ? 0 : completedRuns / totalRuns,
480
+ averageDurationMs: completedDurations.length === 0 ? 0 : Math.round(completedDurations.reduce((sum, duration) => sum + duration, 0) / completedDurations.length),
481
+ totalTokens: runs.reduce((sum, run) => sum + run.totalTokens, 0),
482
+ totalCostUsd: runs.reduce((sum, run) => sum + run.estimatedCostUsd, 0)
483
+ };
484
+ }
485
+
486
+ // src/ui/hooks/useAgentMutations.ts
487
+ function normalizeMutationError(error, fallbackMessage) {
488
+ return error instanceof Error ? error : new Error(fallbackMessage);
489
+ }
194
490
  function useAgentMutations(options = {}) {
195
- const { handlers, projectId } = useTemplateRuntime4();
491
+ const { handlers, projectId } = useTemplateRuntime2();
196
492
  const { agent } = handlers;
197
- const [createState, setCreateState] = useState4({
493
+ const [createState, setCreateState] = useState2({
198
494
  loading: false,
199
495
  error: null,
200
496
  data: null
201
497
  });
202
- const [updateState, setUpdateState] = useState4({
498
+ const [updateState, setUpdateState] = useState2({
203
499
  loading: false,
204
500
  error: null,
205
501
  data: null
206
502
  });
207
- const [executeState, setExecuteState] = useState4({
503
+ const [executeState, setExecuteState] = useState2({
208
504
  loading: false,
209
505
  error: null,
210
506
  data: null
211
507
  });
212
- const createAgent = useCallback4(async (input) => {
508
+ const createAgent = useCallback2(async (input) => {
213
509
  setCreateState({ loading: true, error: null, data: null });
214
510
  try {
215
511
  const result = await agent.createAgent(input, {
216
512
  projectId,
217
- organizationId: "demo-org"
513
+ organizationId: AGENT_CONSOLE_DEMO_ORGANIZATION_ID
218
514
  });
219
515
  setCreateState({ loading: false, error: null, data: result });
220
516
  options.onSuccess?.();
221
517
  return result;
222
518
  } catch (err) {
223
- const error = err instanceof Error ? err : new Error("Failed to create agent");
519
+ const error = normalizeMutationError(err, "Failed to create agent");
224
520
  setCreateState({ loading: false, error, data: null });
225
521
  options.onError?.(error);
226
- return null;
522
+ throw error;
227
523
  }
228
524
  }, [agent, projectId, options]);
229
- const updateAgent = useCallback4(async (input) => {
525
+ const updateAgent = useCallback2(async (input) => {
230
526
  setUpdateState({ loading: true, error: null, data: null });
231
527
  try {
232
528
  const result = await agent.updateAgent(input);
@@ -234,37 +530,40 @@ function useAgentMutations(options = {}) {
234
530
  options.onSuccess?.();
235
531
  return result;
236
532
  } catch (err) {
237
- const error = err instanceof Error ? err : new Error("Failed to update agent");
533
+ const error = normalizeMutationError(err, "Failed to update agent");
238
534
  setUpdateState({ loading: false, error, data: null });
239
535
  options.onError?.(error);
240
- return null;
536
+ throw error;
241
537
  }
242
538
  }, [agent, options]);
243
- const activateAgent = useCallback4(async (agentId) => {
539
+ const activateAgent = useCallback2(async (agentId) => {
244
540
  return updateAgent({ id: agentId, status: "ACTIVE" });
245
541
  }, [updateAgent]);
246
- const pauseAgent = useCallback4(async (agentId) => {
542
+ const pauseAgent = useCallback2(async (agentId) => {
247
543
  return updateAgent({ id: agentId, status: "PAUSED" });
248
544
  }, [updateAgent]);
249
- const archiveAgent = useCallback4(async (agentId) => {
545
+ const archiveAgent = useCallback2(async (agentId) => {
250
546
  return updateAgent({ id: agentId, status: "ARCHIVED" });
251
547
  }, [updateAgent]);
252
- const executeAgent = useCallback4(async (input) => {
548
+ const executeAgent = useCallback2(async (input) => {
253
549
  setExecuteState({ loading: true, error: null, data: null });
254
550
  try {
255
551
  const result = await agent.executeAgent({
256
552
  agentId: input.agentId,
257
553
  message: input.message,
258
- context: { projectId, organizationId: "demo-org" }
554
+ context: {
555
+ projectId,
556
+ organizationId: AGENT_CONSOLE_DEMO_ORGANIZATION_ID
557
+ }
259
558
  });
260
559
  setExecuteState({ loading: false, error: null, data: result });
261
560
  options.onSuccess?.();
262
561
  return result;
263
562
  } catch (err) {
264
- const error = err instanceof Error ? err : new Error("Failed to execute agent");
563
+ const error = normalizeMutationError(err, "Failed to execute agent");
265
564
  setExecuteState({ loading: false, error, data: null });
266
565
  options.onError?.(error);
267
- return null;
566
+ throw error;
268
567
  }
269
568
  }, [agent, projectId, options]);
270
569
  return {
@@ -281,6 +580,157 @@ function useAgentMutations(options = {}) {
281
580
  };
282
581
  }
283
582
 
583
+ // src/ui/hooks/useRunList.ts
584
+ import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
585
+ import { useCallback as useCallback3, useEffect as useEffect2, useState as useState3 } from "react";
586
+ function useRunList(options = {}) {
587
+ const { handlers, projectId } = useTemplateRuntime3();
588
+ const { agent } = handlers;
589
+ const [data, setData] = useState3(null);
590
+ const [metrics, setMetrics] = useState3(null);
591
+ const [loading, setLoading] = useState3(true);
592
+ const [error, setError] = useState3(null);
593
+ const [internalPageIndex, setInternalPageIndex] = useState3(0);
594
+ const pageSize = options.pageSize ?? options.limit ?? 20;
595
+ const pageIndex = options.pageIndex ?? internalPageIndex;
596
+ const [sort] = options.sorting ?? [];
597
+ const fetchData = useCallback3(async () => {
598
+ setLoading(true);
599
+ setError(null);
600
+ try {
601
+ const [runsResult, metricsResult] = await Promise.all([
602
+ agent.listRuns({
603
+ projectId,
604
+ agentId: options.agentId,
605
+ status: options.status === "all" ? undefined : options.status,
606
+ sortBy: sort?.id,
607
+ sortDirection: sort ? sort.desc ? "desc" : "asc" : undefined,
608
+ limit: pageSize,
609
+ offset: pageIndex * pageSize
610
+ }),
611
+ agent.getRunMetrics({
612
+ projectId,
613
+ agentId: options.agentId
614
+ })
615
+ ]);
616
+ setData(runsResult);
617
+ setMetrics(metricsResult);
618
+ } catch (err) {
619
+ setError(err instanceof Error ? err : new Error("Unknown error"));
620
+ } finally {
621
+ setLoading(false);
622
+ }
623
+ }, [
624
+ agent,
625
+ pageIndex,
626
+ pageSize,
627
+ projectId,
628
+ options.agentId,
629
+ options.status,
630
+ sort?.desc,
631
+ sort?.id
632
+ ]);
633
+ useEffect2(() => {
634
+ fetchData();
635
+ }, [fetchData]);
636
+ const hasControlledPagination = options.pageIndex !== undefined;
637
+ return {
638
+ data,
639
+ metrics,
640
+ loading,
641
+ error,
642
+ page: pageIndex + 1,
643
+ pageIndex,
644
+ pageSize,
645
+ refetch: fetchData,
646
+ nextPage: hasControlledPagination ? undefined : () => setInternalPageIndex((current) => current + 1),
647
+ prevPage: hasControlledPagination ? undefined : () => setInternalPageIndex((current) => Math.max(0, current - 1))
648
+ };
649
+ }
650
+
651
+ // src/ui/hooks/useToolList.ts
652
+ import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
653
+ import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo2, useState as useState4 } from "react";
654
+ function useToolList(options = {}) {
655
+ const { handlers, projectId } = useTemplateRuntime4();
656
+ const { agent } = handlers;
657
+ const [data, setData] = useState4(null);
658
+ const [loading, setLoading] = useState4(true);
659
+ const [error, setError] = useState4(null);
660
+ const [page, setPage] = useState4(1);
661
+ const fetchData = useCallback4(async () => {
662
+ setLoading(true);
663
+ setError(null);
664
+ try {
665
+ const result = await agent.listTools({
666
+ projectId,
667
+ search: options.search,
668
+ category: options.category,
669
+ status: options.status === "all" ? undefined : options.status,
670
+ limit: options.limit ?? 50,
671
+ offset: (page - 1) * (options.limit ?? 50)
672
+ });
673
+ setData(result);
674
+ } catch (err) {
675
+ setError(err instanceof Error ? err : new Error("Unknown error"));
676
+ } finally {
677
+ setLoading(false);
678
+ }
679
+ }, [
680
+ agent,
681
+ projectId,
682
+ options.search,
683
+ options.category,
684
+ options.status,
685
+ options.limit,
686
+ page
687
+ ]);
688
+ useEffect3(() => {
689
+ fetchData();
690
+ }, [fetchData]);
691
+ const { stats, groupedByCategory, categoryStats } = useMemo2(() => {
692
+ if (!data)
693
+ return { stats: null, groupedByCategory: {}, categoryStats: [] };
694
+ const items = data.items;
695
+ const active = items.filter((t) => t.status === "ACTIVE").length;
696
+ const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
697
+ const disabled = items.filter((t) => t.status === "DISABLED").length;
698
+ const grouped = {};
699
+ const byCategory = {};
700
+ items.forEach((t) => {
701
+ const cat = t.category;
702
+ if (!grouped[cat])
703
+ grouped[cat] = [];
704
+ grouped[cat].push(t);
705
+ byCategory[cat] = (byCategory[cat] || 0) + 1;
706
+ });
707
+ const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
708
+ return {
709
+ stats: {
710
+ total: data.total,
711
+ active,
712
+ deprecated,
713
+ disabled,
714
+ topCategories: catStats.slice(0, 5)
715
+ },
716
+ groupedByCategory: grouped,
717
+ categoryStats: catStats
718
+ };
719
+ }, [data]);
720
+ return {
721
+ data,
722
+ loading,
723
+ error,
724
+ stats,
725
+ groupedByCategory,
726
+ categoryStats,
727
+ page,
728
+ refetch: fetchData,
729
+ nextPage: () => setPage((p) => p + 1),
730
+ prevPage: () => page > 1 && setPage((p) => p - 1)
731
+ };
732
+ }
733
+
284
734
  // src/ui/hooks/index.ts
285
735
  "use client";
286
736
  export {