stepproof 0.2.22 → 0.4.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 (85) hide show
  1. package/dist/adapters/anthropic.d.ts +3 -2
  2. package/dist/adapters/anthropic.d.ts.map +1 -1
  3. package/dist/adapters/anthropic.js +27 -5
  4. package/dist/adapters/anthropic.js.map +1 -1
  5. package/dist/adapters/base.d.ts +14 -1
  6. package/dist/adapters/base.d.ts.map +1 -1
  7. package/dist/adapters/gemini.d.ts +9 -0
  8. package/dist/adapters/gemini.d.ts.map +1 -0
  9. package/dist/adapters/gemini.js +80 -0
  10. package/dist/adapters/gemini.js.map +1 -0
  11. package/dist/adapters/index.d.ts.map +1 -1
  12. package/dist/adapters/index.js +7 -1
  13. package/dist/adapters/index.js.map +1 -1
  14. package/dist/adapters/ollama.d.ts +9 -0
  15. package/dist/adapters/ollama.d.ts.map +1 -0
  16. package/dist/adapters/ollama.js +61 -0
  17. package/dist/adapters/ollama.js.map +1 -0
  18. package/dist/adapters/openai.d.ts +3 -2
  19. package/dist/adapters/openai.d.ts.map +1 -1
  20. package/dist/adapters/openai.js +16 -5
  21. package/dist/adapters/openai.js.map +1 -1
  22. package/dist/assertions/engine.d.ts +6 -1
  23. package/dist/assertions/engine.d.ts.map +1 -1
  24. package/dist/assertions/engine.js +176 -11
  25. package/dist/assertions/engine.js.map +1 -1
  26. package/dist/baseline.d.ts +23 -0
  27. package/dist/baseline.d.ts.map +1 -0
  28. package/dist/baseline.js +98 -0
  29. package/dist/baseline.js.map +1 -0
  30. package/dist/cache.d.ts +5 -0
  31. package/dist/cache.d.ts.map +1 -0
  32. package/dist/cache.js +71 -0
  33. package/dist/cache.js.map +1 -0
  34. package/dist/cli.js +283 -18
  35. package/dist/cli.js.map +1 -1
  36. package/dist/commands/compare.d.ts +43 -0
  37. package/dist/commands/compare.d.ts.map +1 -0
  38. package/dist/commands/compare.js +75 -0
  39. package/dist/commands/compare.js.map +1 -0
  40. package/dist/commands/diff.d.ts +2 -0
  41. package/dist/commands/diff.d.ts.map +1 -0
  42. package/dist/commands/diff.js +252 -0
  43. package/dist/commands/diff.js.map +1 -0
  44. package/dist/commands/history.d.ts +2 -0
  45. package/dist/commands/history.d.ts.map +1 -0
  46. package/dist/commands/history.js +46 -0
  47. package/dist/commands/history.js.map +1 -0
  48. package/dist/commands/results-store.d.ts +15 -0
  49. package/dist/commands/results-store.d.ts.map +1 -0
  50. package/dist/commands/results-store.js +77 -0
  51. package/dist/commands/results-store.js.map +1 -0
  52. package/dist/commands/view.d.ts +2 -0
  53. package/dist/commands/view.d.ts.map +1 -0
  54. package/dist/commands/view.js +51 -0
  55. package/dist/commands/view.js.map +1 -0
  56. package/dist/commands/watch.d.ts +7 -0
  57. package/dist/commands/watch.d.ts.map +1 -0
  58. package/dist/commands/watch.js +84 -0
  59. package/dist/commands/watch.js.map +1 -0
  60. package/dist/core/scenario-parser.d.ts.map +1 -1
  61. package/dist/core/scenario-parser.js +47 -5
  62. package/dist/core/scenario-parser.js.map +1 -1
  63. package/dist/core/scenario-runner.d.ts +12 -0
  64. package/dist/core/scenario-runner.d.ts.map +1 -1
  65. package/dist/core/scenario-runner.js +372 -41
  66. package/dist/core/scenario-runner.js.map +1 -1
  67. package/dist/core/types.d.ts +63 -9
  68. package/dist/core/types.d.ts.map +1 -1
  69. package/dist/dataset.d.ts +6 -0
  70. package/dist/dataset.d.ts.map +1 -0
  71. package/dist/dataset.js +108 -0
  72. package/dist/dataset.js.map +1 -0
  73. package/dist/reporters/github-comment.d.ts +8 -0
  74. package/dist/reporters/github-comment.d.ts.map +1 -0
  75. package/dist/reporters/github-comment.js +114 -0
  76. package/dist/reporters/github-comment.js.map +1 -0
  77. package/dist/reporters/html-reporter.d.ts +3 -0
  78. package/dist/reporters/html-reporter.d.ts.map +1 -0
  79. package/dist/reporters/html-reporter.js +152 -0
  80. package/dist/reporters/html-reporter.js.map +1 -0
  81. package/dist/reporters/terminal-reporter.d.ts +10 -1
  82. package/dist/reporters/terminal-reporter.d.ts.map +1 -1
  83. package/dist/reporters/terminal-reporter.js +139 -8
  84. package/dist/reporters/terminal-reporter.js.map +1 -1
  85. package/package.json +2 -1
@@ -44,26 +44,68 @@ function validateStep(raw, index) {
44
44
  if (!step.id || typeof step.id !== 'string') {
45
45
  throw new Error(`Step ${index + 1} must have an "id" field (string)`);
46
46
  }
47
- if (!step.provider || !['openai', 'anthropic'].includes(step.provider)) {
48
- throw new Error(`${pos}: "provider" must be "openai" or "anthropic"`);
47
+ const validProviders = ['openai', 'anthropic', 'gemini', 'ollama'];
48
+ if (!step.provider || !validProviders.includes(step.provider)) {
49
+ throw new Error(`${pos}: "provider" must be one of: ${validProviders.join(', ')}`);
49
50
  }
50
51
  if (!step.model || typeof step.model !== 'string') {
51
52
  throw new Error(`${pos}: "model" field is required (string)`);
52
53
  }
53
- if (!step.prompt || typeof step.prompt !== 'string') {
54
- throw new Error(`${pos}: "prompt" field is required (string)`);
54
+ // Parse conversation turns
55
+ let conversation;
56
+ if (Array.isArray(step.conversation)) {
57
+ conversation = step.conversation.map((turn, ti) => {
58
+ const role = turn.role;
59
+ if (!role || !['user', 'assistant', 'system'].includes(role)) {
60
+ throw new Error(`${pos}: conversation turn ${ti + 1} must have "role" of user, assistant, or system`);
61
+ }
62
+ return {
63
+ role: role,
64
+ content: typeof turn.content === 'string' ? turn.content : undefined,
65
+ };
66
+ });
67
+ }
68
+ // prompt is required unless conversation is provided
69
+ if (!conversation && (!step.prompt || typeof step.prompt !== 'string')) {
70
+ throw new Error(`${pos}: "prompt" field is required (string) unless "conversation" is provided`);
71
+ }
72
+ // Parse depends_on
73
+ let dependsOn;
74
+ if (Array.isArray(step.depends_on)) {
75
+ dependsOn = step.depends_on.map((d, di) => {
76
+ if (typeof d !== 'string') {
77
+ throw new Error(`${pos}: depends_on[${di}] must be a string (step ID)`);
78
+ }
79
+ return d;
80
+ });
55
81
  }
82
+ // Parse if condition
83
+ const ifCondition = typeof step.if === 'string' ? step.if : undefined;
56
84
  const minPassRate = typeof step.min_pass_rate === 'number' ? step.min_pass_rate : 0.8;
57
85
  if (minPassRate < 0 || minPassRate > 1) {
58
86
  throw new Error(`${pos}: "min_pass_rate" must be between 0.0 and 1.0`);
59
87
  }
88
+ // Retry validation
89
+ const retry = typeof step.retry === 'number' ? step.retry : undefined;
90
+ if (retry !== undefined && (retry < 0 || !Number.isInteger(retry))) {
91
+ throw new Error(`${pos}: "retry" must be a non-negative integer`);
92
+ }
93
+ const retryDelay = typeof step.retry_delay === 'number' ? step.retry_delay : undefined;
94
+ if (retryDelay !== undefined && retryDelay < 0) {
95
+ throw new Error(`${pos}: "retry_delay" must be a non-negative number`);
96
+ }
60
97
  return {
61
98
  id: step.id,
62
99
  provider: step.provider,
63
100
  model: step.model,
64
- prompt: step.prompt,
101
+ prompt: typeof step.prompt === 'string' ? step.prompt : undefined,
65
102
  system: typeof step.system === 'string' ? step.system : undefined,
103
+ conversation,
104
+ depends_on: dependsOn,
105
+ if: ifCondition,
66
106
  min_pass_rate: minPassRate,
107
+ retry,
108
+ retry_delay: retryDelay,
67
109
  assertions: Array.isArray(step.assertions) ? step.assertions : [],
68
110
  };
69
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scenario-parser.js","sourceRoot":"","sources":["../../src/core/scenario-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scenario-parser.js","sourceRoot":"","sources":["../../src/core/scenario-parser.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,8 @@
1
1
  import type { Scenario, ScenarioReport } from './types.js';
2
+ export interface CacheStats {
3
+ hits: number;
4
+ misses: number;
5
+ }
2
6
  export interface RunOptions {
3
7
  /** Override iterations from scenario file */
4
8
  iterations?: number;
@@ -6,6 +10,14 @@ export interface RunOptions {
6
10
  onIterationComplete?: (iteration: number, total: number) => void;
7
11
  /** Called after each step within an iteration */
8
12
  onStepComplete?: (stepId: string, passed: boolean) => void;
13
+ /** Disable LLM response caching */
14
+ noCache?: boolean;
15
+ /** Populated after run — cache hit/miss stats */
16
+ cacheStats?: CacheStats;
17
+ /** Dataset rows — each row's columns become variables (merged with scenario variables, row wins) */
18
+ dataset?: Array<Record<string, string>>;
19
+ /** Original dataset file path (for reporting) */
20
+ datasetPath?: string;
9
21
  }
10
22
  export declare function runScenario(scenario: Scenario, scenarioFilePath: string, options?: RunOptions): Promise<ScenarioReport>;
11
23
  //# sourceMappingURL=scenario-runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scenario-runner.d.ts","sourceRoot":"","sources":["../../src/core/scenario-runner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAA2B,MAAM,YAAY,CAAC;AAEpF,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,iDAAiD;IACjD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D;AAED,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CA8FzB"}
1
+ {"version":3,"file":"scenario-runner.d.ts","sourceRoot":"","sources":["../../src/core/scenario-runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAoD,MAAM,YAAY,CAAC;AAoB7G,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,iDAAiD;IACjD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,oGAAoG;IACpG,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxC,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAgWD,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAoIzB"}
@@ -2,62 +2,355 @@ import * as path from 'node:path';
2
2
  import { getAdapter } from '../adapters/index.js';
3
3
  import { runAssertions } from '../assertions/engine.js';
4
4
  import { substituteVariables } from './scenario-parser.js';
5
- export async function runScenario(scenario, scenarioFilePath, options = {}) {
6
- const iterations = options.iterations ?? scenario.iterations ?? 10;
7
- const scenarioDir = path.dirname(path.resolve(scenarioFilePath));
8
- const variables = scenario.variables ?? {};
9
- const startedAt = new Date().toISOString();
10
- const startMs = Date.now();
11
- const allResults = [];
12
- for (let i = 1; i <= iterations; i++) {
13
- const stepOutputs = {};
14
- for (const step of scenario.steps) {
15
- const resolvedPrompt = substituteVariables(step.prompt, variables, stepOutputs);
16
- const resolvedSystem = step.system
17
- ? substituteVariables(step.system, variables, stepOutputs)
18
- : undefined;
19
- const stepStartMs = Date.now();
20
- let output = '';
21
- let error;
22
- try {
23
- const adapter = getAdapter(step.provider, step.model);
24
- output = await adapter.call(resolvedPrompt, resolvedSystem);
25
- stepOutputs[step.id] = output;
5
+ import { getCached, setCache } from '../cache.js';
6
+ // Approximate cost per 1K tokens by model
7
+ const COST_PER_1K = {
8
+ 'claude-haiku-4-5-20251001': { input: 0.001, output: 0.005 },
9
+ 'claude-sonnet-4-6-20260401': { input: 0.003, output: 0.015 },
10
+ 'gpt-4o': { input: 0.0025, output: 0.01 },
11
+ 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },
12
+ };
13
+ function calculateCost(model, inputTokens, outputTokens) {
14
+ const pricing = COST_PER_1K[model];
15
+ if (!pricing)
16
+ return 0;
17
+ return (inputTokens / 1000) * pricing.input + (outputTokens / 1000) * pricing.output;
18
+ }
19
+ function delayMs(ms) {
20
+ return new Promise((resolve) => setTimeout(resolve, ms));
21
+ }
22
+ // ── Dependency graph helpers ──────────────────────────────────────────
23
+ /** Extract all {{step_id.output}} references from a string. O(n) in string length. */
24
+ function extractOutputRefs(text) {
25
+ const refs = [];
26
+ const regex = /\{\{(\w+)\.output\}\}/g;
27
+ let match;
28
+ while ((match = regex.exec(text)) !== null) {
29
+ refs.push(match[1]);
30
+ }
31
+ return refs;
32
+ }
33
+ /** Collect all step IDs referenced by a step (from prompt, conversation, system, if condition). */
34
+ function getImplicitDependencies(step) {
35
+ const refs = new Set();
36
+ if (step.prompt)
37
+ for (const r of extractOutputRefs(step.prompt))
38
+ refs.add(r);
39
+ if (step.system)
40
+ for (const r of extractOutputRefs(step.system))
41
+ refs.add(r);
42
+ if (step.conversation) {
43
+ for (const turn of step.conversation) {
44
+ if (turn.content)
45
+ for (const r of extractOutputRefs(turn.content))
46
+ refs.add(r);
47
+ }
48
+ }
49
+ if (step.if)
50
+ for (const r of extractOutputRefs(step.if))
51
+ refs.add(r);
52
+ return Array.from(refs);
53
+ }
54
+ /**
55
+ * Build full dependency set per step (explicit depends_on + implicit template refs).
56
+ * O(S * T) where S = steps, T = max template refs per step.
57
+ */
58
+ function buildDependencyMap(steps) {
59
+ const stepIds = new Set(steps.map(s => s.id));
60
+ const deps = new Map();
61
+ for (const step of steps) {
62
+ const stepDeps = new Set();
63
+ if (step.depends_on) {
64
+ for (const dep of step.depends_on) {
65
+ if (!stepIds.has(dep)) {
66
+ throw new Error(`Step "${step.id}" depends_on unknown step "${dep}"`);
67
+ }
68
+ stepDeps.add(dep);
26
69
  }
27
- catch (e) {
28
- error = e.message;
29
- stepOutputs[step.id] = '';
70
+ }
71
+ for (const ref of getImplicitDependencies(step)) {
72
+ if (stepIds.has(ref))
73
+ stepDeps.add(ref);
74
+ }
75
+ deps.set(step.id, stepDeps);
76
+ }
77
+ return deps;
78
+ }
79
+ /** Check whether any parallelism exists in the dependency graph. */
80
+ function hasAnyParallelism(steps, depMap) {
81
+ // If any step has explicit deps/if/conversation, use the parallel executor
82
+ if (steps.some(s => s.if || s.conversation))
83
+ return true;
84
+ // If >1 step has zero deps they can run concurrently
85
+ let zeroDeps = 0;
86
+ for (const deps of depMap.values()) {
87
+ if (deps.size === 0)
88
+ zeroDeps++;
89
+ if (zeroDeps > 1)
90
+ return true;
91
+ }
92
+ return false;
93
+ }
94
+ // ── Conditional step evaluation ──────────────────────────────────────
95
+ /**
96
+ * Evaluate an `if` condition string against step outputs.
97
+ * Format: '<subject> contains|not_contains|matches "<value>"'
98
+ * Subject is typically "{{step_id.output}}" which gets substituted first.
99
+ */
100
+ function evaluateCondition(condition, variables, stepOutputs) {
101
+ const resolved = substituteVariables(condition, variables, stepOutputs);
102
+ const opMatch = resolved.match(/^(.+?)\s+(contains|not_contains|matches)\s+"(.*)"$/s);
103
+ if (!opMatch) {
104
+ throw new Error(`Invalid if condition: ${condition}. Expected: '<expr> contains|not_contains|matches "<value>"'`);
105
+ }
106
+ let subject = opMatch[1].trim();
107
+ const operator = opMatch[2];
108
+ const value = opMatch[3];
109
+ // Strip surrounding quotes from subject if present
110
+ if ((subject.startsWith('"') && subject.endsWith('"')) ||
111
+ (subject.startsWith("'") && subject.endsWith("'"))) {
112
+ subject = subject.slice(1, -1);
113
+ }
114
+ switch (operator) {
115
+ case 'contains': return subject.includes(value);
116
+ case 'not_contains': return !subject.includes(value);
117
+ case 'matches': return new RegExp(value).test(subject);
118
+ default: return false;
119
+ }
120
+ }
121
+ // ── Multi-turn conversation execution ────────────────────────────────
122
+ /**
123
+ * Execute a multi-turn conversation step.
124
+ * Builds messages from conversation turns, substituting templates.
125
+ * The last assistant turn without content is the LLM generation point.
126
+ */
127
+ async function executeConversation(step, variables, stepOutputs, resolvedSystem, useCache, cacheStats) {
128
+ const turns = step.conversation;
129
+ const messages = [];
130
+ for (const turn of turns) {
131
+ if (turn.content !== undefined) {
132
+ const resolvedContent = substituteVariables(turn.content, variables, stepOutputs);
133
+ messages.push({ role: turn.role, content: resolvedContent });
134
+ }
135
+ else if (turn.role === 'assistant') {
136
+ // LLM generation point — stop building messages here
137
+ break;
138
+ }
139
+ }
140
+ // Cache key: concatenation of all messages + system
141
+ const cacheKeyStr = messages.map(m => `${m.role}:${m.content}`).join('|');
142
+ const cached = useCache
143
+ ? getCached(step.provider, step.model, cacheKeyStr, resolvedSystem)
144
+ : null;
145
+ if (cached !== null) {
146
+ cacheStats.hits++;
147
+ return cached;
148
+ }
149
+ const adapter = getAdapter(step.provider, step.model);
150
+ const response = await adapter.chat(messages, resolvedSystem);
151
+ cacheStats.misses++;
152
+ if (useCache) {
153
+ setCache(step.provider, step.model, cacheKeyStr, resolvedSystem, response);
154
+ }
155
+ return response;
156
+ }
157
+ // ── Single step execution (with retry) ───────────────────────────────
158
+ /**
159
+ * Run a single step for one iteration: conditional check, adapter call (prompt or conversation),
160
+ * assertions, and retries.
161
+ */
162
+ async function runStepIteration(step, iteration, variables, stepOutputs, scenarioDir, useCache, cacheStats, datasetRow) {
163
+ // Conditional: evaluate `if` and skip when false
164
+ if (step.if) {
165
+ const conditionMet = evaluateCondition(step.if, variables, stepOutputs);
166
+ if (!conditionMet) {
167
+ stepOutputs[step.id] = '';
168
+ return {
169
+ stepId: step.id,
170
+ iteration,
171
+ output: '',
172
+ passed: true,
173
+ skipped: true,
174
+ assertionResults: [],
175
+ durationMs: 0,
176
+ datasetRow,
177
+ };
178
+ }
179
+ }
180
+ const maxRetries = step.retry ?? 0;
181
+ const retryDelayVal = step.retry_delay ?? 1000;
182
+ let retriesUsed = 0;
183
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
184
+ const resolvedSystem = step.system
185
+ ? substituteVariables(step.system, variables, stepOutputs)
186
+ : undefined;
187
+ let output = '';
188
+ let error;
189
+ let durationMs = 0;
190
+ let inputTokens;
191
+ let outputTokens;
192
+ let costUsd;
193
+ try {
194
+ let response;
195
+ if (step.conversation) {
196
+ // Multi-turn conversation mode
197
+ response = await executeConversation(step, variables, stepOutputs, resolvedSystem, useCache, cacheStats);
30
198
  }
31
- const durationMs = Date.now() - stepStartMs;
32
- let assertionResults = [];
33
- let assertionsPassed = false;
34
- if (!error) {
35
- const { results, allPassed } = await runAssertions(output, step.assertions, scenarioDir);
36
- assertionResults = results;
37
- assertionsPassed = allPassed;
199
+ else {
200
+ // Standard single-prompt mode
201
+ const resolvedPrompt = substituteVariables(step.prompt ?? '', variables, stepOutputs);
202
+ const cached = useCache
203
+ ? getCached(step.provider, step.model, resolvedPrompt, resolvedSystem)
204
+ : null;
205
+ if (cached !== null) {
206
+ cacheStats.hits++;
207
+ response = cached;
208
+ }
209
+ else {
210
+ const adapter = getAdapter(step.provider, step.model);
211
+ response = await adapter.call(resolvedPrompt, resolvedSystem);
212
+ cacheStats.misses++;
213
+ if (useCache && attempt === 0) {
214
+ setCache(step.provider, step.model, resolvedPrompt, resolvedSystem, response);
215
+ }
216
+ }
38
217
  }
39
- const stepPassed = !error && assertionsPassed;
40
- const result = {
218
+ output = response.text;
219
+ durationMs = response.durationMs;
220
+ if (response.usage) {
221
+ inputTokens = response.usage.inputTokens;
222
+ outputTokens = response.usage.outputTokens;
223
+ costUsd = calculateCost(step.model, inputTokens, outputTokens);
224
+ }
225
+ stepOutputs[step.id] = output;
226
+ }
227
+ catch (e) {
228
+ error = e.message;
229
+ cacheStats.misses++;
230
+ stepOutputs[step.id] = '';
231
+ }
232
+ let assertionResults = [];
233
+ let assertionsPassed = false;
234
+ if (!error) {
235
+ const { results, allPassed } = await runAssertions(output, step.assertions, scenarioDir, { durationMs, costUsd });
236
+ assertionResults = results;
237
+ assertionsPassed = allPassed;
238
+ }
239
+ const stepPassed = !error && assertionsPassed;
240
+ if (stepPassed || attempt === maxRetries) {
241
+ return {
41
242
  stepId: step.id,
42
- iteration: i,
243
+ iteration,
43
244
  output,
44
245
  passed: stepPassed,
246
+ retriesUsed,
247
+ datasetRow,
45
248
  assertionResults,
46
249
  error,
47
250
  durationMs,
251
+ inputTokens,
252
+ outputTokens,
253
+ costUsd,
48
254
  };
49
- allResults.push(result);
50
- options.onStepComplete?.(step.id, stepPassed);
51
255
  }
52
- options.onIterationComplete?.(i, iterations);
256
+ retriesUsed++;
257
+ if (retryDelayVal > 0)
258
+ await delayMs(retryDelayVal);
259
+ }
260
+ // Unreachable
261
+ throw new Error('Unreachable');
262
+ }
263
+ // ── Parallel step execution (topological) ────────────────────────────
264
+ /**
265
+ * Execute steps respecting dependency graph.
266
+ * Steps with all dependencies satisfied run concurrently via Promise.all().
267
+ * O(S^2) worst case (fully serial chain) — S is typically < 20.
268
+ */
269
+ async function executeStepsParallel(steps, depMap, variables, scenarioDir, iteration, useCache, cacheStats, onStepComplete, datasetRow) {
270
+ const results = [];
271
+ const stepOutputs = {};
272
+ const completed = new Set();
273
+ const remaining = new Set(steps.map(s => s.id));
274
+ const stepById = new Map(steps.map(s => [s.id, s]));
275
+ while (remaining.size > 0) {
276
+ // Find steps whose dependencies are all satisfied
277
+ const ready = [];
278
+ for (const id of remaining) {
279
+ const deps = depMap.get(id);
280
+ let allMet = true;
281
+ for (const dep of deps) {
282
+ if (!completed.has(dep)) {
283
+ allMet = false;
284
+ break;
285
+ }
286
+ }
287
+ if (allMet)
288
+ ready.push(stepById.get(id));
289
+ }
290
+ if (ready.length === 0) {
291
+ throw new Error(`Circular dependency detected among steps: ${Array.from(remaining).join(', ')}`);
292
+ }
293
+ const batchResults = await Promise.all(ready.map(step => runStepIteration(step, iteration, variables, stepOutputs, scenarioDir, useCache, cacheStats, datasetRow)));
294
+ for (const result of batchResults) {
295
+ results.push(result);
296
+ completed.add(result.stepId);
297
+ remaining.delete(result.stepId);
298
+ onStepComplete?.(result.stepId, result.passed);
299
+ }
53
300
  }
54
- // Aggregate per-step summaries
301
+ return results;
302
+ }
303
+ // ── Main entry point ─────────────────────────────────────────────────
304
+ export async function runScenario(scenario, scenarioFilePath, options = {}) {
305
+ const iterations = options.iterations ?? scenario.iterations ?? 10;
306
+ const scenarioDir = path.dirname(path.resolve(scenarioFilePath));
307
+ const baseVariables = scenario.variables ?? {};
308
+ const dataset = options.dataset;
309
+ const startedAt = new Date().toISOString();
310
+ const startMs = Date.now();
311
+ const allResults = [];
312
+ const useCache = !options.noCache;
313
+ const cacheStats = { hits: 0, misses: 0 };
314
+ // Build dependency graph once
315
+ const depMap = buildDependencyMap(scenario.steps);
316
+ const useParallel = hasAnyParallelism(scenario.steps, depMap);
317
+ // Variable sets: one per dataset row, or just base variables
318
+ const variableSets = dataset
319
+ ? dataset.map((row, i) => ({ vars: { ...baseVariables, ...row }, rowIndex: i }))
320
+ : [{ vars: baseVariables }];
321
+ for (const { vars, rowIndex } of variableSets) {
322
+ for (let i = 1; i <= iterations; i++) {
323
+ let iterResults;
324
+ if (useParallel) {
325
+ iterResults = await executeStepsParallel(scenario.steps, depMap, vars, scenarioDir, i, useCache, cacheStats, options.onStepComplete, rowIndex);
326
+ }
327
+ else {
328
+ // Fast sequential path for simple scenarios
329
+ const stepOutputs = {};
330
+ iterResults = [];
331
+ for (const step of scenario.steps) {
332
+ const result = await runStepIteration(step, i, vars, stepOutputs, scenarioDir, useCache, cacheStats, rowIndex);
333
+ iterResults.push(result);
334
+ options.onStepComplete?.(step.id, result.passed);
335
+ }
336
+ }
337
+ allResults.push(...iterResults);
338
+ options.onIterationComplete?.(dataset ? (rowIndex * iterations) + i : i, dataset ? dataset.length * iterations : iterations);
339
+ }
340
+ }
341
+ // Aggregate per-step summaries (exclude skipped from pass/fail counts)
55
342
  const steps = scenario.steps.map((step) => {
56
343
  const stepResults = allResults.filter((r) => r.stepId === step.id);
57
- const passes = stepResults.filter((r) => r.passed).length;
58
- const failures = stepResults.length - passes;
59
- const passRate = stepResults.length > 0 ? passes / stepResults.length : 0;
344
+ const nonSkipped = stepResults.filter(r => !r.skipped);
345
+ const passes = nonSkipped.filter((r) => r.passed).length;
346
+ const failures = nonSkipped.length - passes;
347
+ const passRate = nonSkipped.length > 0 ? passes / nonSkipped.length : 1; // all-skipped = pass
60
348
  const minPassRate = step.min_pass_rate ?? 0.8;
349
+ const retriedCount = stepResults.filter((r) => (r.retriesUsed ?? 0) > 0).length;
350
+ const totalDurationMs = stepResults.reduce((s, r) => s + r.durationMs, 0);
351
+ const avgDurationMs = stepResults.length > 0 ? totalDurationMs / stepResults.length : 0;
352
+ const totalCostUsd = stepResults.reduce((s, r) => s + (r.costUsd ?? 0), 0);
353
+ const avgCostUsd = stepResults.length > 0 ? totalCostUsd / stepResults.length : 0;
61
354
  return {
62
355
  stepId: step.id,
63
356
  totalRuns: stepResults.length,
@@ -66,11 +359,48 @@ export async function runScenario(scenario, scenarioFilePath, options = {}) {
66
359
  passRate,
67
360
  minPassRate,
68
361
  belowThreshold: passRate < minPassRate,
362
+ avgDurationMs,
363
+ totalCostUsd,
364
+ avgCostUsd,
365
+ retriedCount: retriedCount > 0 ? retriedCount : undefined,
69
366
  };
70
367
  });
71
368
  const allPassed = steps.every((s) => !s.belowThreshold);
72
369
  const completedAt = new Date().toISOString();
73
370
  const durationMs = Date.now() - startMs;
371
+ // Build dataset summary if applicable
372
+ let datasetInfo;
373
+ if (dataset && options.datasetPath) {
374
+ const rowSummaries = dataset.map((row, rowIdx) => {
375
+ const rowResults = allResults.filter((r) => r.datasetRow === rowIdx);
376
+ const stepSummaries = scenario.steps.map((step) => {
377
+ const sr = rowResults.filter((r) => r.stepId === step.id);
378
+ const passed = sr.filter((r) => r.passed).length;
379
+ return {
380
+ stepId: step.id,
381
+ passed: passed === sr.length,
382
+ passRate: sr.length > 0 ? passed / sr.length : 0,
383
+ };
384
+ });
385
+ const keys = Object.keys(row).slice(0, 3);
386
+ const preview = {};
387
+ for (const k of keys)
388
+ preview[k] = row[k];
389
+ return {
390
+ rowIndex: rowIdx,
391
+ rowPreview: preview,
392
+ allStepsPassed: stepSummaries.every((s) => s.passed),
393
+ stepResults: stepSummaries,
394
+ };
395
+ });
396
+ datasetInfo = {
397
+ path: options.datasetPath,
398
+ totalRows: dataset.length,
399
+ rowsPassed: rowSummaries.filter((r) => r.allStepsPassed).length,
400
+ rowSummaries,
401
+ };
402
+ }
403
+ options.cacheStats = cacheStats;
74
404
  return {
75
405
  scenarioName: scenario.name,
76
406
  iterations,
@@ -80,6 +410,7 @@ export async function runScenario(scenario, scenarioFilePath, options = {}) {
80
410
  steps,
81
411
  allPassed,
82
412
  results: allResults,
413
+ dataset: datasetInfo,
83
414
  };
84
415
  }
85
416
  //# sourceMappingURL=scenario-runner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scenario-runner.js","sourceRoot":"","sources":["../../src/core/scenario-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAY3D,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAkB,EAClB,gBAAwB,EACxB,UAAsB,EAAE;IAExB,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC;IACnE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;IAE3C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAiB,EAAE,CAAC;IAEpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,WAAW,GAA2B,EAAE,CAAC;QAE/C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YAChF,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM;gBAChC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC;gBAC1D,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/B,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,KAAyB,CAAC;YAE9B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACtD,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;gBAC5D,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;YAChC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,KAAK,GAAI,CAAW,CAAC,OAAO,CAAC;gBAC7B,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;YAC5B,CAAC;YAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;YAE5C,IAAI,gBAAgB,GAA0D,EAAE,CAAC;YACjF,IAAI,gBAAgB,GAAG,KAAK,CAAC;YAE7B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;gBACzF,gBAAgB,GAAG,OAAO,CAAC;gBAC3B,gBAAgB,GAAG,SAAS,CAAC;YAC/B,CAAC;YAED,MAAM,UAAU,GAAG,CAAC,KAAK,IAAI,gBAAgB,CAAC;YAE9C,MAAM,MAAM,GAAe;gBACzB,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,SAAS,EAAE,CAAC;gBACZ,MAAM;gBACN,MAAM,EAAE,UAAU;gBAClB,gBAAgB;gBAChB,KAAK;gBACL,UAAU;aACX,CAAC;YAEF,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACxB,OAAO,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,+BAA+B;IAC/B,MAAM,KAAK,GAAkB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACvD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QAC1D,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC;QAC7C,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC;QAE9C,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,SAAS,EAAE,WAAW,CAAC,MAAM;YAC7B,MAAM;YACN,QAAQ;YACR,QAAQ;YACR,WAAW;YACX,cAAc,EAAE,QAAQ,GAAG,WAAW;SACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;IAExC,OAAO;QACL,YAAY,EAAE,QAAQ,CAAC,IAAI;QAC3B,UAAU;QACV,SAAS;QACT,WAAW;QACX,UAAU;QACV,KAAK;QACL,SAAS;QACT,OAAO,EAAE,UAAU;KACpB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"scenario-runner.js","sourceRoot":"","sources":["../../src/core/scenario-runner.ts"],"names":[],"mappings":"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"}