@contractspec/example.agent-console 3.7.7 → 3.8.4

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 (191) hide show
  1. package/.turbo/turbo-build.log +126 -105
  2. package/AGENTS.md +3 -1
  3. package/CHANGELOG.md +57 -0
  4. package/README.md +46 -9
  5. package/dist/agent/agent.handler.d.ts +3 -0
  6. package/dist/agent/agent.handler.js +730 -1
  7. package/dist/agent/index.js +73 -72
  8. package/dist/agent.feature.js +179 -0
  9. package/dist/browser/agent/agent.handler.js +730 -1
  10. package/dist/browser/agent/index.js +73 -72
  11. package/dist/browser/agent.feature.js +179 -0
  12. package/dist/browser/docs/agent-console.docblock.js +11 -8
  13. package/dist/browser/docs/index.js +11 -8
  14. package/dist/browser/example.js +2 -3
  15. package/dist/browser/handlers/agent.handlers.js +1883 -2
  16. package/dist/browser/handlers/index.js +2142 -8
  17. package/dist/browser/index.js +3347 -2433
  18. package/dist/browser/presentations/index.js +49 -49
  19. package/dist/browser/run/index.js +818 -812
  20. package/dist/browser/run/run.handler.js +666 -1
  21. package/dist/browser/shared/index.js +293 -1
  22. package/dist/browser/shared/mock-runs.js +5 -0
  23. package/dist/browser/tool/index.js +331 -331
  24. package/dist/browser/tool/tool.handler.js +479 -3
  25. package/dist/browser/ui/AgentDashboard.js +1204 -319
  26. package/dist/browser/ui/AgentDashboard.visualizations.js +217 -0
  27. package/dist/browser/ui/AgentRunList.js +359 -127
  28. package/dist/browser/ui/hooks/index.js +468 -18
  29. package/dist/browser/ui/hooks/useAgentMutations.js +443 -8
  30. package/dist/browser/ui/hooks/useRunList.js +25 -10
  31. package/dist/browser/ui/index.js +1293 -390
  32. package/dist/browser/ui/renderers/agent-list.markdown.js +14 -5
  33. package/dist/browser/ui/renderers/dashboard.markdown.js +207 -36
  34. package/dist/browser/ui/renderers/index.js +245 -49
  35. package/dist/browser/ui/renderers/run-list.markdown.js +9 -4
  36. package/dist/browser/ui/renderers/tool-registry.markdown.js +15 -4
  37. package/dist/browser/ui/views/RunDataTable.js +326 -0
  38. package/dist/browser/ui/views/RunListView.js +359 -127
  39. package/dist/browser/ui/views/index.js +406 -174
  40. package/dist/browser/ui/views/run-data-table.columns.js +271 -0
  41. package/dist/browser/ui/views/run-list.shared.js +177 -0
  42. package/dist/browser/visualizations/catalog.js +134 -0
  43. package/dist/browser/visualizations/index.js +187 -0
  44. package/dist/browser/visualizations/selectors.js +181 -0
  45. package/dist/docs/agent-console.docblock.js +11 -8
  46. package/dist/docs/index.js +11 -8
  47. package/dist/example.js +2 -3
  48. package/dist/example.test.d.ts +1 -0
  49. package/dist/handlers/agent.handlers.d.ts +2 -0
  50. package/dist/handlers/agent.handlers.js +1883 -2
  51. package/dist/handlers/index.d.ts +1 -3
  52. package/dist/handlers/index.js +2142 -8
  53. package/dist/handlers/mock-handlers.test.d.ts +1 -0
  54. package/dist/index.d.ts +2 -0
  55. package/dist/index.js +3347 -2433
  56. package/dist/node/agent/agent.handler.js +730 -1
  57. package/dist/node/agent/index.js +73 -72
  58. package/dist/node/agent.feature.js +179 -0
  59. package/dist/node/docs/agent-console.docblock.js +11 -8
  60. package/dist/node/docs/index.js +11 -8
  61. package/dist/node/example.js +2 -3
  62. package/dist/node/handlers/agent.handlers.js +1883 -2
  63. package/dist/node/handlers/index.js +2142 -8
  64. package/dist/node/index.js +3347 -2433
  65. package/dist/node/presentations/index.js +49 -49
  66. package/dist/node/run/index.js +818 -812
  67. package/dist/node/run/run.handler.js +666 -1
  68. package/dist/node/shared/index.js +293 -1
  69. package/dist/node/shared/mock-runs.js +5 -0
  70. package/dist/node/tool/index.js +331 -331
  71. package/dist/node/tool/tool.handler.js +479 -3
  72. package/dist/node/ui/AgentDashboard.js +1204 -319
  73. package/dist/node/ui/AgentDashboard.visualizations.js +217 -0
  74. package/dist/node/ui/AgentRunList.js +359 -127
  75. package/dist/node/ui/hooks/index.js +468 -18
  76. package/dist/node/ui/hooks/useAgentMutations.js +443 -8
  77. package/dist/node/ui/hooks/useRunList.js +25 -10
  78. package/dist/node/ui/index.js +1293 -390
  79. package/dist/node/ui/renderers/agent-list.markdown.js +14 -5
  80. package/dist/node/ui/renderers/dashboard.markdown.js +207 -36
  81. package/dist/node/ui/renderers/index.js +245 -49
  82. package/dist/node/ui/renderers/run-list.markdown.js +9 -4
  83. package/dist/node/ui/renderers/tool-registry.markdown.js +15 -4
  84. package/dist/node/ui/views/RunDataTable.js +326 -0
  85. package/dist/node/ui/views/RunListView.js +359 -127
  86. package/dist/node/ui/views/index.js +406 -174
  87. package/dist/node/ui/views/run-data-table.columns.js +271 -0
  88. package/dist/node/ui/views/run-list.shared.js +177 -0
  89. package/dist/node/visualizations/catalog.js +134 -0
  90. package/dist/node/visualizations/index.js +187 -0
  91. package/dist/node/visualizations/selectors.js +181 -0
  92. package/dist/presentations/index.js +49 -49
  93. package/dist/proof/index.d.ts +2 -0
  94. package/dist/proof/meetup-proof.d.ts +10 -0
  95. package/dist/proof/meetup-proof.runtime.d.ts +22 -0
  96. package/dist/proof/meetup-proof.scenario.d.ts +2 -0
  97. package/dist/proof/meetup-proof.suite.d.ts +1 -0
  98. package/dist/proof/meetup-proof.test.d.ts +1 -0
  99. package/dist/run/index.js +818 -812
  100. package/dist/run/run.handler.d.ts +4 -0
  101. package/dist/run/run.handler.js +666 -1
  102. package/dist/shared/demo-dashboard-data.d.ts +16 -0
  103. package/dist/shared/demo-runtime-seed.d.ts +17 -0
  104. package/dist/shared/demo-runtime.d.ts +8 -0
  105. package/dist/shared/demo-runtime.test.d.ts +1 -0
  106. package/dist/shared/index.d.ts +3 -0
  107. package/dist/shared/index.js +293 -1
  108. package/dist/shared/mock-runs.d.ts +4 -0
  109. package/dist/shared/mock-runs.js +5 -0
  110. package/dist/tool/index.js +331 -331
  111. package/dist/tool/tool.handler.d.ts +4 -1
  112. package/dist/tool/tool.handler.js +479 -3
  113. package/dist/ui/AgentDashboard.js +1204 -319
  114. package/dist/ui/AgentDashboard.sandbox.test.d.ts +1 -0
  115. package/dist/ui/AgentDashboard.visualizations.d.ts +4 -0
  116. package/dist/ui/AgentDashboard.visualizations.js +218 -0
  117. package/dist/ui/AgentRunList.js +359 -127
  118. package/dist/ui/hooks/index.js +468 -18
  119. package/dist/ui/hooks/useAgentMutations.js +443 -8
  120. package/dist/ui/hooks/useRunList.d.ts +8 -2
  121. package/dist/ui/hooks/useRunList.js +25 -10
  122. package/dist/ui/index.js +1293 -390
  123. package/dist/ui/renderers/agent-list.markdown.d.ts +1 -1
  124. package/dist/ui/renderers/agent-list.markdown.js +14 -5
  125. package/dist/ui/renderers/agent-list.renderer.d.ts +1 -1
  126. package/dist/ui/renderers/dashboard.markdown.d.ts +1 -1
  127. package/dist/ui/renderers/dashboard.markdown.js +207 -36
  128. package/dist/ui/renderers/index.js +245 -49
  129. package/dist/ui/renderers/run-list.markdown.d.ts +1 -1
  130. package/dist/ui/renderers/run-list.markdown.js +9 -4
  131. package/dist/ui/renderers/tool-registry.markdown.d.ts +2 -2
  132. package/dist/ui/renderers/tool-registry.markdown.js +15 -4
  133. package/dist/ui/views/RunDataTable.d.ts +18 -0
  134. package/dist/ui/views/RunDataTable.js +327 -0
  135. package/dist/ui/views/RunListView.js +359 -127
  136. package/dist/ui/views/index.js +406 -174
  137. package/dist/ui/views/run-data-table.columns.d.ts +3 -0
  138. package/dist/ui/views/run-data-table.columns.js +272 -0
  139. package/dist/ui/views/run-list.shared.d.ts +14 -0
  140. package/dist/ui/views/run-list.shared.js +178 -0
  141. package/dist/visualizations/catalog.d.ts +10 -0
  142. package/dist/visualizations/catalog.js +135 -0
  143. package/dist/visualizations/index.d.ts +2 -0
  144. package/dist/visualizations/index.js +188 -0
  145. package/dist/visualizations/selectors.d.ts +3 -0
  146. package/dist/visualizations/selectors.js +182 -0
  147. package/dist/visualizations/selectors.test.d.ts +1 -0
  148. package/package.json +114 -11
  149. package/proofs/agent-console-meetup.replay.json +220 -0
  150. package/src/agent/agent.handler.ts +18 -1
  151. package/src/agent.feature.ts +3 -0
  152. package/src/docs/agent-console.docblock.ts +11 -8
  153. package/src/example.test.ts +75 -0
  154. package/src/example.ts +2 -3
  155. package/src/handlers/agent.handlers.ts +55 -2
  156. package/src/handlers/index.ts +18 -2
  157. package/src/handlers/mock-handlers.test.ts +77 -0
  158. package/src/index.ts +2 -0
  159. package/src/proof/index.ts +2 -0
  160. package/src/proof/meetup-proof.runtime.ts +196 -0
  161. package/src/proof/meetup-proof.scenario.ts +99 -0
  162. package/src/proof/meetup-proof.suite.ts +29 -0
  163. package/src/proof/meetup-proof.test.ts +28 -0
  164. package/src/proof/meetup-proof.ts +130 -0
  165. package/src/run/run.handler.ts +17 -1
  166. package/src/shared/demo-dashboard-data.ts +58 -0
  167. package/src/shared/demo-runtime-seed.ts +139 -0
  168. package/src/shared/demo-runtime.test.ts +169 -0
  169. package/src/shared/demo-runtime.ts +260 -0
  170. package/src/shared/index.ts +11 -0
  171. package/src/shared/mock-runs.ts +5 -0
  172. package/src/tool/tool.handler.ts +21 -4
  173. package/src/ui/AgentDashboard.sandbox.test.tsx +312 -0
  174. package/src/ui/AgentDashboard.tsx +4 -1
  175. package/src/ui/AgentDashboard.visualizations.tsx +35 -0
  176. package/src/ui/hooks/useAgentMutations.ts +19 -11
  177. package/src/ui/hooks/useRunList.ts +41 -9
  178. package/src/ui/renderers/agent-list.markdown.ts +32 -13
  179. package/src/ui/renderers/agent-list.renderer.tsx +1 -1
  180. package/src/ui/renderers/dashboard.markdown.ts +38 -43
  181. package/src/ui/renderers/run-list.markdown.ts +17 -9
  182. package/src/ui/renderers/tool-registry.markdown.ts +22 -10
  183. package/src/ui/views/RunDataTable.tsx +74 -0
  184. package/src/ui/views/RunListView.tsx +37 -111
  185. package/src/ui/views/run-data-table.columns.tsx +102 -0
  186. package/src/ui/views/run-list.shared.tsx +139 -0
  187. package/src/visualizations/catalog.ts +132 -0
  188. package/src/visualizations/index.ts +2 -0
  189. package/src/visualizations/selectors.test.ts +12 -0
  190. package/src/visualizations/selectors.ts +70 -0
  191. package/tsdown.config.js +17 -0
@@ -0,0 +1,196 @@
1
+ import type {
2
+ HarnessArtifactQuery,
3
+ HarnessArtifactStore,
4
+ HarnessExecutionAdapter,
5
+ HarnessStoredArtifact,
6
+ } from '@contractspec/lib.harness';
7
+ import type { AgentHandlers, Run } from '../handlers/agent.handlers';
8
+ import { getAgentConsoleDashboardData } from '../shared/demo-dashboard-data';
9
+ import { MEETUP_AGENT_NAME } from './meetup-proof.scenario';
10
+
11
+ export class MemoryArtifactStore implements HarnessArtifactStore {
12
+ private readonly items: HarnessStoredArtifact[] = [];
13
+
14
+ async put(artifact: HarnessStoredArtifact) {
15
+ this.items.push(artifact);
16
+ return artifact;
17
+ }
18
+
19
+ async get(artifactId: string) {
20
+ return this.items.find((artifact) => artifact.artifactId === artifactId);
21
+ }
22
+
23
+ async list(query: HarnessArtifactQuery = {}) {
24
+ return this.items.filter((artifact) => {
25
+ if (query.runId && artifact.runId !== query.runId) return false;
26
+ if (query.stepId && artifact.stepId !== query.stepId) return false;
27
+ if (query.kind && artifact.kind !== query.kind) return false;
28
+ return true;
29
+ });
30
+ }
31
+ }
32
+
33
+ export function createProofNow() {
34
+ let tick = 0;
35
+ const base = Date.parse('2026-03-20T09:30:00.000Z');
36
+ return () => new Date(base + tick++ * 60_000);
37
+ }
38
+
39
+ export function createProofIdFactory(prefix: string) {
40
+ let index = 0;
41
+ return () => `${prefix}-${++index}`;
42
+ }
43
+
44
+ export function createMeetupEntityIdFactory() {
45
+ const counters = { agent: 0, run: 0 };
46
+ return (kind: 'agent' | 'run') => `${kind}-meetup-${++counters[kind]}`;
47
+ }
48
+
49
+ interface MeetupExecutionState {
50
+ agentId: string;
51
+ runId: string;
52
+ }
53
+
54
+ function buildRunSummary(run: Run) {
55
+ return {
56
+ status: 'completed' as const,
57
+ summary: `Executed ${run.agentName} and completed ${run.id}.`,
58
+ output: {
59
+ runId: run.id,
60
+ status: run.status,
61
+ totalTokens: run.totalTokens,
62
+ },
63
+ artifacts: [
64
+ {
65
+ kind: 'step-summary' as const,
66
+ summary: `Completed ${run.id} for ${run.agentName}`,
67
+ },
68
+ ],
69
+ };
70
+ }
71
+
72
+ export function createMeetupProofAdapter(input: {
73
+ handlers: AgentHandlers;
74
+ projectId: string;
75
+ organizationId: string;
76
+ state: MeetupExecutionState;
77
+ }): HarnessExecutionAdapter {
78
+ return {
79
+ mode: 'code-execution',
80
+ supports: () => true,
81
+ execute: async ({ step }) => {
82
+ const { handlers, projectId, organizationId, state } = input;
83
+ switch (step.key) {
84
+ case 'open-dashboard': {
85
+ const dashboard = await getAgentConsoleDashboardData(handlers, {
86
+ projectId,
87
+ organizationId,
88
+ });
89
+ return {
90
+ status: 'completed',
91
+ summary: `Seeded dashboard ready with ${dashboard.summary.totalAgents} agents, ${dashboard.summary.totalTools} tools, and ${dashboard.summary.totalRuns} runs.`,
92
+ output: {
93
+ agentCount: dashboard.summary.totalAgents,
94
+ runCount: dashboard.summary.totalRuns,
95
+ toolCount: dashboard.summary.totalTools,
96
+ },
97
+ artifacts: [
98
+ {
99
+ kind: 'step-summary',
100
+ summary: `Seeded dashboard agents=${dashboard.summary.totalAgents} tools=${dashboard.summary.totalTools} runs=${dashboard.summary.totalRuns}`,
101
+ },
102
+ ],
103
+ };
104
+ }
105
+ case 'create-agent': {
106
+ const agent = await handlers.createAgent(
107
+ {
108
+ name: MEETUP_AGENT_NAME,
109
+ description:
110
+ 'Offline-safe walkthrough agent for the Paris meetup.',
111
+ systemPrompt:
112
+ 'Demonstrate the deterministic ContractSpec meetup flow.',
113
+ },
114
+ { projectId, organizationId }
115
+ );
116
+ state.agentId = agent.id;
117
+ return {
118
+ status: 'completed',
119
+ summary: `Created ${agent.name} as ${agent.id}.`,
120
+ output: {
121
+ agentId: agent.id,
122
+ status: agent.status,
123
+ },
124
+ artifacts: [
125
+ {
126
+ kind: 'step-summary',
127
+ summary: `Created ${agent.name} (${agent.id})`,
128
+ },
129
+ ],
130
+ };
131
+ }
132
+ case 'activate-agent': {
133
+ const agent = await handlers.updateAgent({
134
+ id: state.agentId,
135
+ status: 'ACTIVE',
136
+ });
137
+ return {
138
+ status: 'completed',
139
+ summary: `Activated ${agent.name}.`,
140
+ output: {
141
+ agentId: agent.id,
142
+ status: agent.status,
143
+ },
144
+ artifacts: [
145
+ {
146
+ kind: 'step-summary',
147
+ summary: `Activated ${agent.name}`,
148
+ },
149
+ ],
150
+ };
151
+ }
152
+ case 'execute-agent': {
153
+ const run = await handlers.executeAgent({
154
+ agentId: state.agentId,
155
+ message: 'Summarize the meetup proof lane.',
156
+ context: { projectId, organizationId },
157
+ });
158
+ state.runId = run.id;
159
+ return buildRunSummary(run);
160
+ }
161
+ case 'inspect-dashboard': {
162
+ const [dashboard, metrics] = await Promise.all([
163
+ getAgentConsoleDashboardData(handlers, {
164
+ projectId,
165
+ organizationId,
166
+ }),
167
+ handlers.getRunMetrics({ projectId }),
168
+ ]);
169
+ return {
170
+ status: 'completed',
171
+ summary: `${MEETUP_AGENT_NAME} is visible with ${dashboard.summary.totalAgents} agents and ${dashboard.summary.totalRuns} runs.`,
172
+ output: {
173
+ agentCount: dashboard.summary.totalAgents,
174
+ runCount: dashboard.summary.totalRuns,
175
+ toolCount: dashboard.summary.totalTools,
176
+ latestAgentName: dashboard.agents[0]?.name ?? null,
177
+ latestRunId: dashboard.runs[0]?.id ?? null,
178
+ successRate: metrics.successRate,
179
+ },
180
+ artifacts: [
181
+ {
182
+ kind: 'step-summary',
183
+ summary: `Final dashboard agents=${dashboard.summary.totalAgents} runs=${dashboard.summary.totalRuns}`,
184
+ },
185
+ ],
186
+ };
187
+ }
188
+ default:
189
+ return {
190
+ status: 'failed',
191
+ summary: `Unknown meetup proof step ${step.key}.`,
192
+ };
193
+ }
194
+ },
195
+ };
196
+ }
@@ -0,0 +1,99 @@
1
+ import { defineHarnessScenario } from '@contractspec/lib.contracts-spec';
2
+ import { MOCK_AGENTS } from '../shared/mock-agents';
3
+ import { MOCK_RUNS } from '../shared/mock-runs';
4
+ import { MOCK_TOOLS } from '../shared/mock-tools';
5
+
6
+ export const MEETUP_AGENT_NAME = 'Paris Meetup Demo Agent';
7
+ const SEEDED_COMPLETED_RUNS = MOCK_RUNS.filter(
8
+ (run) => run.status === 'COMPLETED'
9
+ ).length;
10
+ const SUCCESS_RATE_AFTER_MEETUP_EXECUTION =
11
+ (SEEDED_COMPLETED_RUNS + 1) / (MOCK_RUNS.length + 1);
12
+
13
+ export const AGENT_CONSOLE_MEETUP_PROOF_SCENARIO = defineHarnessScenario({
14
+ meta: {
15
+ key: 'agent-console.meetup.proof',
16
+ version: '1.0.0',
17
+ title: 'Agent console meetup proof',
18
+ description:
19
+ 'Verifies the deterministic autonomous-agent walkthrough end-to-end.',
20
+ domain: 'agent-console',
21
+ owners: ['@agent-console-team'],
22
+ tags: ['meetup', 'proof', 'autonomous-agents'],
23
+ stability: 'experimental',
24
+ },
25
+ target: {
26
+ allowlistedDomains: ['sandbox.contractspec.local'],
27
+ isolation: 'sandbox',
28
+ },
29
+ allowedModes: ['code-execution'],
30
+ steps: [
31
+ {
32
+ key: 'open-dashboard',
33
+ description: 'Inspect seeded dashboard state',
34
+ actionClass: 'code-exec-read',
35
+ intent:
36
+ 'Confirm the local demo starts with seeded agents, tools, and runs.',
37
+ },
38
+ {
39
+ key: 'create-agent',
40
+ description: 'Create the meetup demo agent',
41
+ actionClass: 'code-exec-mutate',
42
+ intent: 'Add a new agent for the walkthrough.',
43
+ mutatesState: true,
44
+ },
45
+ {
46
+ key: 'activate-agent',
47
+ description: 'Activate the meetup demo agent',
48
+ actionClass: 'code-exec-mutate',
49
+ intent: 'Move the new agent into an executable state.',
50
+ mutatesState: true,
51
+ },
52
+ {
53
+ key: 'execute-agent',
54
+ description: 'Run the meetup demo agent',
55
+ actionClass: 'code-exec-mutate',
56
+ intent: 'Create a deterministic completed run.',
57
+ mutatesState: true,
58
+ },
59
+ {
60
+ key: 'inspect-dashboard',
61
+ description: 'Confirm dashboard totals after execution',
62
+ actionClass: 'code-exec-read',
63
+ intent: 'Verify the new agent and run are visible in the demo state.',
64
+ },
65
+ ],
66
+ assertions: [
67
+ {
68
+ key: 'captured-step-summaries',
69
+ type: 'count',
70
+ source: 'step-summary',
71
+ match: 5,
72
+ },
73
+ {
74
+ key: 'execution-completed',
75
+ type: 'step-status',
76
+ source: 'execute-agent',
77
+ match: 'completed',
78
+ },
79
+ {
80
+ key: 'final-summary-mentions-meetup-agent',
81
+ type: 'text-match',
82
+ source: 'inspect-dashboard',
83
+ match: MEETUP_AGENT_NAME,
84
+ },
85
+ {
86
+ key: 'final-dashboard-shape',
87
+ type: 'json-match',
88
+ source: 'inspect-dashboard',
89
+ match: {
90
+ agentCount: MOCK_AGENTS.length + 1,
91
+ runCount: MOCK_RUNS.length + 1,
92
+ toolCount: MOCK_TOOLS.length,
93
+ latestAgentName: MEETUP_AGENT_NAME,
94
+ latestRunId: 'run-meetup-1',
95
+ successRate: SUCCESS_RATE_AFTER_MEETUP_EXECUTION,
96
+ },
97
+ },
98
+ ],
99
+ });
@@ -0,0 +1,29 @@
1
+ import { defineHarnessSuite } from '@contractspec/lib.contracts-spec';
2
+ import { AGENT_CONSOLE_MEETUP_PROOF_SCENARIO } from './meetup-proof.scenario';
3
+
4
+ export const AgentConsoleMeetupProofSuite = defineHarnessSuite({
5
+ meta: {
6
+ key: 'agent-console.meetup.proof-suite',
7
+ version: '1.0.0',
8
+ title: 'Agent console meetup proof suite',
9
+ description:
10
+ 'Bundles the deterministic meetup walkthrough into a reusable harness suite.',
11
+ domain: 'agent-console',
12
+ owners: ['@agent-console-team'],
13
+ tags: ['meetup', 'proof', 'harness-suite'],
14
+ stability: 'experimental',
15
+ },
16
+ summary:
17
+ 'Runs the canonical agent-console meetup scenario and validates the final dashboard evidence.',
18
+ tags: ['agent-console', 'meetup', 'proof'],
19
+ scenarios: [
20
+ {
21
+ scenario: {
22
+ key: AGENT_CONSOLE_MEETUP_PROOF_SCENARIO.meta.key,
23
+ version: AGENT_CONSOLE_MEETUP_PROOF_SCENARIO.meta.version,
24
+ },
25
+ required: true,
26
+ weight: 1,
27
+ },
28
+ ],
29
+ });
@@ -0,0 +1,28 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ import { summarizeHarnessReplayBundle } from '@contractspec/lib.harness';
3
+ import { runAgentConsoleMeetupProof } from './meetup-proof';
4
+ import { AGENT_CONSOLE_MEETUP_PROOF_SCENARIO } from './meetup-proof.scenario';
5
+
6
+ describe('agent-console meetup proof', () => {
7
+ it('runs the canonical walkthrough and generates a replay bundle', async () => {
8
+ const result = await runAgentConsoleMeetupProof();
9
+ const summary = summarizeHarnessReplayBundle(result.replayBundle);
10
+
11
+ expect(result.evaluation.status).toBe('passed');
12
+ expect(
13
+ result.evaluation.assertions.every((item) => item.status === 'passed')
14
+ ).toBe(true);
15
+ expect(result.evaluation.run.scenarioKey).toBe(
16
+ AGENT_CONSOLE_MEETUP_PROOF_SCENARIO.meta.key
17
+ );
18
+ expect(result.replayUri).toBe('memory://agent-console-meetup-proof');
19
+ expect(summary.status).toBe('completed');
20
+ expect(summary.stepCount).toBe(
21
+ AGENT_CONSOLE_MEETUP_PROOF_SCENARIO.steps.length
22
+ );
23
+ expect(summary.artifactCount).toBe(
24
+ AGENT_CONSOLE_MEETUP_PROOF_SCENARIO.steps.length
25
+ );
26
+ expect(summary.failedAssertions).toBe(0);
27
+ });
28
+ });
@@ -0,0 +1,130 @@
1
+ import {
2
+ HarnessEvaluationRunner,
3
+ type HarnessReplayBundle,
4
+ type HarnessReplaySink,
5
+ HarnessRunner,
6
+ } from '@contractspec/lib.harness';
7
+ import { createAgentConsoleDemoHandlers } from '../shared/demo-runtime';
8
+ import {
9
+ AGENT_CONSOLE_DEMO_ORGANIZATION_ID,
10
+ AGENT_CONSOLE_DEMO_PROJECT_ID,
11
+ } from '../shared/demo-runtime-seed';
12
+ import {
13
+ createMeetupEntityIdFactory,
14
+ createMeetupProofAdapter,
15
+ createProofIdFactory,
16
+ createProofNow,
17
+ MemoryArtifactStore,
18
+ } from './meetup-proof.runtime';
19
+ import { AGENT_CONSOLE_MEETUP_PROOF_SCENARIO } from './meetup-proof.scenario';
20
+
21
+ function isHarnessReplayBundle(value: unknown): value is HarnessReplayBundle {
22
+ return (
23
+ typeof value === 'object' &&
24
+ value !== null &&
25
+ 'version' in value &&
26
+ 'run' in value &&
27
+ 'assertions' in value &&
28
+ 'artifacts' in value
29
+ );
30
+ }
31
+
32
+ export async function runAgentConsoleMeetupProof(input?: {
33
+ projectId?: string;
34
+ organizationId?: string;
35
+ replaySink?: HarnessReplaySink;
36
+ }) {
37
+ const projectId = input?.projectId ?? AGENT_CONSOLE_DEMO_PROJECT_ID;
38
+ const organizationId =
39
+ input?.organizationId ?? AGENT_CONSOLE_DEMO_ORGANIZATION_ID;
40
+ const harnessNow = createProofNow();
41
+ const handlers = createAgentConsoleDemoHandlers({
42
+ projectId,
43
+ organizationId,
44
+ now: createProofNow(),
45
+ idFactory: createMeetupEntityIdFactory(),
46
+ });
47
+ const executionState = {
48
+ agentId: '',
49
+ runId: '',
50
+ };
51
+ const artifactStore = new MemoryArtifactStore();
52
+ const replayUris: string[] = [];
53
+ let replayBundle: HarnessReplayBundle | null = null;
54
+ const adapter = createMeetupProofAdapter({
55
+ handlers,
56
+ projectId,
57
+ organizationId,
58
+ state: executionState,
59
+ });
60
+
61
+ const replaySink: HarnessReplaySink = {
62
+ async save(bundle: unknown) {
63
+ if (!isHarnessReplayBundle(bundle)) {
64
+ throw new Error('Replay sink received an invalid harness bundle.');
65
+ }
66
+ replayBundle = bundle;
67
+ const delegatedUri = await input?.replaySink?.save(bundle);
68
+ const uri = delegatedUri ?? 'memory://agent-console-meetup-proof';
69
+ replayUris.push(uri);
70
+ return uri;
71
+ },
72
+ };
73
+
74
+ const runner = new HarnessRunner({
75
+ targetResolver: {
76
+ async resolve() {
77
+ return {
78
+ targetId: 'sandbox-agent-console',
79
+ kind: 'sandbox',
80
+ isolation: 'sandbox',
81
+ environment: 'local',
82
+ baseUrl: 'https://sandbox.contractspec.local/agent-console',
83
+ allowlistedDomains: ['sandbox.contractspec.local'],
84
+ };
85
+ },
86
+ },
87
+ artifactStore,
88
+ adapters: [adapter],
89
+ approvalGateway: {
90
+ async approve() {
91
+ return { approved: true, approverId: 'meetup-proof' };
92
+ },
93
+ },
94
+ now: harnessNow,
95
+ idFactory: createProofIdFactory('proof'),
96
+ defaultMode: 'code-execution',
97
+ });
98
+ const evaluationRunner = new HarnessEvaluationRunner({
99
+ runner,
100
+ replaySink,
101
+ now: harnessNow,
102
+ idFactory: createProofIdFactory('evaluation'),
103
+ });
104
+ const evaluation = await evaluationRunner.runScenarioEvaluation({
105
+ scenario: AGENT_CONSOLE_MEETUP_PROOF_SCENARIO,
106
+ mode: 'code-execution',
107
+ target: {
108
+ targetId: 'sandbox-agent-console',
109
+ isolation: 'sandbox',
110
+ baseUrl: 'https://sandbox.contractspec.local/agent-console',
111
+ allowlistedDomains: ['sandbox.contractspec.local'],
112
+ },
113
+ context: {
114
+ metadata: {
115
+ lane: 'meetup-proof',
116
+ templateId: 'agent-console',
117
+ },
118
+ },
119
+ });
120
+
121
+ if (!replayBundle) {
122
+ throw new Error('Meetup proof did not produce a replay bundle.');
123
+ }
124
+
125
+ return {
126
+ evaluation,
127
+ replayBundle,
128
+ replayUri: replayUris[0] ?? evaluation.replayBundleUri,
129
+ };
130
+ }
@@ -4,6 +4,22 @@
4
4
 
5
5
  import { MOCK_AGENTS } from '../shared/mock-agents';
6
6
  import { MOCK_RUNS } from '../shared/mock-runs';
7
+ import {
8
+ CancelRunCommand,
9
+ ExecuteAgentCommand,
10
+ GetRunQuery,
11
+ ListRunsQuery,
12
+ } from './run.operation';
13
+
14
+ const RUN_HANDLER_CONTRACTS = [
15
+ CancelRunCommand,
16
+ ExecuteAgentCommand,
17
+ GetRunQuery,
18
+ ListRunsQuery,
19
+ ] as const;
20
+ void RUN_HANDLER_CONTRACTS;
21
+
22
+ let nextMockRunId = MOCK_RUNS.length + 1;
7
23
 
8
24
  export interface ListRunsInput {
9
25
  organizationId?: string;
@@ -117,7 +133,7 @@ export async function mockExecuteAgentHandler(input: {
117
133
  if (agent.status !== 'ACTIVE') throw new Error('AGENT_NOT_ACTIVE');
118
134
 
119
135
  return {
120
- runId: `run-${Date.now()}`,
136
+ runId: `run-${nextMockRunId++}`,
121
137
  status: 'QUEUED' as const,
122
138
  estimatedWaitMs: 500,
123
139
  };
@@ -0,0 +1,58 @@
1
+ import type { AgentHandlers } from '../handlers/agent.handlers';
2
+ import { createAgentConsoleDemoHandlers } from './demo-runtime';
3
+ import {
4
+ AGENT_CONSOLE_DEMO_ORGANIZATION_ID,
5
+ AGENT_CONSOLE_DEMO_PROJECT_ID,
6
+ } from './demo-runtime-seed';
7
+
8
+ export interface AgentConsoleDashboardData {
9
+ agents: Awaited<ReturnType<AgentHandlers['listAgents']>>['items'];
10
+ runs: Awaited<ReturnType<AgentHandlers['listRuns']>>['items'];
11
+ tools: Awaited<ReturnType<AgentHandlers['listTools']>>['items'];
12
+ summary: {
13
+ totalAgents: number;
14
+ totalRuns: number;
15
+ totalTools: number;
16
+ };
17
+ }
18
+
19
+ export async function getAgentConsoleDashboardData(
20
+ handlers: AgentHandlers,
21
+ params: { projectId: string; organizationId?: string }
22
+ ): Promise<AgentConsoleDashboardData> {
23
+ const organizationId =
24
+ params.organizationId ?? AGENT_CONSOLE_DEMO_ORGANIZATION_ID;
25
+ const [agentsResult, runsResult, toolsResult] = await Promise.all([
26
+ handlers.listAgents({
27
+ projectId: params.projectId,
28
+ organizationId,
29
+ limit: 10,
30
+ }),
31
+ handlers.listRuns({ projectId: params.projectId, limit: 10 }),
32
+ handlers.listTools({
33
+ projectId: params.projectId,
34
+ organizationId,
35
+ limit: 10,
36
+ }),
37
+ ]);
38
+
39
+ return {
40
+ agents: agentsResult.items,
41
+ runs: runsResult.items,
42
+ tools: toolsResult.items,
43
+ summary: {
44
+ totalAgents: agentsResult.total,
45
+ totalRuns: runsResult.total,
46
+ totalTools: toolsResult.total,
47
+ },
48
+ };
49
+ }
50
+
51
+ export async function getFallbackAgentConsoleDashboardData() {
52
+ const handlers = createAgentConsoleDemoHandlers({
53
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID,
54
+ });
55
+ return getAgentConsoleDashboardData(handlers, {
56
+ projectId: AGENT_CONSOLE_DEMO_PROJECT_ID,
57
+ });
58
+ }