@contractspec/example.agent-console 3.7.5 → 3.7.7

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 (176) hide show
  1. package/.turbo/turbo-build.log +18 -18
  2. package/AGENTS.md +50 -31
  3. package/CHANGELOG.md +12 -0
  4. package/README.md +69 -77
  5. package/dist/agent/agent.event.js +1 -1
  6. package/dist/agent/agent.operation.js +1 -1
  7. package/dist/agent/index.d.ts +5 -5
  8. package/dist/agent/index.js +1 -1
  9. package/dist/browser/agent/agent.event.js +1 -1
  10. package/dist/browser/agent/agent.operation.js +1 -1
  11. package/dist/browser/agent/index.js +1 -1
  12. package/dist/browser/index.js +2145 -2145
  13. package/dist/browser/presentations/index.js +4 -4
  14. package/dist/browser/run/index.js +536 -536
  15. package/dist/browser/run/run.event.js +2 -2
  16. package/dist/browser/run/run.presentation.js +2 -2
  17. package/dist/browser/tool/index.js +260 -260
  18. package/dist/browser/tool/tool.event.js +1 -1
  19. package/dist/browser/tool/tool.presentation.js +2 -2
  20. package/dist/browser/ui/AgentDashboard.js +956 -956
  21. package/dist/browser/ui/AgentRunList.js +16 -16
  22. package/dist/browser/ui/AgentToolRegistry.js +9 -9
  23. package/dist/browser/ui/hooks/index.js +153 -153
  24. package/dist/browser/ui/hooks/useAgentList.js +1 -1
  25. package/dist/browser/ui/hooks/useAgentMutations.js +1 -1
  26. package/dist/browser/ui/hooks/useRunList.js +1 -1
  27. package/dist/browser/ui/hooks/useToolList.js +1 -1
  28. package/dist/browser/ui/index.js +1222 -1222
  29. package/dist/browser/ui/modals/AgentActionsModal.js +13 -13
  30. package/dist/browser/ui/modals/CreateAgentModal.js +15 -15
  31. package/dist/browser/ui/modals/index.js +297 -297
  32. package/dist/browser/ui/renderers/agent-list.renderer.js +7 -7
  33. package/dist/browser/ui/renderers/index.js +157 -157
  34. package/dist/browser/ui/views/AgentListView.js +7 -7
  35. package/dist/browser/ui/views/RunListView.js +16 -16
  36. package/dist/browser/ui/views/ToolRegistryView.js +9 -9
  37. package/dist/browser/ui/views/index.js +97 -97
  38. package/dist/handlers/index.d.ts +1 -1
  39. package/dist/index.d.ts +4 -4
  40. package/dist/index.js +2145 -2145
  41. package/dist/node/agent/agent.event.js +1 -1
  42. package/dist/node/agent/agent.operation.js +1 -1
  43. package/dist/node/agent/index.js +1 -1
  44. package/dist/node/index.js +2145 -2145
  45. package/dist/node/presentations/index.js +4 -4
  46. package/dist/node/run/index.js +536 -536
  47. package/dist/node/run/run.event.js +2 -2
  48. package/dist/node/run/run.presentation.js +2 -2
  49. package/dist/node/tool/index.js +260 -260
  50. package/dist/node/tool/tool.event.js +1 -1
  51. package/dist/node/tool/tool.presentation.js +2 -2
  52. package/dist/node/ui/AgentDashboard.js +956 -956
  53. package/dist/node/ui/AgentRunList.js +16 -16
  54. package/dist/node/ui/AgentToolRegistry.js +9 -9
  55. package/dist/node/ui/hooks/index.js +153 -153
  56. package/dist/node/ui/hooks/useAgentList.js +1 -1
  57. package/dist/node/ui/hooks/useAgentMutations.js +1 -1
  58. package/dist/node/ui/hooks/useRunList.js +1 -1
  59. package/dist/node/ui/hooks/useToolList.js +1 -1
  60. package/dist/node/ui/index.js +1222 -1222
  61. package/dist/node/ui/modals/AgentActionsModal.js +13 -13
  62. package/dist/node/ui/modals/CreateAgentModal.js +15 -15
  63. package/dist/node/ui/modals/index.js +297 -297
  64. package/dist/node/ui/renderers/agent-list.renderer.js +7 -7
  65. package/dist/node/ui/renderers/index.js +157 -157
  66. package/dist/node/ui/views/AgentListView.js +7 -7
  67. package/dist/node/ui/views/RunListView.js +16 -16
  68. package/dist/node/ui/views/ToolRegistryView.js +9 -9
  69. package/dist/node/ui/views/index.js +97 -97
  70. package/dist/presentations/index.d.ts +3 -5
  71. package/dist/presentations/index.js +4 -4
  72. package/dist/run/index.d.ts +7 -7
  73. package/dist/run/index.js +536 -536
  74. package/dist/run/run.event.js +2 -2
  75. package/dist/run/run.handler.d.ts +3 -0
  76. package/dist/run/run.presentation.js +2 -2
  77. package/dist/shared/index.d.ts +1 -1
  78. package/dist/tool/index.d.ts +7 -7
  79. package/dist/tool/index.js +260 -260
  80. package/dist/tool/tool.event.js +1 -1
  81. package/dist/tool/tool.handler.d.ts +1 -1
  82. package/dist/tool/tool.presentation.js +2 -2
  83. package/dist/ui/AgentDashboard.js +956 -956
  84. package/dist/ui/AgentRunList.js +16 -16
  85. package/dist/ui/AgentToolRegistry.js +9 -9
  86. package/dist/ui/hooks/index.d.ts +4 -4
  87. package/dist/ui/hooks/index.js +153 -153
  88. package/dist/ui/hooks/useAgentList.d.ts +5 -0
  89. package/dist/ui/hooks/useAgentList.js +1 -1
  90. package/dist/ui/hooks/useAgentMutations.d.ts +9 -2
  91. package/dist/ui/hooks/useAgentMutations.js +1 -1
  92. package/dist/ui/hooks/useRunList.d.ts +5 -0
  93. package/dist/ui/hooks/useRunList.js +1 -1
  94. package/dist/ui/hooks/useToolList.d.ts +5 -0
  95. package/dist/ui/hooks/useToolList.js +1 -1
  96. package/dist/ui/index.d.ts +3 -3
  97. package/dist/ui/index.js +1222 -1222
  98. package/dist/ui/modals/AgentActionsModal.js +13 -13
  99. package/dist/ui/modals/CreateAgentModal.js +15 -15
  100. package/dist/ui/modals/index.d.ts +1 -1
  101. package/dist/ui/modals/index.js +297 -297
  102. package/dist/ui/renderers/agent-list.markdown.d.ts +5 -0
  103. package/dist/ui/renderers/agent-list.renderer.js +7 -7
  104. package/dist/ui/renderers/dashboard.markdown.d.ts +5 -0
  105. package/dist/ui/renderers/index.d.ts +2 -2
  106. package/dist/ui/renderers/index.js +157 -157
  107. package/dist/ui/renderers/run-list.markdown.d.ts +5 -0
  108. package/dist/ui/renderers/tool-registry.markdown.d.ts +5 -0
  109. package/dist/ui/views/AgentListView.js +7 -7
  110. package/dist/ui/views/RunListView.js +16 -16
  111. package/dist/ui/views/ToolRegistryView.js +9 -9
  112. package/dist/ui/views/index.js +97 -97
  113. package/package.json +10 -10
  114. package/src/agent/agent.entity.ts +111 -111
  115. package/src/agent/agent.enum.ts +12 -12
  116. package/src/agent/agent.event.ts +91 -91
  117. package/src/agent/agent.handler.ts +123 -123
  118. package/src/agent/agent.operation.ts +400 -400
  119. package/src/agent/agent.presentation.ts +62 -62
  120. package/src/agent/agent.schema.ts +175 -175
  121. package/src/agent/agent.test-spec.ts +48 -48
  122. package/src/agent/index.ts +46 -51
  123. package/src/agent.capability.ts +11 -11
  124. package/src/agent.feature.ts +131 -131
  125. package/src/docs/agent-console.docblock.ts +42 -42
  126. package/src/example.ts +35 -35
  127. package/src/handlers/agent.handlers.ts +522 -521
  128. package/src/handlers/index.ts +12 -12
  129. package/src/index.ts +8 -9
  130. package/src/presentations/index.ts +11 -13
  131. package/src/run/index.ts +49 -54
  132. package/src/run/run.entity.ts +137 -137
  133. package/src/run/run.enum.ts +18 -18
  134. package/src/run/run.event.ts +174 -174
  135. package/src/run/run.handler.ts +92 -91
  136. package/src/run/run.operation.ts +474 -474
  137. package/src/run/run.presentation.ts +42 -42
  138. package/src/run/run.schema.ts +126 -126
  139. package/src/run/run.test-spec.ts +48 -48
  140. package/src/seeders/index.ts +21 -21
  141. package/src/shared/index.ts +1 -1
  142. package/src/shared/mock-agents.ts +76 -76
  143. package/src/shared/mock-runs.ts +102 -102
  144. package/src/shared/mock-tools.ts +140 -140
  145. package/src/shared/overlay-types.ts +23 -23
  146. package/src/tool/index.ts +39 -44
  147. package/src/tool/tool.entity.ts +73 -73
  148. package/src/tool/tool.enum.ts +13 -13
  149. package/src/tool/tool.event.ts +80 -80
  150. package/src/tool/tool.handler.ts +102 -102
  151. package/src/tool/tool.operation.ts +328 -328
  152. package/src/tool/tool.presentation.ts +43 -43
  153. package/src/tool/tool.schema.ts +106 -106
  154. package/src/tool/tool.test-spec.ts +48 -48
  155. package/src/ui/AgentDashboard.tsx +348 -348
  156. package/src/ui/hooks/index.ts +7 -7
  157. package/src/ui/hooks/useAgentList.ts +57 -56
  158. package/src/ui/hooks/useAgentMutations.ts +160 -159
  159. package/src/ui/hooks/useRunList.ts +58 -57
  160. package/src/ui/hooks/useToolList.ts +102 -101
  161. package/src/ui/index.ts +6 -9
  162. package/src/ui/modals/AgentActionsModal.tsx +262 -262
  163. package/src/ui/modals/CreateAgentModal.tsx +232 -232
  164. package/src/ui/modals/index.ts +1 -1
  165. package/src/ui/overlays/demo-overlays.ts +52 -52
  166. package/src/ui/renderers/agent-list.markdown.ts +61 -60
  167. package/src/ui/renderers/agent-list.renderer.tsx +14 -14
  168. package/src/ui/renderers/dashboard.markdown.ts +140 -139
  169. package/src/ui/renderers/index.ts +3 -4
  170. package/src/ui/renderers/run-list.markdown.ts +48 -47
  171. package/src/ui/renderers/tool-registry.markdown.ts +66 -65
  172. package/src/ui/views/AgentListView.tsx +90 -90
  173. package/src/ui/views/RunListView.tsx +141 -141
  174. package/src/ui/views/ToolRegistryView.tsx +113 -113
  175. package/tsconfig.json +7 -8
  176. package/tsdown.config.js +7 -3
@@ -3,12 +3,13 @@
3
3
  *
4
4
  * Uses handlers from the agent-console example package.
5
5
  */
6
- import type { PresentationSpec } from '@contractspec/lib.contracts-spec/presentations';
7
- import type { PresentationRenderer } from '@contractspec/lib.contracts-spec/presentations/transform-engine';
6
+
8
7
  import {
9
- type AgentSummary,
10
- mockListAgentsHandler,
8
+ type AgentSummary,
9
+ mockListAgentsHandler,
11
10
  } from '@contractspec/example.agent-console/handlers';
11
+ import type { PresentationSpec } from '@contractspec/lib.contracts-spec/presentations';
12
+ import type { PresentationRenderer } from '@contractspec/lib.contracts-spec/presentations/transform-engine';
12
13
 
13
14
  type Agent = AgentSummary;
14
15
 
@@ -17,66 +18,66 @@ type Agent = AgentSummary;
17
18
  * Only handles AgentListView component
18
19
  */
19
20
  export const agentListMarkdownRenderer: PresentationRenderer<{
20
- mimeType: string;
21
- body: string;
21
+ mimeType: string;
22
+ body: string;
22
23
  }> = {
23
- target: 'markdown',
24
- render: async (desc: PresentationSpec) => {
25
- // Only handle AgentListView
26
- if (
27
- desc.source.type !== 'component' ||
28
- desc.source.componentKey !== 'AgentListView'
29
- ) {
30
- throw new Error('agentListMarkdownRenderer: not AgentListView');
31
- }
24
+ target: 'markdown',
25
+ render: async (desc: PresentationSpec) => {
26
+ // Only handle AgentListView
27
+ if (
28
+ desc.source.type !== 'component' ||
29
+ desc.source.componentKey !== 'AgentListView'
30
+ ) {
31
+ throw new Error('agentListMarkdownRenderer: not AgentListView');
32
+ }
32
33
 
33
- // Fetch data using mock handler
34
- const data = await mockListAgentsHandler({
35
- organizationId: 'demo-org',
36
- limit: 50,
37
- offset: 0,
38
- });
34
+ // Fetch data using mock handler
35
+ const data = await mockListAgentsHandler({
36
+ organizationId: 'demo-org',
37
+ limit: 50,
38
+ offset: 0,
39
+ });
39
40
 
40
- // Generate markdown
41
- const lines: string[] = [
42
- `# ${desc.meta.description ?? 'Agent List'}`,
43
- '',
44
- `> ${desc.meta.key} v${desc.meta.version}`,
45
- '',
46
- `**Total Agents:** ${data.total}`,
47
- '',
48
- '## Agents',
49
- '',
50
- ];
41
+ // Generate markdown
42
+ const lines: string[] = [
43
+ `# ${desc.meta.description ?? 'Agent List'}`,
44
+ '',
45
+ `> ${desc.meta.key} v${desc.meta.version}`,
46
+ '',
47
+ `**Total Agents:** ${data.total}`,
48
+ '',
49
+ '## Agents',
50
+ '',
51
+ ];
51
52
 
52
- // Group by status
53
- const byStatus: Record<string, Agent[]> = {};
54
- for (const agent of data.items) {
55
- const status = agent.status;
56
- if (byStatus[status]) {
57
- byStatus[status].push(agent);
58
- } else {
59
- byStatus[status] = [agent];
60
- }
61
- }
53
+ // Group by status
54
+ const byStatus: Record<string, Agent[]> = {};
55
+ for (const agent of data.items) {
56
+ const status = agent.status;
57
+ if (byStatus[status]) {
58
+ byStatus[status].push(agent);
59
+ } else {
60
+ byStatus[status] = [agent];
61
+ }
62
+ }
62
63
 
63
- for (const [status, agents] of Object.entries(byStatus)) {
64
- lines.push(`### ${status} (${agents.length})`);
65
- lines.push('');
66
- for (const agent of agents) {
67
- lines.push(
68
- `- **${agent.name}** (${agent.modelProvider}/${agent.modelName})`
69
- );
70
- if (agent.description) {
71
- lines.push(` > ${agent.description}`);
72
- }
73
- }
74
- lines.push('');
75
- }
64
+ for (const [status, agents] of Object.entries(byStatus)) {
65
+ lines.push(`### ${status} (${agents.length})`);
66
+ lines.push('');
67
+ for (const agent of agents) {
68
+ lines.push(
69
+ `- **${agent.name}** (${agent.modelProvider}/${agent.modelName})`
70
+ );
71
+ if (agent.description) {
72
+ lines.push(` > ${agent.description}`);
73
+ }
74
+ }
75
+ lines.push('');
76
+ }
76
77
 
77
- return {
78
- mimeType: 'text/markdown',
79
- body: lines.join('\n'),
80
- };
81
- },
78
+ return {
79
+ mimeType: 'text/markdown',
80
+ body: lines.join('\n'),
81
+ };
82
+ },
82
83
  };
@@ -9,17 +9,17 @@ import { AgentListView } from '../views/AgentListView';
9
9
  * React renderer for agent-console.agent.list presentation
10
10
  */
11
11
  export const agentListReactRenderer: PresentationRenderer<React.ReactElement> =
12
- {
13
- target: 'react',
14
- render: async (desc: PresentationSpec) => {
15
- if (desc.source.type !== 'component') {
16
- throw new Error('AgentListRenderer: expected component source');
17
- }
18
- if (desc.source.componentKey !== 'AgentListView') {
19
- throw new Error(
20
- `AgentListRenderer: unknown component ${desc.source.componentKey}`
21
- );
22
- }
23
- return <AgentListView />;
24
- },
25
- };
12
+ {
13
+ target: 'react',
14
+ render: async (desc: PresentationSpec) => {
15
+ if (desc.source.type !== 'component') {
16
+ throw new Error('AgentListRenderer: expected component source');
17
+ }
18
+ if (desc.source.componentKey !== 'AgentListView') {
19
+ throw new Error(
20
+ `AgentListRenderer: unknown component ${desc.source.componentKey}`
21
+ );
22
+ }
23
+ return <AgentListView />;
24
+ },
25
+ };
@@ -3,18 +3,19 @@
3
3
  *
4
4
  * Provides a comprehensive overview of agents, runs, and tools.
5
5
  */
6
- import type { PresentationSpec } from '@contractspec/lib.contracts-spec/presentations';
7
- import type { PresentationRenderer } from '@contractspec/lib.contracts-spec/presentations/transform-engine';
6
+
8
7
  import {
9
- mockListAgentsHandler,
10
- mockListRunsHandler,
11
- mockListToolsHandler,
8
+ mockListAgentsHandler,
9
+ mockListRunsHandler,
10
+ mockListToolsHandler,
12
11
  } from '@contractspec/example.agent-console/handlers';
12
+ import type { PresentationSpec } from '@contractspec/lib.contracts-spec/presentations';
13
+ import type { PresentationRenderer } from '@contractspec/lib.contracts-spec/presentations/transform-engine';
13
14
 
14
15
  function formatDuration(ms: number): string {
15
- if (ms < 1000) return `${ms}ms`;
16
- if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
17
- return `${(ms / 60000).toFixed(1)}m`;
16
+ if (ms < 1000) return `${ms}ms`;
17
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
18
+ return `${(ms / 60000).toFixed(1)}m`;
18
19
  }
19
20
 
20
21
  /**
@@ -22,146 +23,146 @@ function formatDuration(ms: number): string {
22
23
  * Only handles AgentConsoleDashboard component
23
24
  */
24
25
  export const agentDashboardMarkdownRenderer: PresentationRenderer<{
25
- mimeType: string;
26
- body: string;
26
+ mimeType: string;
27
+ body: string;
27
28
  }> = {
28
- target: 'markdown',
29
- render: async (desc: PresentationSpec) => {
30
- // Only handle AgentConsoleDashboard
31
- if (
32
- desc.source.type !== 'component' ||
33
- desc.source.componentKey !== 'AgentConsoleDashboard'
34
- ) {
35
- throw new Error(
36
- 'agentDashboardMarkdownRenderer: not AgentConsoleDashboard'
37
- );
38
- }
29
+ target: 'markdown',
30
+ render: async (desc: PresentationSpec) => {
31
+ // Only handle AgentConsoleDashboard
32
+ if (
33
+ desc.source.type !== 'component' ||
34
+ desc.source.componentKey !== 'AgentConsoleDashboard'
35
+ ) {
36
+ throw new Error(
37
+ 'agentDashboardMarkdownRenderer: not AgentConsoleDashboard'
38
+ );
39
+ }
39
40
 
40
- // Fetch all data in parallel
41
- const [agentsData, runsData, toolsData] = await Promise.all([
42
- mockListAgentsHandler({
43
- organizationId: 'demo-org',
44
- limit: 100,
45
- }),
46
- mockListRunsHandler({
47
- limit: 100,
48
- }),
49
- mockListToolsHandler({
50
- organizationId: 'demo-org',
51
- limit: 100,
52
- }),
53
- ]);
41
+ // Fetch all data in parallel
42
+ const [agentsData, runsData, toolsData] = await Promise.all([
43
+ mockListAgentsHandler({
44
+ organizationId: 'demo-org',
45
+ limit: 100,
46
+ }),
47
+ mockListRunsHandler({
48
+ limit: 100,
49
+ }),
50
+ mockListToolsHandler({
51
+ organizationId: 'demo-org',
52
+ limit: 100,
53
+ }),
54
+ ]);
54
55
 
55
- // Calculate stats
56
- const activeAgents = agentsData.items.filter(
57
- (a) => a.status === 'ACTIVE'
58
- ).length;
59
- const completedRuns = runsData.items.filter(
60
- (r) => r.status === 'COMPLETED'
61
- ).length;
62
- const failedRuns = runsData.items.filter(
63
- (r) => r.status === 'FAILED'
64
- ).length;
65
- const totalTokens = runsData.items.reduce(
66
- (sum, r) => sum + (r.totalTokens ?? 0),
67
- 0
68
- );
69
- const totalCost = runsData.items.reduce(
70
- (sum, r) => sum + (r.estimatedCostUsd ?? 0),
71
- 0
72
- );
73
- const activeTools = toolsData.items.filter(
74
- (t) => t.status === 'ACTIVE'
75
- ).length;
56
+ // Calculate stats
57
+ const activeAgents = agentsData.items.filter(
58
+ (a) => a.status === 'ACTIVE'
59
+ ).length;
60
+ const completedRuns = runsData.items.filter(
61
+ (r) => r.status === 'COMPLETED'
62
+ ).length;
63
+ const failedRuns = runsData.items.filter(
64
+ (r) => r.status === 'FAILED'
65
+ ).length;
66
+ const totalTokens = runsData.items.reduce(
67
+ (sum, r) => sum + (r.totalTokens ?? 0),
68
+ 0
69
+ );
70
+ const totalCost = runsData.items.reduce(
71
+ (sum, r) => sum + (r.estimatedCostUsd ?? 0),
72
+ 0
73
+ );
74
+ const activeTools = toolsData.items.filter(
75
+ (t) => t.status === 'ACTIVE'
76
+ ).length;
76
77
 
77
- // Build dashboard markdown
78
- const lines: string[] = [
79
- '# Agent Console Dashboard',
80
- '',
81
- '> AI agent operations overview',
82
- '',
83
- '## Summary',
84
- '',
85
- '| Metric | Value |',
86
- '|--------|-------|',
87
- `| Total Agents | ${agentsData.total} |`,
88
- `| Active Agents | ${activeAgents} |`,
89
- `| Total Runs | ${runsData.total} |`,
90
- `| Completed Runs | ${completedRuns} |`,
91
- `| Failed Runs | ${failedRuns} |`,
92
- `| Total Tokens | ${totalTokens.toLocaleString()} |`,
93
- `| Total Cost | $${totalCost.toFixed(4)} |`,
94
- `| Total Tools | ${toolsData.total} |`,
95
- `| Active Tools | ${activeTools} |`,
96
- '',
97
- '## Agents',
98
- '',
99
- ];
78
+ // Build dashboard markdown
79
+ const lines: string[] = [
80
+ '# Agent Console Dashboard',
81
+ '',
82
+ '> AI agent operations overview',
83
+ '',
84
+ '## Summary',
85
+ '',
86
+ '| Metric | Value |',
87
+ '|--------|-------|',
88
+ `| Total Agents | ${agentsData.total} |`,
89
+ `| Active Agents | ${activeAgents} |`,
90
+ `| Total Runs | ${runsData.total} |`,
91
+ `| Completed Runs | ${completedRuns} |`,
92
+ `| Failed Runs | ${failedRuns} |`,
93
+ `| Total Tokens | ${totalTokens.toLocaleString()} |`,
94
+ `| Total Cost | $${totalCost.toFixed(4)} |`,
95
+ `| Total Tools | ${toolsData.total} |`,
96
+ `| Active Tools | ${activeTools} |`,
97
+ '',
98
+ '## Agents',
99
+ '',
100
+ ];
100
101
 
101
- // Agent list
102
- if (agentsData.items.length === 0) {
103
- lines.push('_No agents configured._');
104
- } else {
105
- lines.push('| Agent | Model | Status | Description |');
106
- lines.push('|-------|-------|--------|-------------|');
107
- for (const agent of agentsData.items.slice(0, 5)) {
108
- lines.push(
109
- `| ${agent.name} | ${agent.modelProvider}/${agent.modelName} | ${agent.status} | ${agent.description ?? '-'} |`
110
- );
111
- }
112
- if (agentsData.items.length > 5) {
113
- lines.push(`| ... | ... | ... | _${agentsData.total - 5} more_ |`);
114
- }
115
- }
102
+ // Agent list
103
+ if (agentsData.items.length === 0) {
104
+ lines.push('_No agents configured._');
105
+ } else {
106
+ lines.push('| Agent | Model | Status | Description |');
107
+ lines.push('|-------|-------|--------|-------------|');
108
+ for (const agent of agentsData.items.slice(0, 5)) {
109
+ lines.push(
110
+ `| ${agent.name} | ${agent.modelProvider}/${agent.modelName} | ${agent.status} | ${agent.description ?? '-'} |`
111
+ );
112
+ }
113
+ if (agentsData.items.length > 5) {
114
+ lines.push(`| ... | ... | ... | _${agentsData.total - 5} more_ |`);
115
+ }
116
+ }
116
117
 
117
- lines.push('');
118
- lines.push('## Recent Runs');
119
- lines.push('');
118
+ lines.push('');
119
+ lines.push('## Recent Runs');
120
+ lines.push('');
120
121
 
121
- // Recent runs
122
- if (runsData.items.length === 0) {
123
- lines.push('_No runs yet._');
124
- } else {
125
- lines.push('| Run ID | Agent | Status | Duration | Tokens | Cost |');
126
- lines.push('|--------|-------|--------|----------|--------|------|');
127
- for (const run of runsData.items.slice(0, 5)) {
128
- lines.push(
129
- `| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration(run.durationMs) : '-'} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`
130
- );
131
- }
132
- if (runsData.items.length > 5) {
133
- lines.push(
134
- `| ... | ... | ... | ... | ... | _${runsData.total - 5} more_ |`
135
- );
136
- }
137
- }
122
+ // Recent runs
123
+ if (runsData.items.length === 0) {
124
+ lines.push('_No runs yet._');
125
+ } else {
126
+ lines.push('| Run ID | Agent | Status | Duration | Tokens | Cost |');
127
+ lines.push('|--------|-------|--------|----------|--------|------|');
128
+ for (const run of runsData.items.slice(0, 5)) {
129
+ lines.push(
130
+ `| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration(run.durationMs) : '-'} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`
131
+ );
132
+ }
133
+ if (runsData.items.length > 5) {
134
+ lines.push(
135
+ `| ... | ... | ... | ... | ... | _${runsData.total - 5} more_ |`
136
+ );
137
+ }
138
+ }
138
139
 
139
- lines.push('');
140
- lines.push('## Tools');
141
- lines.push('');
140
+ lines.push('');
141
+ lines.push('## Tools');
142
+ lines.push('');
142
143
 
143
- // Tool categories
144
- const toolsByCategory: Record<string, typeof toolsData.items> = {};
145
- for (const tool of toolsData.items) {
146
- const cat = tool.category;
147
- if (!toolsByCategory[cat]) toolsByCategory[cat] = [];
148
- toolsByCategory[cat].push(tool);
149
- }
144
+ // Tool categories
145
+ const toolsByCategory: Record<string, typeof toolsData.items> = {};
146
+ for (const tool of toolsData.items) {
147
+ const cat = tool.category;
148
+ if (!toolsByCategory[cat]) toolsByCategory[cat] = [];
149
+ toolsByCategory[cat].push(tool);
150
+ }
150
151
 
151
- if (Object.keys(toolsByCategory).length === 0) {
152
- lines.push('_No tools registered._');
153
- } else {
154
- lines.push('| Category | Tools | Active |');
155
- lines.push('|----------|-------|--------|');
156
- for (const [category, tools] of Object.entries(toolsByCategory).sort()) {
157
- const active = tools.filter((t) => t.status === 'ACTIVE').length;
158
- lines.push(`| ${category} | ${tools.length} | ${active} |`);
159
- }
160
- }
152
+ if (Object.keys(toolsByCategory).length === 0) {
153
+ lines.push('_No tools registered._');
154
+ } else {
155
+ lines.push('| Category | Tools | Active |');
156
+ lines.push('|----------|-------|--------|');
157
+ for (const [category, tools] of Object.entries(toolsByCategory).sort()) {
158
+ const active = tools.filter((t) => t.status === 'ACTIVE').length;
159
+ lines.push(`| ${category} | ${tools.length} | ${active} |`);
160
+ }
161
+ }
161
162
 
162
- return {
163
- mimeType: 'text/markdown',
164
- body: lines.join('\n'),
165
- };
166
- },
163
+ return {
164
+ mimeType: 'text/markdown',
165
+ body: lines.join('\n'),
166
+ };
167
+ },
167
168
  };
@@ -2,11 +2,10 @@
2
2
  * Renderers for agent-console presentations
3
3
  */
4
4
 
5
- // React renderers
6
- export { agentListReactRenderer } from './agent-list.renderer';
7
-
8
5
  // Markdown renderers
9
6
  export { agentListMarkdownRenderer } from './agent-list.markdown';
7
+ // React renderers
8
+ export { agentListReactRenderer } from './agent-list.renderer';
9
+ export { agentDashboardMarkdownRenderer } from './dashboard.markdown';
10
10
  export { runListMarkdownRenderer } from './run-list.markdown';
11
11
  export { toolRegistryMarkdownRenderer } from './tool-registry.markdown';
12
- export { agentDashboardMarkdownRenderer } from './dashboard.markdown';
@@ -3,21 +3,22 @@
3
3
  *
4
4
  * Uses dynamic import for handlers to ensure correct build order.
5
5
  */
6
+
7
+ import { mockListRunsHandler } from '@contractspec/example.agent-console/handlers';
6
8
  import type { PresentationSpec } from '@contractspec/lib.contracts-spec/presentations';
7
9
  import type { PresentationRenderer } from '@contractspec/lib.contracts-spec/presentations/transform-engine';
8
10
  import type { Run } from '../hooks/useRunList';
9
- import { mockListRunsHandler } from '@contractspec/example.agent-console/handlers';
10
11
 
11
12
  interface RunListOutput {
12
- items: Run[];
13
- total: number;
14
- hasMore: boolean;
13
+ items: Run[];
14
+ total: number;
15
+ hasMore: boolean;
15
16
  }
16
17
 
17
18
  function formatDuration(ms: number): string {
18
- if (ms < 1000) return `${ms}ms`;
19
- if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
20
- return `${(ms / 60000).toFixed(1)}m`;
19
+ if (ms < 1000) return `${ms}ms`;
20
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
21
+ return `${(ms / 60000).toFixed(1)}m`;
21
22
  }
22
23
 
23
24
  /**
@@ -25,49 +26,49 @@ function formatDuration(ms: number): string {
25
26
  * Only handles RunListView component
26
27
  */
27
28
  export const runListMarkdownRenderer: PresentationRenderer<{
28
- mimeType: string;
29
- body: string;
29
+ mimeType: string;
30
+ body: string;
30
31
  }> = {
31
- target: 'markdown',
32
- render: async (desc: PresentationSpec) => {
33
- // Only handle RunListView
34
- if (
35
- desc.source.type !== 'component' ||
36
- desc.source.componentKey !== 'RunListView'
37
- ) {
38
- throw new Error('runListMarkdownRenderer: not RunListView');
39
- }
32
+ target: 'markdown',
33
+ render: async (desc: PresentationSpec) => {
34
+ // Only handle RunListView
35
+ if (
36
+ desc.source.type !== 'component' ||
37
+ desc.source.componentKey !== 'RunListView'
38
+ ) {
39
+ throw new Error('runListMarkdownRenderer: not RunListView');
40
+ }
40
41
 
41
- // Fetch data using mock handler
42
- const data = (await mockListRunsHandler({
43
- organizationId: 'demo-org',
44
- limit: 20,
45
- offset: 0,
46
- })) as RunListOutput;
42
+ // Fetch data using mock handler
43
+ const data = (await mockListRunsHandler({
44
+ organizationId: 'demo-org',
45
+ limit: 20,
46
+ offset: 0,
47
+ })) as RunListOutput;
47
48
 
48
- // Generate markdown
49
- const lines: string[] = [
50
- `# ${desc.meta.description ?? 'Agent Runs'}`,
51
- '',
52
- `> ${desc.meta.key} v${desc.meta.version}`,
53
- '',
54
- `**Total Runs:** ${data.total}`,
55
- '',
56
- '## Recent Runs',
57
- '',
58
- '| ID | Agent | Status | Duration | Tokens | Cost |',
59
- '| --- | --- | --- | --- | --- | --- |',
60
- ];
49
+ // Generate markdown
50
+ const lines: string[] = [
51
+ `# ${desc.meta.description ?? 'Agent Runs'}`,
52
+ '',
53
+ `> ${desc.meta.key} v${desc.meta.version}`,
54
+ '',
55
+ `**Total Runs:** ${data.total}`,
56
+ '',
57
+ '## Recent Runs',
58
+ '',
59
+ '| ID | Agent | Status | Duration | Tokens | Cost |',
60
+ '| --- | --- | --- | --- | --- | --- |',
61
+ ];
61
62
 
62
- for (const run of data.items.slice(0, 10)) {
63
- lines.push(
64
- `| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration(run.durationMs) : '-'} | ${run.totalTokens} | $${run.estimatedCostUsd?.toFixed(4) ?? '-'} |`
65
- );
66
- }
63
+ for (const run of data.items.slice(0, 10)) {
64
+ lines.push(
65
+ `| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration(run.durationMs) : '-'} | ${run.totalTokens} | $${run.estimatedCostUsd?.toFixed(4) ?? '-'} |`
66
+ );
67
+ }
67
68
 
68
- return {
69
- mimeType: 'text/markdown',
70
- body: lines.join('\n'),
71
- };
72
- },
69
+ return {
70
+ mimeType: 'text/markdown',
71
+ body: lines.join('\n'),
72
+ };
73
+ },
73
74
  };