@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.
- package/.turbo/turbo-build.log +126 -105
- package/AGENTS.md +3 -1
- package/CHANGELOG.md +57 -0
- package/README.md +46 -9
- package/dist/agent/agent.handler.d.ts +3 -0
- package/dist/agent/agent.handler.js +730 -1
- package/dist/agent/index.js +73 -72
- package/dist/agent.feature.js +179 -0
- package/dist/browser/agent/agent.handler.js +730 -1
- package/dist/browser/agent/index.js +73 -72
- package/dist/browser/agent.feature.js +179 -0
- package/dist/browser/docs/agent-console.docblock.js +11 -8
- package/dist/browser/docs/index.js +11 -8
- package/dist/browser/example.js +2 -3
- package/dist/browser/handlers/agent.handlers.js +1883 -2
- package/dist/browser/handlers/index.js +2142 -8
- package/dist/browser/index.js +3347 -2433
- package/dist/browser/presentations/index.js +49 -49
- package/dist/browser/run/index.js +818 -812
- package/dist/browser/run/run.handler.js +666 -1
- package/dist/browser/shared/index.js +293 -1
- package/dist/browser/shared/mock-runs.js +5 -0
- package/dist/browser/tool/index.js +331 -331
- package/dist/browser/tool/tool.handler.js +479 -3
- package/dist/browser/ui/AgentDashboard.js +1204 -319
- package/dist/browser/ui/AgentDashboard.visualizations.js +217 -0
- package/dist/browser/ui/AgentRunList.js +359 -127
- package/dist/browser/ui/hooks/index.js +468 -18
- package/dist/browser/ui/hooks/useAgentMutations.js +443 -8
- package/dist/browser/ui/hooks/useRunList.js +25 -10
- package/dist/browser/ui/index.js +1293 -390
- package/dist/browser/ui/renderers/agent-list.markdown.js +14 -5
- package/dist/browser/ui/renderers/dashboard.markdown.js +207 -36
- package/dist/browser/ui/renderers/index.js +245 -49
- package/dist/browser/ui/renderers/run-list.markdown.js +9 -4
- package/dist/browser/ui/renderers/tool-registry.markdown.js +15 -4
- package/dist/browser/ui/views/RunDataTable.js +326 -0
- package/dist/browser/ui/views/RunListView.js +359 -127
- package/dist/browser/ui/views/index.js +406 -174
- package/dist/browser/ui/views/run-data-table.columns.js +271 -0
- package/dist/browser/ui/views/run-list.shared.js +177 -0
- package/dist/browser/visualizations/catalog.js +134 -0
- package/dist/browser/visualizations/index.js +187 -0
- package/dist/browser/visualizations/selectors.js +181 -0
- package/dist/docs/agent-console.docblock.js +11 -8
- package/dist/docs/index.js +11 -8
- package/dist/example.js +2 -3
- package/dist/example.test.d.ts +1 -0
- package/dist/handlers/agent.handlers.d.ts +2 -0
- package/dist/handlers/agent.handlers.js +1883 -2
- package/dist/handlers/index.d.ts +1 -3
- package/dist/handlers/index.js +2142 -8
- package/dist/handlers/mock-handlers.test.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3347 -2433
- package/dist/node/agent/agent.handler.js +730 -1
- package/dist/node/agent/index.js +73 -72
- package/dist/node/agent.feature.js +179 -0
- package/dist/node/docs/agent-console.docblock.js +11 -8
- package/dist/node/docs/index.js +11 -8
- package/dist/node/example.js +2 -3
- package/dist/node/handlers/agent.handlers.js +1883 -2
- package/dist/node/handlers/index.js +2142 -8
- package/dist/node/index.js +3347 -2433
- package/dist/node/presentations/index.js +49 -49
- package/dist/node/run/index.js +818 -812
- package/dist/node/run/run.handler.js +666 -1
- package/dist/node/shared/index.js +293 -1
- package/dist/node/shared/mock-runs.js +5 -0
- package/dist/node/tool/index.js +331 -331
- package/dist/node/tool/tool.handler.js +479 -3
- package/dist/node/ui/AgentDashboard.js +1204 -319
- package/dist/node/ui/AgentDashboard.visualizations.js +217 -0
- package/dist/node/ui/AgentRunList.js +359 -127
- package/dist/node/ui/hooks/index.js +468 -18
- package/dist/node/ui/hooks/useAgentMutations.js +443 -8
- package/dist/node/ui/hooks/useRunList.js +25 -10
- package/dist/node/ui/index.js +1293 -390
- package/dist/node/ui/renderers/agent-list.markdown.js +14 -5
- package/dist/node/ui/renderers/dashboard.markdown.js +207 -36
- package/dist/node/ui/renderers/index.js +245 -49
- package/dist/node/ui/renderers/run-list.markdown.js +9 -4
- package/dist/node/ui/renderers/tool-registry.markdown.js +15 -4
- package/dist/node/ui/views/RunDataTable.js +326 -0
- package/dist/node/ui/views/RunListView.js +359 -127
- package/dist/node/ui/views/index.js +406 -174
- package/dist/node/ui/views/run-data-table.columns.js +271 -0
- package/dist/node/ui/views/run-list.shared.js +177 -0
- package/dist/node/visualizations/catalog.js +134 -0
- package/dist/node/visualizations/index.js +187 -0
- package/dist/node/visualizations/selectors.js +181 -0
- package/dist/presentations/index.js +49 -49
- package/dist/proof/index.d.ts +2 -0
- package/dist/proof/meetup-proof.d.ts +10 -0
- package/dist/proof/meetup-proof.runtime.d.ts +22 -0
- package/dist/proof/meetup-proof.scenario.d.ts +2 -0
- package/dist/proof/meetup-proof.suite.d.ts +1 -0
- package/dist/proof/meetup-proof.test.d.ts +1 -0
- package/dist/run/index.js +818 -812
- package/dist/run/run.handler.d.ts +4 -0
- package/dist/run/run.handler.js +666 -1
- package/dist/shared/demo-dashboard-data.d.ts +16 -0
- package/dist/shared/demo-runtime-seed.d.ts +17 -0
- package/dist/shared/demo-runtime.d.ts +8 -0
- package/dist/shared/demo-runtime.test.d.ts +1 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +293 -1
- package/dist/shared/mock-runs.d.ts +4 -0
- package/dist/shared/mock-runs.js +5 -0
- package/dist/tool/index.js +331 -331
- package/dist/tool/tool.handler.d.ts +4 -1
- package/dist/tool/tool.handler.js +479 -3
- package/dist/ui/AgentDashboard.js +1204 -319
- package/dist/ui/AgentDashboard.sandbox.test.d.ts +1 -0
- package/dist/ui/AgentDashboard.visualizations.d.ts +4 -0
- package/dist/ui/AgentDashboard.visualizations.js +218 -0
- package/dist/ui/AgentRunList.js +359 -127
- package/dist/ui/hooks/index.js +468 -18
- package/dist/ui/hooks/useAgentMutations.js +443 -8
- package/dist/ui/hooks/useRunList.d.ts +8 -2
- package/dist/ui/hooks/useRunList.js +25 -10
- package/dist/ui/index.js +1293 -390
- package/dist/ui/renderers/agent-list.markdown.d.ts +1 -1
- package/dist/ui/renderers/agent-list.markdown.js +14 -5
- package/dist/ui/renderers/agent-list.renderer.d.ts +1 -1
- package/dist/ui/renderers/dashboard.markdown.d.ts +1 -1
- package/dist/ui/renderers/dashboard.markdown.js +207 -36
- package/dist/ui/renderers/index.js +245 -49
- package/dist/ui/renderers/run-list.markdown.d.ts +1 -1
- package/dist/ui/renderers/run-list.markdown.js +9 -4
- package/dist/ui/renderers/tool-registry.markdown.d.ts +2 -2
- package/dist/ui/renderers/tool-registry.markdown.js +15 -4
- package/dist/ui/views/RunDataTable.d.ts +18 -0
- package/dist/ui/views/RunDataTable.js +327 -0
- package/dist/ui/views/RunListView.js +359 -127
- package/dist/ui/views/index.js +406 -174
- package/dist/ui/views/run-data-table.columns.d.ts +3 -0
- package/dist/ui/views/run-data-table.columns.js +272 -0
- package/dist/ui/views/run-list.shared.d.ts +14 -0
- package/dist/ui/views/run-list.shared.js +178 -0
- package/dist/visualizations/catalog.d.ts +10 -0
- package/dist/visualizations/catalog.js +135 -0
- package/dist/visualizations/index.d.ts +2 -0
- package/dist/visualizations/index.js +188 -0
- package/dist/visualizations/selectors.d.ts +3 -0
- package/dist/visualizations/selectors.js +182 -0
- package/dist/visualizations/selectors.test.d.ts +1 -0
- package/package.json +114 -11
- package/proofs/agent-console-meetup.replay.json +220 -0
- package/src/agent/agent.handler.ts +18 -1
- package/src/agent.feature.ts +3 -0
- package/src/docs/agent-console.docblock.ts +11 -8
- package/src/example.test.ts +75 -0
- package/src/example.ts +2 -3
- package/src/handlers/agent.handlers.ts +55 -2
- package/src/handlers/index.ts +18 -2
- package/src/handlers/mock-handlers.test.ts +77 -0
- package/src/index.ts +2 -0
- package/src/proof/index.ts +2 -0
- package/src/proof/meetup-proof.runtime.ts +196 -0
- package/src/proof/meetup-proof.scenario.ts +99 -0
- package/src/proof/meetup-proof.suite.ts +29 -0
- package/src/proof/meetup-proof.test.ts +28 -0
- package/src/proof/meetup-proof.ts +130 -0
- package/src/run/run.handler.ts +17 -1
- package/src/shared/demo-dashboard-data.ts +58 -0
- package/src/shared/demo-runtime-seed.ts +139 -0
- package/src/shared/demo-runtime.test.ts +169 -0
- package/src/shared/demo-runtime.ts +260 -0
- package/src/shared/index.ts +11 -0
- package/src/shared/mock-runs.ts +5 -0
- package/src/tool/tool.handler.ts +21 -4
- package/src/ui/AgentDashboard.sandbox.test.tsx +312 -0
- package/src/ui/AgentDashboard.tsx +4 -1
- package/src/ui/AgentDashboard.visualizations.tsx +35 -0
- package/src/ui/hooks/useAgentMutations.ts +19 -11
- package/src/ui/hooks/useRunList.ts +41 -9
- package/src/ui/renderers/agent-list.markdown.ts +32 -13
- package/src/ui/renderers/agent-list.renderer.tsx +1 -1
- package/src/ui/renderers/dashboard.markdown.ts +38 -43
- package/src/ui/renderers/run-list.markdown.ts +17 -9
- package/src/ui/renderers/tool-registry.markdown.ts +22 -10
- package/src/ui/views/RunDataTable.tsx +74 -0
- package/src/ui/views/RunListView.tsx +37 -111
- package/src/ui/views/run-data-table.columns.tsx +102 -0
- package/src/ui/views/run-list.shared.tsx +139 -0
- package/src/visualizations/catalog.ts +132 -0
- package/src/visualizations/index.ts +2 -0
- package/src/visualizations/selectors.test.ts +12 -0
- package/src/visualizations/selectors.ts +70 -0
- 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
|
+
}
|
package/src/run/run.handler.ts
CHANGED
|
@@ -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-${
|
|
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
|
+
}
|