@contractspec/example.agent-console 1.46.1 → 1.47.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 (201) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +275 -128
  2. package/.turbo/turbo-build.log +274 -127
  3. package/CHANGELOG.md +37 -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.js +5 -5
  10. package/dist/agent/agent.event.js.map +1 -1
  11. package/dist/agent/agent.handler.js.map +1 -1
  12. package/dist/agent/agent.operation.d.ts +117 -117
  13. package/dist/agent/agent.operation.d.ts.map +1 -1
  14. package/dist/agent/agent.presentation.d.ts +4 -5
  15. package/dist/agent/agent.presentation.d.ts.map +1 -1
  16. package/dist/agent/agent.presentation.js +7 -7
  17. package/dist/agent/agent.presentation.js.map +1 -1
  18. package/dist/agent/agent.schema.d.ts +95 -95
  19. package/dist/agent/agent.schema.d.ts.map +1 -1
  20. package/dist/agent/agent.test-spec.d.ts +8 -0
  21. package/dist/agent/agent.test-spec.d.ts.map +1 -0
  22. package/dist/agent/agent.test-spec.js +65 -0
  23. package/dist/agent/agent.test-spec.js.map +1 -0
  24. package/dist/agent.capability.d.ts +7 -0
  25. package/dist/agent.capability.d.ts.map +1 -0
  26. package/dist/agent.capability.js +20 -0
  27. package/dist/agent.capability.js.map +1 -0
  28. package/dist/agent.feature.d.ts.map +1 -1
  29. package/dist/agent.feature.js +4 -2
  30. package/dist/agent.feature.js.map +1 -1
  31. package/dist/example.d.ts +2 -2
  32. package/dist/example.d.ts.map +1 -1
  33. package/dist/example.js +4 -2
  34. package/dist/example.js.map +1 -1
  35. package/dist/handlers/agent.handlers.d.ts +135 -0
  36. package/dist/handlers/agent.handlers.d.ts.map +1 -0
  37. package/dist/handlers/agent.handlers.js +263 -0
  38. package/dist/handlers/agent.handlers.js.map +1 -0
  39. package/dist/handlers/index.d.ts +2 -1
  40. package/dist/handlers/index.js +2 -1
  41. package/dist/index.d.ts +19 -1
  42. package/dist/index.js +19 -1
  43. package/dist/run/run.entity.d.ts +56 -56
  44. package/dist/run/run.enum.d.ts +5 -5
  45. package/dist/run/run.event.d.ts +71 -71
  46. package/dist/run/run.event.js +8 -8
  47. package/dist/run/run.event.js.map +1 -1
  48. package/dist/run/run.operation.d.ts +175 -175
  49. package/dist/run/run.presentation.d.ts +3 -4
  50. package/dist/run/run.presentation.d.ts.map +1 -1
  51. package/dist/run/run.presentation.js +5 -5
  52. package/dist/run/run.presentation.js.map +1 -1
  53. package/dist/run/run.schema.d.ts +99 -99
  54. package/dist/run/run.test-spec.d.ts +8 -0
  55. package/dist/run/run.test-spec.d.ts.map +1 -0
  56. package/dist/run/run.test-spec.js +65 -0
  57. package/dist/run/run.test-spec.js.map +1 -0
  58. package/dist/seeders/index.d.ts +10 -0
  59. package/dist/seeders/index.d.ts.map +1 -0
  60. package/dist/seeders/index.js +20 -0
  61. package/dist/seeders/index.js.map +1 -0
  62. package/dist/shared/overlay-types.d.ts +34 -0
  63. package/dist/shared/overlay-types.d.ts.map +1 -0
  64. package/dist/shared/overlay-types.js +0 -0
  65. package/dist/tool/tool.entity.d.ts +24 -24
  66. package/dist/tool/tool.enum.d.ts +4 -4
  67. package/dist/tool/tool.event.d.ts +25 -25
  68. package/dist/tool/tool.event.js +4 -4
  69. package/dist/tool/tool.event.js.map +1 -1
  70. package/dist/tool/tool.handler.d.ts.map +1 -1
  71. package/dist/tool/tool.operation.d.ts +101 -101
  72. package/dist/tool/tool.presentation.d.ts +3 -4
  73. package/dist/tool/tool.presentation.d.ts.map +1 -1
  74. package/dist/tool/tool.presentation.js +5 -5
  75. package/dist/tool/tool.presentation.js.map +1 -1
  76. package/dist/tool/tool.schema.d.ts +52 -52
  77. package/dist/tool/tool.schema.d.ts.map +1 -1
  78. package/dist/tool/tool.test-spec.d.ts +8 -0
  79. package/dist/tool/tool.test-spec.d.ts.map +1 -0
  80. package/dist/tool/tool.test-spec.js +65 -0
  81. package/dist/tool/tool.test-spec.js.map +1 -0
  82. package/dist/ui/AgentDashboard.d.ts +7 -0
  83. package/dist/ui/AgentDashboard.d.ts.map +1 -0
  84. package/dist/ui/AgentDashboard.js +420 -0
  85. package/dist/ui/AgentDashboard.js.map +1 -0
  86. package/dist/ui/AgentRunList.d.ts +2 -0
  87. package/dist/ui/AgentRunList.js +5 -0
  88. package/dist/ui/AgentToolRegistry.d.ts +2 -0
  89. package/dist/ui/AgentToolRegistry.js +5 -0
  90. package/dist/ui/hooks/index.d.ts +6 -0
  91. package/dist/ui/hooks/index.js +8 -0
  92. package/dist/ui/hooks/useAgentList.d.ts +28 -0
  93. package/dist/ui/hooks/useAgentList.d.ts.map +1 -0
  94. package/dist/ui/hooks/useAgentList.js +66 -0
  95. package/dist/ui/hooks/useAgentList.js.map +1 -0
  96. package/dist/ui/hooks/useAgentMutations.d.ts +29 -0
  97. package/dist/ui/hooks/useAgentMutations.d.ts.map +1 -0
  98. package/dist/ui/hooks/useAgentMutations.js +124 -0
  99. package/dist/ui/hooks/useAgentMutations.js.map +1 -0
  100. package/dist/ui/hooks/useRunList.d.ts +24 -0
  101. package/dist/ui/hooks/useRunList.d.ts.map +1 -0
  102. package/dist/ui/hooks/useRunList.js +66 -0
  103. package/dist/ui/hooks/useRunList.js.map +1 -0
  104. package/dist/ui/hooks/useToolList.d.ts +40 -0
  105. package/dist/ui/hooks/useToolList.d.ts.map +1 -0
  106. package/dist/ui/hooks/useToolList.js +96 -0
  107. package/dist/ui/hooks/useToolList.js.map +1 -0
  108. package/dist/ui/index.d.ts +24 -0
  109. package/dist/ui/index.js +24 -0
  110. package/dist/ui/modals/AgentActionsModal.d.ts +27 -0
  111. package/dist/ui/modals/AgentActionsModal.d.ts.map +1 -0
  112. package/dist/ui/modals/AgentActionsModal.js +262 -0
  113. package/dist/ui/modals/AgentActionsModal.js.map +1 -0
  114. package/dist/ui/modals/CreateAgentModal.d.ts +25 -0
  115. package/dist/ui/modals/CreateAgentModal.d.ts.map +1 -0
  116. package/dist/ui/modals/CreateAgentModal.js +214 -0
  117. package/dist/ui/modals/CreateAgentModal.js.map +1 -0
  118. package/dist/ui/modals/index.d.ts +3 -0
  119. package/dist/ui/modals/index.js +4 -0
  120. package/dist/ui/overlays/demo-overlays.d.ts +19 -0
  121. package/dist/ui/overlays/demo-overlays.d.ts.map +1 -0
  122. package/dist/ui/overlays/demo-overlays.js +73 -0
  123. package/dist/ui/overlays/demo-overlays.js.map +1 -0
  124. package/dist/ui/overlays/index.d.ts +2 -0
  125. package/dist/ui/overlays/index.js +3 -0
  126. package/dist/ui/renderers/agent-list.markdown.d.ts +15 -0
  127. package/dist/ui/renderers/agent-list.markdown.d.ts.map +1 -0
  128. package/dist/ui/renderers/agent-list.markdown.js +51 -0
  129. package/dist/ui/renderers/agent-list.markdown.js.map +1 -0
  130. package/dist/ui/renderers/agent-list.renderer.d.ts +11 -0
  131. package/dist/ui/renderers/agent-list.renderer.d.ts.map +1 -0
  132. package/dist/ui/renderers/agent-list.renderer.js +19 -0
  133. package/dist/ui/renderers/agent-list.renderer.js.map +1 -0
  134. package/dist/ui/renderers/dashboard.markdown.d.ts +15 -0
  135. package/dist/ui/renderers/dashboard.markdown.d.ts.map +1 -0
  136. package/dist/ui/renderers/dashboard.markdown.js +100 -0
  137. package/dist/ui/renderers/dashboard.markdown.js.map +1 -0
  138. package/dist/ui/renderers/index.d.ts +6 -0
  139. package/dist/ui/renderers/index.js +7 -0
  140. package/dist/ui/renderers/run-list.markdown.d.ts +15 -0
  141. package/dist/ui/renderers/run-list.markdown.d.ts.map +1 -0
  142. package/dist/ui/renderers/run-list.markdown.js +44 -0
  143. package/dist/ui/renderers/run-list.markdown.js.map +1 -0
  144. package/dist/ui/renderers/tool-registry.markdown.d.ts +15 -0
  145. package/dist/ui/renderers/tool-registry.markdown.d.ts.map +1 -0
  146. package/dist/ui/renderers/tool-registry.markdown.js +55 -0
  147. package/dist/ui/renderers/tool-registry.markdown.js.map +1 -0
  148. package/dist/ui/views/AgentListView.d.ts +7 -0
  149. package/dist/ui/views/AgentListView.d.ts.map +1 -0
  150. package/dist/ui/views/AgentListView.js +93 -0
  151. package/dist/ui/views/AgentListView.js.map +1 -0
  152. package/dist/ui/views/RunListView.d.ts +14 -0
  153. package/dist/ui/views/RunListView.d.ts.map +1 -0
  154. package/dist/ui/views/RunListView.js +165 -0
  155. package/dist/ui/views/RunListView.js.map +1 -0
  156. package/dist/ui/views/ToolRegistryView.d.ts +14 -0
  157. package/dist/ui/views/ToolRegistryView.d.ts.map +1 -0
  158. package/dist/ui/views/ToolRegistryView.js +97 -0
  159. package/dist/ui/views/ToolRegistryView.js.map +1 -0
  160. package/dist/ui/views/index.d.ts +4 -0
  161. package/dist/ui/views/index.js +5 -0
  162. package/package.json +46 -10
  163. package/src/agent/agent.presentation.ts +7 -8
  164. package/src/agent/agent.test-spec.ts +55 -0
  165. package/src/agent.capability.ts +13 -0
  166. package/src/agent.feature.ts +3 -2
  167. package/src/example.ts +3 -3
  168. package/src/handlers/agent.handlers.ts +572 -0
  169. package/src/handlers/index.ts +3 -0
  170. package/src/index.ts +5 -0
  171. package/src/run/run.presentation.ts +5 -6
  172. package/src/run/run.test-spec.ts +55 -0
  173. package/src/seeders/index.ts +29 -0
  174. package/src/shared/overlay-types.ts +39 -0
  175. package/src/tool/tool.presentation.ts +5 -6
  176. package/src/tool/tool.test-spec.ts +55 -0
  177. package/src/ui/AgentDashboard.tsx +416 -0
  178. package/src/ui/AgentRunList.tsx +8 -0
  179. package/src/ui/AgentToolRegistry.tsx +8 -0
  180. package/src/ui/hooks/index.ts +14 -0
  181. package/src/ui/hooks/useAgentList.ts +80 -0
  182. package/src/ui/hooks/useAgentMutations.ts +156 -0
  183. package/src/ui/hooks/useRunList.ts +81 -0
  184. package/src/ui/hooks/useToolList.ts +122 -0
  185. package/src/ui/index.ts +21 -0
  186. package/src/ui/modals/AgentActionsModal.tsx +306 -0
  187. package/src/ui/modals/CreateAgentModal.tsx +257 -0
  188. package/src/ui/modals/index.ts +2 -0
  189. package/src/ui/overlays/demo-overlays.ts +77 -0
  190. package/src/ui/overlays/index.ts +1 -0
  191. package/src/ui/renderers/agent-list.markdown.ts +84 -0
  192. package/src/ui/renderers/agent-list.renderer.tsx +27 -0
  193. package/src/ui/renderers/dashboard.markdown.ts +169 -0
  194. package/src/ui/renderers/index.ts +12 -0
  195. package/src/ui/renderers/run-list.markdown.ts +75 -0
  196. package/src/ui/renderers/tool-registry.markdown.ts +91 -0
  197. package/src/ui/views/AgentListView.tsx +113 -0
  198. package/src/ui/views/RunListView.tsx +173 -0
  199. package/src/ui/views/ToolRegistryView.tsx +140 -0
  200. package/src/ui/views/index.ts +6 -0
  201. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,257 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * CreateAgentModal - Form for creating a new AI agent
5
+ *
6
+ * Wires to CreateAgentCommand via useAgentMutations hook.
7
+ */
8
+ import { useState } from 'react';
9
+ import { Button, Input } from '@contractspec/lib.design-system';
10
+
11
+ // Local type definition for modal props
12
+ export interface CreateAgentInput {
13
+ name: string;
14
+ description?: string;
15
+ modelProvider: string;
16
+ modelName: string;
17
+ systemPrompt?: string;
18
+ }
19
+
20
+ interface CreateAgentModalProps {
21
+ isOpen: boolean;
22
+ onClose: () => void;
23
+ onSubmit: (input: CreateAgentInput) => Promise<void>;
24
+ isLoading?: boolean;
25
+ }
26
+
27
+ const MODEL_PROVIDERS = [
28
+ {
29
+ value: 'openai',
30
+ label: 'OpenAI',
31
+ models: ['gpt-4o', 'gpt-4-turbo', 'gpt-3.5-turbo'],
32
+ },
33
+ {
34
+ value: 'anthropic',
35
+ label: 'Anthropic',
36
+ models: ['claude-3-opus', 'claude-3-sonnet', 'claude-3-haiku'],
37
+ },
38
+ { value: 'google', label: 'Google', models: ['gemini-pro', 'gemini-ultra'] },
39
+ {
40
+ value: 'mistral',
41
+ label: 'Mistral',
42
+ models: ['mistral-large', 'mistral-medium', 'mistral-small'],
43
+ },
44
+ ] as const;
45
+
46
+ type ModelProvider = (typeof MODEL_PROVIDERS)[number]['value'];
47
+
48
+ export function CreateAgentModal({
49
+ isOpen,
50
+ onClose,
51
+ onSubmit,
52
+ isLoading = false,
53
+ }: CreateAgentModalProps) {
54
+ const [name, setName] = useState('');
55
+ const [description, setDescription] = useState('');
56
+ const [modelProvider, setModelProvider] = useState<ModelProvider>('openai');
57
+ const [modelName, setModelName] = useState('gpt-4o');
58
+ const [systemPrompt, setSystemPrompt] = useState('');
59
+ const [error, setError] = useState<string | null>(null);
60
+
61
+ const selectedProvider = MODEL_PROVIDERS.find(
62
+ (p) => p.value === modelProvider
63
+ );
64
+
65
+ const handleSubmit = async (e: React.FormEvent) => {
66
+ e.preventDefault();
67
+ setError(null);
68
+
69
+ // Validation
70
+ if (!name.trim()) {
71
+ setError('Agent name is required');
72
+ return;
73
+ }
74
+
75
+ try {
76
+ await onSubmit({
77
+ name: name.trim(),
78
+ description: description.trim() || undefined,
79
+ modelProvider,
80
+ modelName,
81
+ systemPrompt: systemPrompt.trim() || undefined,
82
+ });
83
+
84
+ // Reset form
85
+ setName('');
86
+ setDescription('');
87
+ setModelProvider('openai');
88
+ setModelName('gpt-4o');
89
+ setSystemPrompt('');
90
+ onClose();
91
+ } catch (err) {
92
+ setError(err instanceof Error ? err.message : 'Failed to create agent');
93
+ }
94
+ };
95
+
96
+ // Update model when provider changes
97
+ const handleProviderChange = (provider: ModelProvider) => {
98
+ setModelProvider(provider);
99
+ const providerConfig = MODEL_PROVIDERS.find((p) => p.value === provider);
100
+ if (providerConfig) {
101
+ setModelName(providerConfig.models[0]);
102
+ }
103
+ };
104
+
105
+ if (!isOpen) return null;
106
+
107
+ return (
108
+ <div className="fixed inset-0 z-50 flex items-center justify-center">
109
+ {/* Backdrop */}
110
+ <div
111
+ className="bg-background/80 absolute inset-0 backdrop-blur-sm"
112
+ onClick={onClose}
113
+ role="button"
114
+ tabIndex={0}
115
+ onKeyDown={(e) => {
116
+ if (e.key === 'Enter' || e.key === ' ') onClose();
117
+ }}
118
+ aria-label="Close modal"
119
+ />
120
+
121
+ {/* Modal */}
122
+ <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">
123
+ <h2 className="mb-4 text-xl font-semibold">Create New Agent</h2>
124
+
125
+ <form onSubmit={handleSubmit} className="space-y-4">
126
+ {/* Agent Name */}
127
+ <div>
128
+ <label
129
+ htmlFor="agent-name"
130
+ className="text-muted-foreground mb-1 block text-sm font-medium"
131
+ >
132
+ Agent Name *
133
+ </label>
134
+ <Input
135
+ id="agent-name"
136
+ value={name}
137
+ onChange={(e) => setName(e.target.value)}
138
+ placeholder="e.g., Customer Support Bot"
139
+ disabled={isLoading}
140
+ />
141
+ </div>
142
+
143
+ {/* Description */}
144
+ <div>
145
+ <label
146
+ htmlFor="agent-description"
147
+ className="text-muted-foreground mb-1 block text-sm font-medium"
148
+ >
149
+ Description
150
+ </label>
151
+ <textarea
152
+ id="agent-description"
153
+ value={description}
154
+ onChange={(e) => setDescription(e.target.value)}
155
+ placeholder="Describe what this agent does..."
156
+ rows={2}
157
+ disabled={isLoading}
158
+ 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"
159
+ />
160
+ </div>
161
+
162
+ {/* Model Provider & Model */}
163
+ <div className="flex gap-3">
164
+ <div className="flex-1">
165
+ <label
166
+ htmlFor="model-provider"
167
+ className="text-muted-foreground mb-1 block text-sm font-medium"
168
+ >
169
+ Provider *
170
+ </label>
171
+ <select
172
+ id="model-provider"
173
+ value={modelProvider}
174
+ onChange={(e) =>
175
+ handleProviderChange(e.target.value as ModelProvider)
176
+ }
177
+ disabled={isLoading}
178
+ 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"
179
+ >
180
+ {MODEL_PROVIDERS.map((p) => (
181
+ <option key={p.value} value={p.value}>
182
+ {p.label}
183
+ </option>
184
+ ))}
185
+ </select>
186
+ </div>
187
+ <div className="flex-1">
188
+ <label
189
+ htmlFor="model-name"
190
+ className="text-muted-foreground mb-1 block text-sm font-medium"
191
+ >
192
+ Model *
193
+ </label>
194
+ <select
195
+ id="model-name"
196
+ value={modelName}
197
+ onChange={(e) => setModelName(e.target.value)}
198
+ disabled={isLoading}
199
+ 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"
200
+ >
201
+ {selectedProvider?.models.map((m) => (
202
+ <option key={m} value={m}>
203
+ {m}
204
+ </option>
205
+ ))}
206
+ </select>
207
+ </div>
208
+ </div>
209
+
210
+ {/* System Prompt */}
211
+ <div>
212
+ <label
213
+ htmlFor="system-prompt"
214
+ className="text-muted-foreground mb-1 block text-sm font-medium"
215
+ >
216
+ System Prompt
217
+ </label>
218
+ <textarea
219
+ id="system-prompt"
220
+ value={systemPrompt}
221
+ onChange={(e) => setSystemPrompt(e.target.value)}
222
+ placeholder="You are a helpful assistant that..."
223
+ rows={4}
224
+ disabled={isLoading}
225
+ 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"
226
+ />
227
+ <p className="text-muted-foreground mt-1 text-xs">
228
+ Instructions that define the agent's behavior
229
+ </p>
230
+ </div>
231
+
232
+ {/* Error Message */}
233
+ {error && (
234
+ <div className="bg-destructive/10 text-destructive rounded-md p-3 text-sm">
235
+ {error}
236
+ </div>
237
+ )}
238
+
239
+ {/* Actions */}
240
+ <div className="flex justify-end gap-3 pt-2">
241
+ <Button
242
+ type="button"
243
+ variant="ghost"
244
+ onPress={onClose}
245
+ disabled={isLoading}
246
+ >
247
+ Cancel
248
+ </Button>
249
+ <Button type="submit" disabled={isLoading}>
250
+ {isLoading ? 'Creating...' : 'Create Agent'}
251
+ </Button>
252
+ </div>
253
+ </form>
254
+ </div>
255
+ </div>
256
+ );
257
+ }
@@ -0,0 +1,2 @@
1
+ export { CreateAgentModal } from './CreateAgentModal';
2
+ export { AgentActionsModal } from './AgentActionsModal';
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Demo Overlay Definitions for Agent Console
3
+ *
4
+ * These overlays customize the presentation for different contexts
5
+ * (e.g., demo users, different roles).
6
+ */
7
+ import type { OverlayDefinition } from '../../shared/overlay-types';
8
+
9
+ /**
10
+ * Demo user overlay - hides advanced configuration options
11
+ */
12
+ export const agentConsoleDemoOverlay: OverlayDefinition = {
13
+ overlayId: 'agent-console.demo-user',
14
+ version: '1.0.0',
15
+ description: 'Simplifies agent console for demo users',
16
+ appliesTo: {
17
+ feature: 'agent-console',
18
+ role: 'demo',
19
+ },
20
+ modifications: [
21
+ {
22
+ type: 'hideField',
23
+ field: 'modelConfig',
24
+ reason: 'Advanced config not relevant for demo',
25
+ },
26
+ {
27
+ type: 'hideField',
28
+ field: 'webhookConfig',
29
+ reason: 'Integration not available in demo',
30
+ },
31
+ {
32
+ type: 'renameLabel',
33
+ field: 'systemPrompt',
34
+ newLabel: 'Agent Instructions',
35
+ },
36
+ {
37
+ type: 'addBadge',
38
+ position: 'header',
39
+ label: 'Demo Mode',
40
+ variant: 'warning',
41
+ },
42
+ ],
43
+ };
44
+
45
+ /**
46
+ * Read-only overlay - for viewing without edit permissions
47
+ */
48
+ export const agentConsoleReadOnlyOverlay: OverlayDefinition = {
49
+ overlayId: 'agent-console.read-only',
50
+ version: '1.0.0',
51
+ description: 'Read-only view for non-admin users',
52
+ appliesTo: {
53
+ feature: 'agent-console',
54
+ role: 'viewer',
55
+ },
56
+ modifications: [
57
+ {
58
+ type: 'hideField',
59
+ field: 'deleteButton',
60
+ reason: 'No delete permission',
61
+ },
62
+ { type: 'hideField', field: 'editButton', reason: 'No edit permission' },
63
+ {
64
+ type: 'hideField',
65
+ field: 'createButton',
66
+ reason: 'No create permission',
67
+ },
68
+ ],
69
+ };
70
+
71
+ /**
72
+ * All overlays for agent-console
73
+ */
74
+ export const agentConsoleOverlays: OverlayDefinition[] = [
75
+ agentConsoleDemoOverlay,
76
+ agentConsoleReadOnlyOverlay,
77
+ ];
@@ -0,0 +1 @@
1
+ export * from './demo-overlays';
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Markdown Renderer for Agent List Presentation
3
+ *
4
+ * Uses handlers from the agent-console example package.
5
+ */
6
+ import type {
7
+ PresentationRenderer,
8
+ PresentationSpec,
9
+ } from '@contractspec/lib.contracts';
10
+ import {
11
+ type AgentSummary,
12
+ mockListAgentsHandler,
13
+ } from '@contractspec/example.agent-console/handlers';
14
+
15
+ type Agent = AgentSummary;
16
+
17
+ /**
18
+ * Markdown renderer for agent-console.agent.list presentation
19
+ * Only handles AgentListView component
20
+ */
21
+ export const agentListMarkdownRenderer: PresentationRenderer<{
22
+ mimeType: string;
23
+ body: string;
24
+ }> = {
25
+ target: 'markdown',
26
+ render: async (desc: PresentationSpec) => {
27
+ // Only handle AgentListView
28
+ if (
29
+ desc.source.type !== 'component' ||
30
+ desc.source.componentKey !== 'AgentListView'
31
+ ) {
32
+ throw new Error('agentListMarkdownRenderer: not AgentListView');
33
+ }
34
+
35
+ // Fetch data using mock handler
36
+ const data = await mockListAgentsHandler({
37
+ organizationId: 'demo-org',
38
+ limit: 50,
39
+ offset: 0,
40
+ });
41
+
42
+ // Generate markdown
43
+ const lines: string[] = [
44
+ `# ${desc.meta.description ?? 'Agent List'}`,
45
+ '',
46
+ `> ${desc.meta.key} v${desc.meta.version}`,
47
+ '',
48
+ `**Total Agents:** ${data.total}`,
49
+ '',
50
+ '## Agents',
51
+ '',
52
+ ];
53
+
54
+ // Group by status
55
+ const byStatus: Record<string, Agent[]> = {};
56
+ for (const agent of data.items) {
57
+ const status = agent.status;
58
+ if (byStatus[status]) {
59
+ byStatus[status].push(agent);
60
+ } else {
61
+ byStatus[status] = [agent];
62
+ }
63
+ }
64
+
65
+ for (const [status, agents] of Object.entries(byStatus)) {
66
+ lines.push(`### ${status} (${agents.length})`);
67
+ lines.push('');
68
+ for (const agent of agents) {
69
+ lines.push(
70
+ `- **${agent.name}** (${agent.modelProvider}/${agent.modelName})`
71
+ );
72
+ if (agent.description) {
73
+ lines.push(` > ${agent.description}`);
74
+ }
75
+ }
76
+ lines.push('');
77
+ }
78
+
79
+ return {
80
+ mimeType: 'text/markdown',
81
+ body: lines.join('\n'),
82
+ };
83
+ },
84
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * React Renderer for Agent List Presentation
3
+ */
4
+ import type {
5
+ PresentationRenderer,
6
+ PresentationSpec,
7
+ } from '@contractspec/lib.contracts';
8
+ import { AgentListView } from '../views/AgentListView';
9
+
10
+ /**
11
+ * React renderer for agent-console.agent.list presentation
12
+ */
13
+ export const agentListReactRenderer: PresentationRenderer<React.ReactElement> =
14
+ {
15
+ target: 'react',
16
+ render: async (desc: PresentationSpec) => {
17
+ if (desc.source.type !== 'component') {
18
+ throw new Error('AgentListRenderer: expected component source');
19
+ }
20
+ if (desc.source.componentKey !== 'AgentListView') {
21
+ throw new Error(
22
+ `AgentListRenderer: unknown component ${desc.source.componentKey}`
23
+ );
24
+ }
25
+ return <AgentListView />;
26
+ },
27
+ };
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Markdown Renderer for Agent Console Dashboard
3
+ *
4
+ * Provides a comprehensive overview of agents, runs, and tools.
5
+ */
6
+ import type {
7
+ PresentationSpec,
8
+ PresentationRenderer,
9
+ } from '@contractspec/lib.contracts';
10
+ import {
11
+ mockListAgentsHandler,
12
+ mockListRunsHandler,
13
+ mockListToolsHandler,
14
+ } from '@contractspec/example.agent-console/handlers';
15
+
16
+ function formatDuration(ms: number): string {
17
+ if (ms < 1000) return `${ms}ms`;
18
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
19
+ return `${(ms / 60000).toFixed(1)}m`;
20
+ }
21
+
22
+ /**
23
+ * Markdown renderer for agent-console.dashboard presentation
24
+ * Only handles AgentConsoleDashboard component
25
+ */
26
+ export const agentDashboardMarkdownRenderer: PresentationRenderer<{
27
+ mimeType: string;
28
+ body: string;
29
+ }> = {
30
+ target: 'markdown',
31
+ render: async (desc: PresentationSpec) => {
32
+ // Only handle AgentConsoleDashboard
33
+ if (
34
+ desc.source.type !== 'component' ||
35
+ desc.source.componentKey !== 'AgentConsoleDashboard'
36
+ ) {
37
+ throw new Error(
38
+ 'agentDashboardMarkdownRenderer: not AgentConsoleDashboard'
39
+ );
40
+ }
41
+
42
+ // Fetch all data in parallel
43
+ const [agentsData, runsData, toolsData] = await Promise.all([
44
+ mockListAgentsHandler({
45
+ organizationId: 'demo-org',
46
+ limit: 100,
47
+ }),
48
+ mockListRunsHandler({
49
+ limit: 100,
50
+ }),
51
+ mockListToolsHandler({
52
+ organizationId: 'demo-org',
53
+ limit: 100,
54
+ }),
55
+ ]);
56
+
57
+ // Calculate stats
58
+ const activeAgents = agentsData.items.filter(
59
+ (a) => a.status === 'ACTIVE'
60
+ ).length;
61
+ const completedRuns = runsData.items.filter(
62
+ (r) => r.status === 'COMPLETED'
63
+ ).length;
64
+ const failedRuns = runsData.items.filter(
65
+ (r) => r.status === 'FAILED'
66
+ ).length;
67
+ const totalTokens = runsData.items.reduce(
68
+ (sum, r) => sum + (r.totalTokens ?? 0),
69
+ 0
70
+ );
71
+ const totalCost = runsData.items.reduce(
72
+ (sum, r) => sum + (r.estimatedCostUsd ?? 0),
73
+ 0
74
+ );
75
+ const activeTools = toolsData.items.filter(
76
+ (t) => t.status === 'ACTIVE'
77
+ ).length;
78
+
79
+ // Build dashboard markdown
80
+ const lines: string[] = [
81
+ '# Agent Console Dashboard',
82
+ '',
83
+ '> AI agent operations overview',
84
+ '',
85
+ '## Summary',
86
+ '',
87
+ '| Metric | Value |',
88
+ '|--------|-------|',
89
+ `| Total Agents | ${agentsData.total} |`,
90
+ `| Active Agents | ${activeAgents} |`,
91
+ `| Total Runs | ${runsData.total} |`,
92
+ `| Completed Runs | ${completedRuns} |`,
93
+ `| Failed Runs | ${failedRuns} |`,
94
+ `| Total Tokens | ${totalTokens.toLocaleString()} |`,
95
+ `| Total Cost | $${totalCost.toFixed(4)} |`,
96
+ `| Total Tools | ${toolsData.total} |`,
97
+ `| Active Tools | ${activeTools} |`,
98
+ '',
99
+ '## Agents',
100
+ '',
101
+ ];
102
+
103
+ // Agent list
104
+ if (agentsData.items.length === 0) {
105
+ lines.push('_No agents configured._');
106
+ } else {
107
+ lines.push('| Agent | Model | Status | Description |');
108
+ lines.push('|-------|-------|--------|-------------|');
109
+ for (const agent of agentsData.items.slice(0, 5)) {
110
+ lines.push(
111
+ `| ${agent.name} | ${agent.modelProvider}/${agent.modelName} | ${agent.status} | ${agent.description ?? '-'} |`
112
+ );
113
+ }
114
+ if (agentsData.items.length > 5) {
115
+ lines.push(`| ... | ... | ... | _${agentsData.total - 5} more_ |`);
116
+ }
117
+ }
118
+
119
+ lines.push('');
120
+ lines.push('## Recent Runs');
121
+ lines.push('');
122
+
123
+ // Recent runs
124
+ if (runsData.items.length === 0) {
125
+ lines.push('_No runs yet._');
126
+ } else {
127
+ lines.push('| Run ID | Agent | Status | Duration | Tokens | Cost |');
128
+ lines.push('|--------|-------|--------|----------|--------|------|');
129
+ for (const run of runsData.items.slice(0, 5)) {
130
+ lines.push(
131
+ `| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration(run.durationMs) : '-'} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`
132
+ );
133
+ }
134
+ if (runsData.items.length > 5) {
135
+ lines.push(
136
+ `| ... | ... | ... | ... | ... | _${runsData.total - 5} more_ |`
137
+ );
138
+ }
139
+ }
140
+
141
+ lines.push('');
142
+ lines.push('## Tools');
143
+ lines.push('');
144
+
145
+ // Tool categories
146
+ const toolsByCategory: Record<string, typeof toolsData.items> = {};
147
+ for (const tool of toolsData.items) {
148
+ const cat = tool.category;
149
+ if (!toolsByCategory[cat]) toolsByCategory[cat] = [];
150
+ toolsByCategory[cat].push(tool);
151
+ }
152
+
153
+ if (Object.keys(toolsByCategory).length === 0) {
154
+ lines.push('_No tools registered._');
155
+ } else {
156
+ lines.push('| Category | Tools | Active |');
157
+ lines.push('|----------|-------|--------|');
158
+ for (const [category, tools] of Object.entries(toolsByCategory).sort()) {
159
+ const active = tools.filter((t) => t.status === 'ACTIVE').length;
160
+ lines.push(`| ${category} | ${tools.length} | ${active} |`);
161
+ }
162
+ }
163
+
164
+ return {
165
+ mimeType: 'text/markdown',
166
+ body: lines.join('\n'),
167
+ };
168
+ },
169
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Renderers for agent-console presentations
3
+ */
4
+
5
+ // React renderers
6
+ export { agentListReactRenderer } from './agent-list.renderer';
7
+
8
+ // Markdown renderers
9
+ export { agentListMarkdownRenderer } from './agent-list.markdown';
10
+ export { runListMarkdownRenderer } from './run-list.markdown';
11
+ export { toolRegistryMarkdownRenderer } from './tool-registry.markdown';
12
+ export { agentDashboardMarkdownRenderer } from './dashboard.markdown';