@contractspec/example.agent-console 1.46.1 → 1.48.0

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 (202) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +275 -128
  2. package/.turbo/turbo-build.log +274 -127
  3. package/CHANGELOG.md +52 -0
  4. package/dist/agent/agent.entity.d.ts +36 -36
  5. package/dist/agent/agent.entity.d.ts.map +1 -1
  6. package/dist/agent/agent.enum.d.ts +4 -4
  7. package/dist/agent/agent.enum.d.ts.map +1 -1
  8. package/dist/agent/agent.event.d.ts +31 -31
  9. package/dist/agent/agent.event.d.ts.map +1 -1
  10. package/dist/agent/agent.event.js +5 -5
  11. package/dist/agent/agent.event.js.map +1 -1
  12. package/dist/agent/agent.handler.js.map +1 -1
  13. package/dist/agent/agent.operation.d.ts +117 -117
  14. package/dist/agent/agent.operation.d.ts.map +1 -1
  15. package/dist/agent/agent.presentation.d.ts +4 -5
  16. package/dist/agent/agent.presentation.d.ts.map +1 -1
  17. package/dist/agent/agent.presentation.js +7 -7
  18. package/dist/agent/agent.presentation.js.map +1 -1
  19. package/dist/agent/agent.schema.d.ts +95 -95
  20. package/dist/agent/agent.schema.d.ts.map +1 -1
  21. package/dist/agent/agent.test-spec.d.ts +8 -0
  22. package/dist/agent/agent.test-spec.d.ts.map +1 -0
  23. package/dist/agent/agent.test-spec.js +65 -0
  24. package/dist/agent/agent.test-spec.js.map +1 -0
  25. package/dist/agent.capability.d.ts +7 -0
  26. package/dist/agent.capability.d.ts.map +1 -0
  27. package/dist/agent.capability.js +20 -0
  28. package/dist/agent.capability.js.map +1 -0
  29. package/dist/agent.feature.d.ts.map +1 -1
  30. package/dist/agent.feature.js +4 -2
  31. package/dist/agent.feature.js.map +1 -1
  32. package/dist/example.d.ts +2 -2
  33. package/dist/example.d.ts.map +1 -1
  34. package/dist/example.js +4 -2
  35. package/dist/example.js.map +1 -1
  36. package/dist/handlers/agent.handlers.d.ts +135 -0
  37. package/dist/handlers/agent.handlers.d.ts.map +1 -0
  38. package/dist/handlers/agent.handlers.js +263 -0
  39. package/dist/handlers/agent.handlers.js.map +1 -0
  40. package/dist/handlers/index.d.ts +2 -1
  41. package/dist/handlers/index.js +2 -1
  42. package/dist/index.d.ts +19 -1
  43. package/dist/index.js +19 -1
  44. package/dist/run/run.entity.d.ts +56 -56
  45. package/dist/run/run.enum.d.ts +5 -5
  46. package/dist/run/run.event.d.ts +71 -71
  47. package/dist/run/run.event.js +8 -8
  48. package/dist/run/run.event.js.map +1 -1
  49. package/dist/run/run.operation.d.ts +175 -175
  50. package/dist/run/run.presentation.d.ts +3 -4
  51. package/dist/run/run.presentation.d.ts.map +1 -1
  52. package/dist/run/run.presentation.js +5 -5
  53. package/dist/run/run.presentation.js.map +1 -1
  54. package/dist/run/run.schema.d.ts +99 -99
  55. package/dist/run/run.test-spec.d.ts +8 -0
  56. package/dist/run/run.test-spec.d.ts.map +1 -0
  57. package/dist/run/run.test-spec.js +65 -0
  58. package/dist/run/run.test-spec.js.map +1 -0
  59. package/dist/seeders/index.d.ts +10 -0
  60. package/dist/seeders/index.d.ts.map +1 -0
  61. package/dist/seeders/index.js +20 -0
  62. package/dist/seeders/index.js.map +1 -0
  63. package/dist/shared/overlay-types.d.ts +34 -0
  64. package/dist/shared/overlay-types.d.ts.map +1 -0
  65. package/dist/shared/overlay-types.js +0 -0
  66. package/dist/tool/tool.entity.d.ts +24 -24
  67. package/dist/tool/tool.enum.d.ts +4 -4
  68. package/dist/tool/tool.event.d.ts +25 -25
  69. package/dist/tool/tool.event.js +4 -4
  70. package/dist/tool/tool.event.js.map +1 -1
  71. package/dist/tool/tool.handler.d.ts.map +1 -1
  72. package/dist/tool/tool.operation.d.ts +101 -101
  73. package/dist/tool/tool.presentation.d.ts +3 -4
  74. package/dist/tool/tool.presentation.d.ts.map +1 -1
  75. package/dist/tool/tool.presentation.js +5 -5
  76. package/dist/tool/tool.presentation.js.map +1 -1
  77. package/dist/tool/tool.schema.d.ts +52 -52
  78. package/dist/tool/tool.schema.d.ts.map +1 -1
  79. package/dist/tool/tool.test-spec.d.ts +8 -0
  80. package/dist/tool/tool.test-spec.d.ts.map +1 -0
  81. package/dist/tool/tool.test-spec.js +65 -0
  82. package/dist/tool/tool.test-spec.js.map +1 -0
  83. package/dist/ui/AgentDashboard.d.ts +7 -0
  84. package/dist/ui/AgentDashboard.d.ts.map +1 -0
  85. package/dist/ui/AgentDashboard.js +420 -0
  86. package/dist/ui/AgentDashboard.js.map +1 -0
  87. package/dist/ui/AgentRunList.d.ts +2 -0
  88. package/dist/ui/AgentRunList.js +5 -0
  89. package/dist/ui/AgentToolRegistry.d.ts +2 -0
  90. package/dist/ui/AgentToolRegistry.js +5 -0
  91. package/dist/ui/hooks/index.d.ts +6 -0
  92. package/dist/ui/hooks/index.js +8 -0
  93. package/dist/ui/hooks/useAgentList.d.ts +28 -0
  94. package/dist/ui/hooks/useAgentList.d.ts.map +1 -0
  95. package/dist/ui/hooks/useAgentList.js +66 -0
  96. package/dist/ui/hooks/useAgentList.js.map +1 -0
  97. package/dist/ui/hooks/useAgentMutations.d.ts +29 -0
  98. package/dist/ui/hooks/useAgentMutations.d.ts.map +1 -0
  99. package/dist/ui/hooks/useAgentMutations.js +124 -0
  100. package/dist/ui/hooks/useAgentMutations.js.map +1 -0
  101. package/dist/ui/hooks/useRunList.d.ts +24 -0
  102. package/dist/ui/hooks/useRunList.d.ts.map +1 -0
  103. package/dist/ui/hooks/useRunList.js +66 -0
  104. package/dist/ui/hooks/useRunList.js.map +1 -0
  105. package/dist/ui/hooks/useToolList.d.ts +40 -0
  106. package/dist/ui/hooks/useToolList.d.ts.map +1 -0
  107. package/dist/ui/hooks/useToolList.js +96 -0
  108. package/dist/ui/hooks/useToolList.js.map +1 -0
  109. package/dist/ui/index.d.ts +24 -0
  110. package/dist/ui/index.js +24 -0
  111. package/dist/ui/modals/AgentActionsModal.d.ts +27 -0
  112. package/dist/ui/modals/AgentActionsModal.d.ts.map +1 -0
  113. package/dist/ui/modals/AgentActionsModal.js +262 -0
  114. package/dist/ui/modals/AgentActionsModal.js.map +1 -0
  115. package/dist/ui/modals/CreateAgentModal.d.ts +25 -0
  116. package/dist/ui/modals/CreateAgentModal.d.ts.map +1 -0
  117. package/dist/ui/modals/CreateAgentModal.js +214 -0
  118. package/dist/ui/modals/CreateAgentModal.js.map +1 -0
  119. package/dist/ui/modals/index.d.ts +3 -0
  120. package/dist/ui/modals/index.js +4 -0
  121. package/dist/ui/overlays/demo-overlays.d.ts +19 -0
  122. package/dist/ui/overlays/demo-overlays.d.ts.map +1 -0
  123. package/dist/ui/overlays/demo-overlays.js +73 -0
  124. package/dist/ui/overlays/demo-overlays.js.map +1 -0
  125. package/dist/ui/overlays/index.d.ts +2 -0
  126. package/dist/ui/overlays/index.js +3 -0
  127. package/dist/ui/renderers/agent-list.markdown.d.ts +15 -0
  128. package/dist/ui/renderers/agent-list.markdown.d.ts.map +1 -0
  129. package/dist/ui/renderers/agent-list.markdown.js +51 -0
  130. package/dist/ui/renderers/agent-list.markdown.js.map +1 -0
  131. package/dist/ui/renderers/agent-list.renderer.d.ts +11 -0
  132. package/dist/ui/renderers/agent-list.renderer.d.ts.map +1 -0
  133. package/dist/ui/renderers/agent-list.renderer.js +19 -0
  134. package/dist/ui/renderers/agent-list.renderer.js.map +1 -0
  135. package/dist/ui/renderers/dashboard.markdown.d.ts +15 -0
  136. package/dist/ui/renderers/dashboard.markdown.d.ts.map +1 -0
  137. package/dist/ui/renderers/dashboard.markdown.js +100 -0
  138. package/dist/ui/renderers/dashboard.markdown.js.map +1 -0
  139. package/dist/ui/renderers/index.d.ts +6 -0
  140. package/dist/ui/renderers/index.js +7 -0
  141. package/dist/ui/renderers/run-list.markdown.d.ts +15 -0
  142. package/dist/ui/renderers/run-list.markdown.d.ts.map +1 -0
  143. package/dist/ui/renderers/run-list.markdown.js +44 -0
  144. package/dist/ui/renderers/run-list.markdown.js.map +1 -0
  145. package/dist/ui/renderers/tool-registry.markdown.d.ts +15 -0
  146. package/dist/ui/renderers/tool-registry.markdown.d.ts.map +1 -0
  147. package/dist/ui/renderers/tool-registry.markdown.js +55 -0
  148. package/dist/ui/renderers/tool-registry.markdown.js.map +1 -0
  149. package/dist/ui/views/AgentListView.d.ts +7 -0
  150. package/dist/ui/views/AgentListView.d.ts.map +1 -0
  151. package/dist/ui/views/AgentListView.js +93 -0
  152. package/dist/ui/views/AgentListView.js.map +1 -0
  153. package/dist/ui/views/RunListView.d.ts +14 -0
  154. package/dist/ui/views/RunListView.d.ts.map +1 -0
  155. package/dist/ui/views/RunListView.js +165 -0
  156. package/dist/ui/views/RunListView.js.map +1 -0
  157. package/dist/ui/views/ToolRegistryView.d.ts +14 -0
  158. package/dist/ui/views/ToolRegistryView.d.ts.map +1 -0
  159. package/dist/ui/views/ToolRegistryView.js +97 -0
  160. package/dist/ui/views/ToolRegistryView.js.map +1 -0
  161. package/dist/ui/views/index.d.ts +4 -0
  162. package/dist/ui/views/index.js +5 -0
  163. package/package.json +46 -10
  164. package/src/agent/agent.presentation.ts +7 -8
  165. package/src/agent/agent.test-spec.ts +55 -0
  166. package/src/agent.capability.ts +13 -0
  167. package/src/agent.feature.ts +3 -2
  168. package/src/example.ts +3 -3
  169. package/src/handlers/agent.handlers.ts +572 -0
  170. package/src/handlers/index.ts +3 -0
  171. package/src/index.ts +5 -0
  172. package/src/run/run.presentation.ts +5 -6
  173. package/src/run/run.test-spec.ts +55 -0
  174. package/src/seeders/index.ts +29 -0
  175. package/src/shared/overlay-types.ts +39 -0
  176. package/src/tool/tool.presentation.ts +5 -6
  177. package/src/tool/tool.test-spec.ts +55 -0
  178. package/src/ui/AgentDashboard.tsx +416 -0
  179. package/src/ui/AgentRunList.tsx +8 -0
  180. package/src/ui/AgentToolRegistry.tsx +8 -0
  181. package/src/ui/hooks/index.ts +14 -0
  182. package/src/ui/hooks/useAgentList.ts +80 -0
  183. package/src/ui/hooks/useAgentMutations.ts +156 -0
  184. package/src/ui/hooks/useRunList.ts +81 -0
  185. package/src/ui/hooks/useToolList.ts +122 -0
  186. package/src/ui/index.ts +21 -0
  187. package/src/ui/modals/AgentActionsModal.tsx +306 -0
  188. package/src/ui/modals/CreateAgentModal.tsx +257 -0
  189. package/src/ui/modals/index.ts +2 -0
  190. package/src/ui/overlays/demo-overlays.ts +77 -0
  191. package/src/ui/overlays/index.ts +1 -0
  192. package/src/ui/renderers/agent-list.markdown.ts +84 -0
  193. package/src/ui/renderers/agent-list.renderer.tsx +27 -0
  194. package/src/ui/renderers/dashboard.markdown.ts +169 -0
  195. package/src/ui/renderers/index.ts +12 -0
  196. package/src/ui/renderers/run-list.markdown.ts +75 -0
  197. package/src/ui/renderers/tool-registry.markdown.ts +91 -0
  198. package/src/ui/views/AgentListView.tsx +113 -0
  199. package/src/ui/views/RunListView.tsx +173 -0
  200. package/src/ui/views/ToolRegistryView.tsx +140 -0
  201. package/src/ui/views/index.ts +6 -0
  202. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,262 @@
1
+ 'use client';
2
+
3
+ import { useState } from "react";
4
+ import { Button } from "@contractspec/lib.design-system";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+
7
+ //#region src/ui/modals/AgentActionsModal.tsx
8
+ /**
9
+ * AgentActionsModal - Actions for a specific agent
10
+ *
11
+ * Wires to UpdateAgentCommand via useAgentMutations hook.
12
+ */
13
+ function getStatusColor(status) {
14
+ switch (status) {
15
+ case "ACTIVE": return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
16
+ case "DRAFT": return "text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30";
17
+ case "PAUSED": return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
18
+ case "ARCHIVED": return "text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700";
19
+ default: return "text-gray-600 bg-gray-100";
20
+ }
21
+ }
22
+ function AgentActionsModal({ isOpen, agent, onClose, onActivate, onPause, onArchive, onExecute, isLoading = false }) {
23
+ const [mode, setMode] = useState("menu");
24
+ const [message, setMessage] = useState("");
25
+ const [confirmAction, setConfirmAction] = useState(null);
26
+ const [error, setError] = useState(null);
27
+ const resetForm = () => {
28
+ setMode("menu");
29
+ setMessage("");
30
+ setConfirmAction(null);
31
+ setError(null);
32
+ };
33
+ const handleClose = () => {
34
+ resetForm();
35
+ onClose();
36
+ };
37
+ const handleExecute = async () => {
38
+ if (!agent) return;
39
+ setError(null);
40
+ if (!message.trim()) {
41
+ setError("Please enter a message");
42
+ return;
43
+ }
44
+ try {
45
+ await onExecute(agent.id, message.trim());
46
+ handleClose();
47
+ } catch (err) {
48
+ setError(err instanceof Error ? err.message : "Failed to execute agent");
49
+ }
50
+ };
51
+ const handleStatusChange = async (action) => {
52
+ if (!agent) return;
53
+ setError(null);
54
+ try {
55
+ switch (action) {
56
+ case "activate":
57
+ await onActivate(agent.id);
58
+ break;
59
+ case "pause":
60
+ await onPause(agent.id);
61
+ break;
62
+ case "archive":
63
+ await onArchive(agent.id);
64
+ break;
65
+ }
66
+ handleClose();
67
+ } catch (err) {
68
+ setError(err instanceof Error ? err.message : `Failed to ${action} agent`);
69
+ }
70
+ };
71
+ if (!isOpen || !agent) return null;
72
+ return /* @__PURE__ */ jsxs("div", {
73
+ className: "fixed inset-0 z-50 flex items-center justify-center",
74
+ children: [/* @__PURE__ */ jsx("div", {
75
+ className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
76
+ onClick: handleClose,
77
+ role: "button",
78
+ tabIndex: 0,
79
+ onKeyDown: (e) => {
80
+ if (e.key === "Enter" || e.key === " ") handleClose();
81
+ },
82
+ "aria-label": "Close modal"
83
+ }), /* @__PURE__ */ jsxs("div", {
84
+ className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
85
+ children: [
86
+ /* @__PURE__ */ jsxs("div", {
87
+ className: "border-border mb-4 border-b pb-4",
88
+ children: [
89
+ /* @__PURE__ */ jsx("h2", {
90
+ className: "text-xl font-semibold",
91
+ children: agent.name
92
+ }),
93
+ /* @__PURE__ */ jsxs("div", {
94
+ className: "mt-1 flex items-center gap-2",
95
+ children: [/* @__PURE__ */ jsxs("span", {
96
+ className: "text-muted-foreground text-sm",
97
+ children: [
98
+ agent.modelProvider,
99
+ " / ",
100
+ agent.modelName
101
+ ]
102
+ }), /* @__PURE__ */ jsx("span", {
103
+ className: `rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(agent.status)}`,
104
+ children: agent.status
105
+ })]
106
+ }),
107
+ agent.description && /* @__PURE__ */ jsx("p", {
108
+ className: "text-muted-foreground mt-2 text-sm",
109
+ children: agent.description
110
+ })
111
+ ]
112
+ }),
113
+ mode === "menu" && /* @__PURE__ */ jsxs("div", {
114
+ className: "space-y-3",
115
+ children: [
116
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxs(Button, {
117
+ className: "w-full justify-start",
118
+ variant: "ghost",
119
+ onPress: () => setMode("execute"),
120
+ children: [/* @__PURE__ */ jsx("span", {
121
+ className: "mr-2",
122
+ children: "▶️"
123
+ }), " Execute Agent"]
124
+ }),
125
+ (agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxs(Button, {
126
+ className: "w-full justify-start",
127
+ variant: "ghost",
128
+ onPress: () => handleStatusChange("activate"),
129
+ disabled: isLoading,
130
+ children: [/* @__PURE__ */ jsx("span", {
131
+ className: "mr-2",
132
+ children: "🟢"
133
+ }), " Activate Agent"]
134
+ }),
135
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxs(Button, {
136
+ className: "w-full justify-start",
137
+ variant: "ghost",
138
+ onPress: () => handleStatusChange("pause"),
139
+ disabled: isLoading,
140
+ children: [/* @__PURE__ */ jsx("span", {
141
+ className: "mr-2",
142
+ children: "⏸️"
143
+ }), " Pause Agent"]
144
+ }),
145
+ agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxs(Button, {
146
+ className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
147
+ variant: "ghost",
148
+ onPress: () => {
149
+ setConfirmAction("archive");
150
+ setMode("confirm");
151
+ },
152
+ children: [/* @__PURE__ */ jsx("span", {
153
+ className: "mr-2",
154
+ children: "📦"
155
+ }), " Archive Agent"]
156
+ }),
157
+ agent.status === "ARCHIVED" && /* @__PURE__ */ jsxs(Button, {
158
+ className: "w-full justify-start",
159
+ variant: "ghost",
160
+ onPress: () => handleStatusChange("activate"),
161
+ disabled: isLoading,
162
+ children: [/* @__PURE__ */ jsx("span", {
163
+ className: "mr-2",
164
+ children: "🔄"
165
+ }), " Restore Agent"]
166
+ }),
167
+ error && /* @__PURE__ */ jsx("div", {
168
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
169
+ children: error
170
+ }),
171
+ /* @__PURE__ */ jsx("div", {
172
+ className: "border-border border-t pt-3",
173
+ children: /* @__PURE__ */ jsx(Button, {
174
+ className: "w-full",
175
+ variant: "outline",
176
+ onPress: handleClose,
177
+ children: "Close"
178
+ })
179
+ })
180
+ ]
181
+ }),
182
+ mode === "execute" && /* @__PURE__ */ jsxs("div", {
183
+ className: "space-y-4",
184
+ children: [
185
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
186
+ htmlFor: "execute-message",
187
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
188
+ children: "Message *"
189
+ }), /* @__PURE__ */ jsx("textarea", {
190
+ id: "execute-message",
191
+ value: message,
192
+ onChange: (e) => setMessage(e.target.value),
193
+ placeholder: "Enter your message to the agent...",
194
+ rows: 4,
195
+ disabled: isLoading,
196
+ 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"
197
+ })] }),
198
+ error && /* @__PURE__ */ jsx("div", {
199
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
200
+ children: error
201
+ }),
202
+ /* @__PURE__ */ jsxs("div", {
203
+ className: "flex justify-end gap-3 pt-2",
204
+ children: [/* @__PURE__ */ jsx(Button, {
205
+ variant: "ghost",
206
+ onPress: () => setMode("menu"),
207
+ disabled: isLoading,
208
+ children: "Back"
209
+ }), /* @__PURE__ */ jsx(Button, {
210
+ onPress: handleExecute,
211
+ disabled: isLoading,
212
+ children: isLoading ? "Executing..." : "▶️ Execute"
213
+ })]
214
+ })
215
+ ]
216
+ }),
217
+ mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxs("div", {
218
+ className: "space-y-4",
219
+ children: [
220
+ /* @__PURE__ */ jsxs("p", {
221
+ className: "text-muted-foreground",
222
+ children: [
223
+ "Are you sure you want to archive",
224
+ " ",
225
+ /* @__PURE__ */ jsx("span", {
226
+ className: "text-foreground font-medium",
227
+ children: agent.name
228
+ }),
229
+ "?"
230
+ ]
231
+ }),
232
+ /* @__PURE__ */ jsx("p", {
233
+ className: "text-muted-foreground text-sm",
234
+ children: "Archived agents cannot be executed but can be restored later."
235
+ }),
236
+ error && /* @__PURE__ */ jsx("div", {
237
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
238
+ children: error
239
+ }),
240
+ /* @__PURE__ */ jsxs("div", {
241
+ className: "flex justify-end gap-3 pt-2",
242
+ children: [/* @__PURE__ */ jsx(Button, {
243
+ variant: "ghost",
244
+ onPress: () => setMode("menu"),
245
+ disabled: isLoading,
246
+ children: "Cancel"
247
+ }), /* @__PURE__ */ jsx(Button, {
248
+ onPress: () => handleStatusChange("archive"),
249
+ disabled: isLoading,
250
+ children: isLoading ? "Archiving..." : "📦 Archive"
251
+ })]
252
+ })
253
+ ]
254
+ })
255
+ ]
256
+ })]
257
+ });
258
+ }
259
+
260
+ //#endregion
261
+ export { AgentActionsModal };
262
+ //# sourceMappingURL=AgentActionsModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentActionsModal.js","names":[],"sources":["../../../src/ui/modals/AgentActionsModal.tsx"],"sourcesContent":["'use client';\n\n/**\n * AgentActionsModal - Actions for a specific agent\n *\n * Wires to UpdateAgentCommand via useAgentMutations hook.\n */\nimport { useState } from 'react';\nimport { Button } from '@contractspec/lib.design-system';\nimport type { Agent } from '../hooks/useAgentList';\n\ntype ActionMode = 'menu' | 'execute' | 'confirm';\n\ninterface AgentActionsModalProps {\n isOpen: boolean;\n agent: Agent | null;\n onClose: () => void;\n onActivate: (agentId: string) => Promise<void>;\n onPause: (agentId: string) => Promise<void>;\n onArchive: (agentId: string) => Promise<void>;\n onExecute: (agentId: string, message: string) => Promise<void>;\n isLoading?: boolean;\n}\n\nfunction getStatusColor(status: Agent['status']): string {\n switch (status) {\n case 'ACTIVE':\n return 'text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30';\n case 'DRAFT':\n return 'text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30';\n case 'PAUSED':\n return 'text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30';\n case 'ARCHIVED':\n return 'text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700';\n default:\n return 'text-gray-600 bg-gray-100';\n }\n}\n\nexport function AgentActionsModal({\n isOpen,\n agent,\n onClose,\n onActivate,\n onPause,\n onArchive,\n onExecute,\n isLoading = false,\n}: AgentActionsModalProps) {\n const [mode, setMode] = useState<ActionMode>('menu');\n const [message, setMessage] = useState('');\n const [confirmAction, setConfirmAction] = useState<'archive' | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const resetForm = () => {\n setMode('menu');\n setMessage('');\n setConfirmAction(null);\n setError(null);\n };\n\n const handleClose = () => {\n resetForm();\n onClose();\n };\n\n const handleExecute = async () => {\n if (!agent) return;\n setError(null);\n\n if (!message.trim()) {\n setError('Please enter a message');\n return;\n }\n\n try {\n await onExecute(agent.id, message.trim());\n handleClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to execute agent');\n }\n };\n\n const handleStatusChange = async (\n action: 'activate' | 'pause' | 'archive'\n ) => {\n if (!agent) return;\n setError(null);\n\n try {\n switch (action) {\n case 'activate':\n await onActivate(agent.id);\n break;\n case 'pause':\n await onPause(agent.id);\n break;\n case 'archive':\n await onArchive(agent.id);\n break;\n }\n handleClose();\n } catch (err) {\n setError(\n err instanceof Error ? err.message : `Failed to ${action} agent`\n );\n }\n };\n\n if (!isOpen || !agent) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <div\n className=\"bg-background/80 absolute inset-0 backdrop-blur-sm\"\n onClick={handleClose}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClose();\n }}\n aria-label=\"Close modal\"\n />\n\n {/* Modal */}\n <div className=\"bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl\">\n {/* Agent Header */}\n <div className=\"border-border mb-4 border-b pb-4\">\n <h2 className=\"text-xl font-semibold\">{agent.name}</h2>\n <div className=\"mt-1 flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">\n {agent.modelProvider} / {agent.modelName}\n </span>\n <span\n className={`rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(agent.status)}`}\n >\n {agent.status}\n </span>\n </div>\n {agent.description && (\n <p className=\"text-muted-foreground mt-2 text-sm\">\n {agent.description}\n </p>\n )}\n </div>\n\n {/* Main Menu */}\n {mode === 'menu' && (\n <div className=\"space-y-3\">\n {/* Execute - Only for active agents */}\n {agent.status === 'ACTIVE' && (\n <Button\n className=\"w-full justify-start\"\n variant=\"ghost\"\n onPress={() => setMode('execute')}\n >\n <span className=\"mr-2\">▶️</span> Execute Agent\n </Button>\n )}\n\n {/* Status Changes */}\n {(agent.status === 'DRAFT' || agent.status === 'PAUSED') && (\n <Button\n className=\"w-full justify-start\"\n variant=\"ghost\"\n onPress={() => handleStatusChange('activate')}\n disabled={isLoading}\n >\n <span className=\"mr-2\">🟢</span> Activate Agent\n </Button>\n )}\n\n {agent.status === 'ACTIVE' && (\n <Button\n className=\"w-full justify-start\"\n variant=\"ghost\"\n onPress={() => handleStatusChange('pause')}\n disabled={isLoading}\n >\n <span className=\"mr-2\">⏸️</span> Pause Agent\n </Button>\n )}\n\n {agent.status !== 'ARCHIVED' && (\n <Button\n className=\"w-full justify-start text-yellow-600 hover:text-yellow-700\"\n variant=\"ghost\"\n onPress={() => {\n setConfirmAction('archive');\n setMode('confirm');\n }}\n >\n <span className=\"mr-2\">📦</span> Archive Agent\n </Button>\n )}\n\n {agent.status === 'ARCHIVED' && (\n <Button\n className=\"w-full justify-start\"\n variant=\"ghost\"\n onPress={() => handleStatusChange('activate')}\n disabled={isLoading}\n >\n <span className=\"mr-2\">🔄</span> Restore Agent\n </Button>\n )}\n\n {error && (\n <div className=\"bg-destructive/10 text-destructive rounded-md p-3 text-sm\">\n {error}\n </div>\n )}\n\n <div className=\"border-border border-t pt-3\">\n <Button\n className=\"w-full\"\n variant=\"outline\"\n onPress={handleClose}\n >\n Close\n </Button>\n </div>\n </div>\n )}\n\n {/* Execute Form */}\n {mode === 'execute' && (\n <div className=\"space-y-4\">\n <div>\n <label\n htmlFor=\"execute-message\"\n className=\"text-muted-foreground mb-1 block text-sm font-medium\"\n >\n Message *\n </label>\n <textarea\n id=\"execute-message\"\n value={message}\n onChange={(e) => setMessage(e.target.value)}\n placeholder=\"Enter your message to the agent...\"\n rows={4}\n disabled={isLoading}\n 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\"\n />\n </div>\n\n {error && (\n <div className=\"bg-destructive/10 text-destructive rounded-md p-3 text-sm\">\n {error}\n </div>\n )}\n\n <div className=\"flex justify-end gap-3 pt-2\">\n <Button\n variant=\"ghost\"\n onPress={() => setMode('menu')}\n disabled={isLoading}\n >\n Back\n </Button>\n <Button onPress={handleExecute} disabled={isLoading}>\n {isLoading ? 'Executing...' : '▶️ Execute'}\n </Button>\n </div>\n </div>\n )}\n\n {/* Confirm Action */}\n {mode === 'confirm' && confirmAction === 'archive' && (\n <div className=\"space-y-4\">\n <p className=\"text-muted-foreground\">\n Are you sure you want to archive{' '}\n <span className=\"text-foreground font-medium\">{agent.name}</span>?\n </p>\n <p className=\"text-muted-foreground text-sm\">\n Archived agents cannot be executed but can be restored later.\n </p>\n\n {error && (\n <div className=\"bg-destructive/10 text-destructive rounded-md p-3 text-sm\">\n {error}\n </div>\n )}\n\n <div className=\"flex justify-end gap-3 pt-2\">\n <Button\n variant=\"ghost\"\n onPress={() => setMode('menu')}\n disabled={isLoading}\n >\n Cancel\n </Button>\n <Button\n onPress={() => handleStatusChange('archive')}\n disabled={isLoading}\n >\n {isLoading ? 'Archiving...' : '📦 Archive'}\n </Button>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import * as react_jsx_runtime3 from "react/jsx-runtime";
2
+
3
+ //#region src/ui/modals/CreateAgentModal.d.ts
4
+ interface CreateAgentInput {
5
+ name: string;
6
+ description?: string;
7
+ modelProvider: string;
8
+ modelName: string;
9
+ systemPrompt?: string;
10
+ }
11
+ interface CreateAgentModalProps {
12
+ isOpen: boolean;
13
+ onClose: () => void;
14
+ onSubmit: (input: CreateAgentInput) => Promise<void>;
15
+ isLoading?: boolean;
16
+ }
17
+ declare function CreateAgentModal({
18
+ isOpen,
19
+ onClose,
20
+ onSubmit,
21
+ isLoading
22
+ }: CreateAgentModalProps): react_jsx_runtime3.JSX.Element | null;
23
+ //#endregion
24
+ export { CreateAgentInput, CreateAgentModal };
25
+ //# sourceMappingURL=CreateAgentModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CreateAgentModal.d.ts","names":[],"sources":["../../../src/ui/modals/CreateAgentModal.tsx"],"sourcesContent":[],"mappings":";;;UAWiB,gBAAA;;;EAAA,aAAA,EAAA,MAAgB;EAQvB,SAAA,EAAA,MAAA;EA4BM,YAAA,CAAA,EAAA,MAAgB;;UA5BtB,qBAAA,CA8BR;EACA,MAAA,EAAA,OAAA;EACA,OAAA,EAAA,GAAA,GAAA,IAAA;EACC,QAAA,EAAA,CAAA,KAAA,EA9BiB,gBA8BjB,EAAA,GA9BsC,OA8BtC,CAAA,IAAA,CAAA;EAAqB,SAAA,CAAA,EAAA,OAAA;;iBALR,gBAAA;;;;;GAKb,wBAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,214 @@
1
+ 'use client';
2
+
3
+ import { useState } from "react";
4
+ import { Button, Input } from "@contractspec/lib.design-system";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+
7
+ //#region src/ui/modals/CreateAgentModal.tsx
8
+ /**
9
+ * CreateAgentModal - Form for creating a new AI agent
10
+ *
11
+ * Wires to CreateAgentCommand via useAgentMutations hook.
12
+ */
13
+ const MODEL_PROVIDERS = [
14
+ {
15
+ value: "openai",
16
+ label: "OpenAI",
17
+ models: [
18
+ "gpt-4o",
19
+ "gpt-4-turbo",
20
+ "gpt-3.5-turbo"
21
+ ]
22
+ },
23
+ {
24
+ value: "anthropic",
25
+ label: "Anthropic",
26
+ models: [
27
+ "claude-3-opus",
28
+ "claude-3-sonnet",
29
+ "claude-3-haiku"
30
+ ]
31
+ },
32
+ {
33
+ value: "google",
34
+ label: "Google",
35
+ models: ["gemini-pro", "gemini-ultra"]
36
+ },
37
+ {
38
+ value: "mistral",
39
+ label: "Mistral",
40
+ models: [
41
+ "mistral-large",
42
+ "mistral-medium",
43
+ "mistral-small"
44
+ ]
45
+ }
46
+ ];
47
+ function CreateAgentModal({ isOpen, onClose, onSubmit, isLoading = false }) {
48
+ const [name, setName] = useState("");
49
+ const [description, setDescription] = useState("");
50
+ const [modelProvider, setModelProvider] = useState("openai");
51
+ const [modelName, setModelName] = useState("gpt-4o");
52
+ const [systemPrompt, setSystemPrompt] = useState("");
53
+ const [error, setError] = useState(null);
54
+ const selectedProvider = MODEL_PROVIDERS.find((p) => p.value === modelProvider);
55
+ const handleSubmit = async (e) => {
56
+ e.preventDefault();
57
+ setError(null);
58
+ if (!name.trim()) {
59
+ setError("Agent name is required");
60
+ return;
61
+ }
62
+ try {
63
+ await onSubmit({
64
+ name: name.trim(),
65
+ description: description.trim() || void 0,
66
+ modelProvider,
67
+ modelName,
68
+ systemPrompt: systemPrompt.trim() || void 0
69
+ });
70
+ setName("");
71
+ setDescription("");
72
+ setModelProvider("openai");
73
+ setModelName("gpt-4o");
74
+ setSystemPrompt("");
75
+ onClose();
76
+ } catch (err) {
77
+ setError(err instanceof Error ? err.message : "Failed to create agent");
78
+ }
79
+ };
80
+ const handleProviderChange = (provider) => {
81
+ setModelProvider(provider);
82
+ const providerConfig = MODEL_PROVIDERS.find((p) => p.value === provider);
83
+ if (providerConfig) setModelName(providerConfig.models[0]);
84
+ };
85
+ if (!isOpen) return null;
86
+ return /* @__PURE__ */ jsxs("div", {
87
+ className: "fixed inset-0 z-50 flex items-center justify-center",
88
+ children: [/* @__PURE__ */ jsx("div", {
89
+ className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
90
+ onClick: onClose,
91
+ role: "button",
92
+ tabIndex: 0,
93
+ onKeyDown: (e) => {
94
+ if (e.key === "Enter" || e.key === " ") onClose();
95
+ },
96
+ "aria-label": "Close modal"
97
+ }), /* @__PURE__ */ jsxs("div", {
98
+ 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",
99
+ children: [/* @__PURE__ */ jsx("h2", {
100
+ className: "mb-4 text-xl font-semibold",
101
+ children: "Create New Agent"
102
+ }), /* @__PURE__ */ jsxs("form", {
103
+ onSubmit: handleSubmit,
104
+ className: "space-y-4",
105
+ children: [
106
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
107
+ htmlFor: "agent-name",
108
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
109
+ children: "Agent Name *"
110
+ }), /* @__PURE__ */ jsx(Input, {
111
+ id: "agent-name",
112
+ value: name,
113
+ onChange: (e) => setName(e.target.value),
114
+ placeholder: "e.g., Customer Support Bot",
115
+ disabled: isLoading
116
+ })] }),
117
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("label", {
118
+ htmlFor: "agent-description",
119
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
120
+ children: "Description"
121
+ }), /* @__PURE__ */ jsx("textarea", {
122
+ id: "agent-description",
123
+ value: description,
124
+ onChange: (e) => setDescription(e.target.value),
125
+ placeholder: "Describe what this agent does...",
126
+ rows: 2,
127
+ disabled: isLoading,
128
+ 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"
129
+ })] }),
130
+ /* @__PURE__ */ jsxs("div", {
131
+ className: "flex gap-3",
132
+ children: [/* @__PURE__ */ jsxs("div", {
133
+ className: "flex-1",
134
+ children: [/* @__PURE__ */ jsx("label", {
135
+ htmlFor: "model-provider",
136
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
137
+ children: "Provider *"
138
+ }), /* @__PURE__ */ jsx("select", {
139
+ id: "model-provider",
140
+ value: modelProvider,
141
+ onChange: (e) => handleProviderChange(e.target.value),
142
+ disabled: isLoading,
143
+ 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",
144
+ children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsx("option", {
145
+ value: p.value,
146
+ children: p.label
147
+ }, p.value))
148
+ })]
149
+ }), /* @__PURE__ */ jsxs("div", {
150
+ className: "flex-1",
151
+ children: [/* @__PURE__ */ jsx("label", {
152
+ htmlFor: "model-name",
153
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
154
+ children: "Model *"
155
+ }), /* @__PURE__ */ jsx("select", {
156
+ id: "model-name",
157
+ value: modelName,
158
+ onChange: (e) => setModelName(e.target.value),
159
+ disabled: isLoading,
160
+ 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",
161
+ children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsx("option", {
162
+ value: m,
163
+ children: m
164
+ }, m))
165
+ })]
166
+ })]
167
+ }),
168
+ /* @__PURE__ */ jsxs("div", { children: [
169
+ /* @__PURE__ */ jsx("label", {
170
+ htmlFor: "system-prompt",
171
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
172
+ children: "System Prompt"
173
+ }),
174
+ /* @__PURE__ */ jsx("textarea", {
175
+ id: "system-prompt",
176
+ value: systemPrompt,
177
+ onChange: (e) => setSystemPrompt(e.target.value),
178
+ placeholder: "You are a helpful assistant that...",
179
+ rows: 4,
180
+ disabled: isLoading,
181
+ 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"
182
+ }),
183
+ /* @__PURE__ */ jsx("p", {
184
+ className: "text-muted-foreground mt-1 text-xs",
185
+ children: "Instructions that define the agent's behavior"
186
+ })
187
+ ] }),
188
+ error && /* @__PURE__ */ jsx("div", {
189
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
190
+ children: error
191
+ }),
192
+ /* @__PURE__ */ jsxs("div", {
193
+ className: "flex justify-end gap-3 pt-2",
194
+ children: [/* @__PURE__ */ jsx(Button, {
195
+ type: "button",
196
+ variant: "ghost",
197
+ onPress: onClose,
198
+ disabled: isLoading,
199
+ children: "Cancel"
200
+ }), /* @__PURE__ */ jsx(Button, {
201
+ type: "submit",
202
+ disabled: isLoading,
203
+ children: isLoading ? "Creating..." : "Create Agent"
204
+ })]
205
+ })
206
+ ]
207
+ })]
208
+ })]
209
+ });
210
+ }
211
+
212
+ //#endregion
213
+ export { CreateAgentModal };
214
+ //# sourceMappingURL=CreateAgentModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CreateAgentModal.js","names":[],"sources":["../../../src/ui/modals/CreateAgentModal.tsx"],"sourcesContent":["'use client';\n\n/**\n * CreateAgentModal - Form for creating a new AI agent\n *\n * Wires to CreateAgentCommand via useAgentMutations hook.\n */\nimport { useState } from 'react';\nimport { Button, Input } from '@contractspec/lib.design-system';\n\n// Local type definition for modal props\nexport interface CreateAgentInput {\n name: string;\n description?: string;\n modelProvider: string;\n modelName: string;\n systemPrompt?: string;\n}\n\ninterface CreateAgentModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (input: CreateAgentInput) => Promise<void>;\n isLoading?: boolean;\n}\n\nconst MODEL_PROVIDERS = [\n {\n value: 'openai',\n label: 'OpenAI',\n models: ['gpt-4o', 'gpt-4-turbo', 'gpt-3.5-turbo'],\n },\n {\n value: 'anthropic',\n label: 'Anthropic',\n models: ['claude-3-opus', 'claude-3-sonnet', 'claude-3-haiku'],\n },\n { value: 'google', label: 'Google', models: ['gemini-pro', 'gemini-ultra'] },\n {\n value: 'mistral',\n label: 'Mistral',\n models: ['mistral-large', 'mistral-medium', 'mistral-small'],\n },\n] as const;\n\ntype ModelProvider = (typeof MODEL_PROVIDERS)[number]['value'];\n\nexport function CreateAgentModal({\n isOpen,\n onClose,\n onSubmit,\n isLoading = false,\n}: CreateAgentModalProps) {\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [modelProvider, setModelProvider] = useState<ModelProvider>('openai');\n const [modelName, setModelName] = useState('gpt-4o');\n const [systemPrompt, setSystemPrompt] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const selectedProvider = MODEL_PROVIDERS.find(\n (p) => p.value === modelProvider\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n // Validation\n if (!name.trim()) {\n setError('Agent name is required');\n return;\n }\n\n try {\n await onSubmit({\n name: name.trim(),\n description: description.trim() || undefined,\n modelProvider,\n modelName,\n systemPrompt: systemPrompt.trim() || undefined,\n });\n\n // Reset form\n setName('');\n setDescription('');\n setModelProvider('openai');\n setModelName('gpt-4o');\n setSystemPrompt('');\n onClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to create agent');\n }\n };\n\n // Update model when provider changes\n const handleProviderChange = (provider: ModelProvider) => {\n setModelProvider(provider);\n const providerConfig = MODEL_PROVIDERS.find((p) => p.value === provider);\n if (providerConfig) {\n setModelName(providerConfig.models[0]);\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <div\n className=\"bg-background/80 absolute inset-0 backdrop-blur-sm\"\n onClick={onClose}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') onClose();\n }}\n aria-label=\"Close modal\"\n />\n\n {/* Modal */}\n <div 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\">\n <h2 className=\"mb-4 text-xl font-semibold\">Create New Agent</h2>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {/* Agent Name */}\n <div>\n <label\n htmlFor=\"agent-name\"\n className=\"text-muted-foreground mb-1 block text-sm font-medium\"\n >\n Agent Name *\n </label>\n <Input\n id=\"agent-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g., Customer Support Bot\"\n disabled={isLoading}\n />\n </div>\n\n {/* Description */}\n <div>\n <label\n htmlFor=\"agent-description\"\n className=\"text-muted-foreground mb-1 block text-sm font-medium\"\n >\n Description\n </label>\n <textarea\n id=\"agent-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Describe what this agent does...\"\n rows={2}\n disabled={isLoading}\n 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\"\n />\n </div>\n\n {/* Model Provider & Model */}\n <div className=\"flex gap-3\">\n <div className=\"flex-1\">\n <label\n htmlFor=\"model-provider\"\n className=\"text-muted-foreground mb-1 block text-sm font-medium\"\n >\n Provider *\n </label>\n <select\n id=\"model-provider\"\n value={modelProvider}\n onChange={(e) =>\n handleProviderChange(e.target.value as ModelProvider)\n }\n disabled={isLoading}\n 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\"\n >\n {MODEL_PROVIDERS.map((p) => (\n <option key={p.value} value={p.value}>\n {p.label}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex-1\">\n <label\n htmlFor=\"model-name\"\n className=\"text-muted-foreground mb-1 block text-sm font-medium\"\n >\n Model *\n </label>\n <select\n id=\"model-name\"\n value={modelName}\n onChange={(e) => setModelName(e.target.value)}\n disabled={isLoading}\n 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\"\n >\n {selectedProvider?.models.map((m) => (\n <option key={m} value={m}>\n {m}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n {/* System Prompt */}\n <div>\n <label\n htmlFor=\"system-prompt\"\n className=\"text-muted-foreground mb-1 block text-sm font-medium\"\n >\n System Prompt\n </label>\n <textarea\n id=\"system-prompt\"\n value={systemPrompt}\n onChange={(e) => setSystemPrompt(e.target.value)}\n placeholder=\"You are a helpful assistant that...\"\n rows={4}\n disabled={isLoading}\n 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\"\n />\n <p className=\"text-muted-foreground mt-1 text-xs\">\n Instructions that define the agent's behavior\n </p>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"bg-destructive/10 text-destructive rounded-md p-3 text-sm\">\n {error}\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex justify-end gap-3 pt-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n onPress={onClose}\n disabled={isLoading}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isLoading}>\n {isLoading ? 'Creating...' : 'Create Agent'}\n </Button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { CreateAgentModal } from "./CreateAgentModal.js";
2
+ import { AgentActionsModal } from "./AgentActionsModal.js";
3
+ export { AgentActionsModal, CreateAgentModal };
@@ -0,0 +1,4 @@
1
+ import { CreateAgentModal } from "./CreateAgentModal.js";
2
+ import { AgentActionsModal } from "./AgentActionsModal.js";
3
+
4
+ export { AgentActionsModal, CreateAgentModal };
@@ -0,0 +1,19 @@
1
+ import { OverlayDefinition } from "../../shared/overlay-types.js";
2
+
3
+ //#region src/ui/overlays/demo-overlays.d.ts
4
+
5
+ /**
6
+ * Demo user overlay - hides advanced configuration options
7
+ */
8
+ declare const agentConsoleDemoOverlay: OverlayDefinition;
9
+ /**
10
+ * Read-only overlay - for viewing without edit permissions
11
+ */
12
+ declare const agentConsoleReadOnlyOverlay: OverlayDefinition;
13
+ /**
14
+ * All overlays for agent-console
15
+ */
16
+ declare const agentConsoleOverlays: OverlayDefinition[];
17
+ //#endregion
18
+ export { agentConsoleDemoOverlay, agentConsoleOverlays, agentConsoleReadOnlyOverlay };
19
+ //# sourceMappingURL=demo-overlays.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo-overlays.d.ts","names":[],"sources":["../../../src/ui/overlays/demo-overlays.ts"],"sourcesContent":[],"mappings":";;;;;;;cAWa,yBAAyB;;;;cAoCzB,6BAA6B;;;;cA0B7B,sBAAsB"}
@@ -0,0 +1,73 @@
1
+ //#region src/ui/overlays/demo-overlays.ts
2
+ /**
3
+ * Demo user overlay - hides advanced configuration options
4
+ */
5
+ const agentConsoleDemoOverlay = {
6
+ overlayId: "agent-console.demo-user",
7
+ version: "1.0.0",
8
+ description: "Simplifies agent console for demo users",
9
+ appliesTo: {
10
+ feature: "agent-console",
11
+ role: "demo"
12
+ },
13
+ modifications: [
14
+ {
15
+ type: "hideField",
16
+ field: "modelConfig",
17
+ reason: "Advanced config not relevant for demo"
18
+ },
19
+ {
20
+ type: "hideField",
21
+ field: "webhookConfig",
22
+ reason: "Integration not available in demo"
23
+ },
24
+ {
25
+ type: "renameLabel",
26
+ field: "systemPrompt",
27
+ newLabel: "Agent Instructions"
28
+ },
29
+ {
30
+ type: "addBadge",
31
+ position: "header",
32
+ label: "Demo Mode",
33
+ variant: "warning"
34
+ }
35
+ ]
36
+ };
37
+ /**
38
+ * Read-only overlay - for viewing without edit permissions
39
+ */
40
+ const agentConsoleReadOnlyOverlay = {
41
+ overlayId: "agent-console.read-only",
42
+ version: "1.0.0",
43
+ description: "Read-only view for non-admin users",
44
+ appliesTo: {
45
+ feature: "agent-console",
46
+ role: "viewer"
47
+ },
48
+ modifications: [
49
+ {
50
+ type: "hideField",
51
+ field: "deleteButton",
52
+ reason: "No delete permission"
53
+ },
54
+ {
55
+ type: "hideField",
56
+ field: "editButton",
57
+ reason: "No edit permission"
58
+ },
59
+ {
60
+ type: "hideField",
61
+ field: "createButton",
62
+ reason: "No create permission"
63
+ }
64
+ ]
65
+ };
66
+ /**
67
+ * All overlays for agent-console
68
+ */
69
+ const agentConsoleOverlays = [agentConsoleDemoOverlay, agentConsoleReadOnlyOverlay];
70
+
71
+ //#endregion
72
+ export { agentConsoleDemoOverlay, agentConsoleOverlays, agentConsoleReadOnlyOverlay };
73
+ //# sourceMappingURL=demo-overlays.js.map