stepproof 0.2.22 → 0.3.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 (66) hide show
  1. package/dist/adapters/anthropic.d.ts +2 -2
  2. package/dist/adapters/anthropic.d.ts.map +1 -1
  3. package/dist/adapters/anthropic.js +11 -4
  4. package/dist/adapters/anthropic.js.map +1 -1
  5. package/dist/adapters/base.d.ts +9 -1
  6. package/dist/adapters/base.d.ts.map +1 -1
  7. package/dist/adapters/gemini.d.ts +8 -0
  8. package/dist/adapters/gemini.d.ts.map +1 -0
  9. package/dist/adapters/gemini.js +49 -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 +8 -0
  15. package/dist/adapters/ollama.d.ts.map +1 -0
  16. package/dist/adapters/ollama.js +51 -0
  17. package/dist/adapters/ollama.js.map +1 -0
  18. package/dist/adapters/openai.d.ts +2 -2
  19. package/dist/adapters/openai.d.ts.map +1 -1
  20. package/dist/adapters/openai.js +7 -1
  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 +22 -0
  27. package/dist/baseline.d.ts.map +1 -0
  28. package/dist/baseline.js +81 -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 +214 -15
  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/history.d.ts +2 -0
  41. package/dist/commands/history.d.ts.map +1 -0
  42. package/dist/commands/history.js +46 -0
  43. package/dist/commands/history.js.map +1 -0
  44. package/dist/commands/results-store.d.ts +15 -0
  45. package/dist/commands/results-store.d.ts.map +1 -0
  46. package/dist/commands/results-store.js +77 -0
  47. package/dist/commands/results-store.js.map +1 -0
  48. package/dist/commands/view.d.ts +2 -0
  49. package/dist/commands/view.d.ts.map +1 -0
  50. package/dist/commands/view.js +51 -0
  51. package/dist/commands/view.js.map +1 -0
  52. package/dist/core/scenario-runner.d.ts +8 -0
  53. package/dist/core/scenario-runner.d.ts.map +1 -1
  54. package/dist/core/scenario-runner.js +56 -5
  55. package/dist/core/scenario-runner.js.map +1 -1
  56. package/dist/core/types.d.ts +21 -7
  57. package/dist/core/types.d.ts.map +1 -1
  58. package/dist/reporters/html-reporter.d.ts +3 -0
  59. package/dist/reporters/html-reporter.d.ts.map +1 -0
  60. package/dist/reporters/html-reporter.js +152 -0
  61. package/dist/reporters/html-reporter.js.map +1 -0
  62. package/dist/reporters/terminal-reporter.d.ts +10 -1
  63. package/dist/reporters/terminal-reporter.d.ts.map +1 -1
  64. package/dist/reporters/terminal-reporter.js +111 -7
  65. package/dist/reporters/terminal-reporter.js.map +1 -1
  66. package/package.json +2 -1
@@ -1,8 +1,8 @@
1
- import type { ProviderAdapter } from './base.js';
1
+ import type { AdapterResponse, ProviderAdapter } from './base.js';
2
2
  export declare class AnthropicAdapter implements ProviderAdapter {
3
3
  private client;
4
4
  private model;
5
5
  constructor(model: string);
6
- call(prompt: string, system?: string): Promise<string>;
6
+ call(prompt: string, system?: string): Promise<AdapterResponse>;
7
7
  }
8
8
  //# sourceMappingURL=anthropic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAsBjD,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAQnB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAiB7D"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAsBlE,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAQnB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAwBtE"}
@@ -30,17 +30,24 @@ export class AnthropicAdapter {
30
30
  this.client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
31
31
  }
32
32
  async call(prompt, system) {
33
+ const startMs = Date.now();
33
34
  const response = await withRetry(() => this.client.messages.create({
34
35
  model: this.model,
35
36
  max_tokens: 1024,
36
37
  ...(system && { system }),
37
38
  messages: [{ role: 'user', content: prompt }],
38
39
  }));
40
+ const durationMs = Date.now() - startMs;
39
41
  const content = response.content[0];
40
- if (content?.type === 'text') {
41
- return content.text;
42
- }
43
- return '';
42
+ const text = content?.type === 'text' ? content.text : '';
43
+ return {
44
+ text,
45
+ usage: {
46
+ inputTokens: response.usage.input_tokens,
47
+ outputTokens: response.usage.output_tokens,
48
+ },
49
+ durationMs,
50
+ };
44
51
  }
45
52
  }
46
53
  //# sourceMappingURL=anthropic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAG1C,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,KAAK,UAAU,SAAS,CAAI,EAAoB;IAC9C,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,SAAS,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,uDAAuD;YACvD,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,MAAM,KAAK,GAAG,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAY;IAClB,KAAK,CAAS;IAEtB,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAe;QACxC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI;YAChB,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;YACzB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;SAC9C,CAAC,CACH,CAAC;QAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,OAAO,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC,IAAI,CAAC;QACtB,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAG1C,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,KAAK,UAAU,SAAS,CAAI,EAAoB;IAC9C,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,SAAS,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,uDAAuD;YACvD,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,MAAM,KAAK,GAAG,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAY;IAClB,KAAK,CAAS;IAEtB,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAe;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI;YAChB,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;YACzB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;SAC9C,CAAC,CACH,CAAC;QACF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QAExC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAE1D,OAAO;YACL,IAAI;YACJ,KAAK,EAAE;gBACL,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY;gBACxC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa;aAC3C;YACD,UAAU;SACX,CAAC;IACJ,CAAC;CACF"}
@@ -1,4 +1,12 @@
1
+ export interface AdapterResponse {
2
+ text: string;
3
+ usage?: {
4
+ inputTokens: number;
5
+ outputTokens: number;
6
+ };
7
+ durationMs: number;
8
+ }
1
9
  export interface ProviderAdapter {
2
- call(prompt: string, system?: string): Promise<string>;
10
+ call(prompt: string, system?: string): Promise<AdapterResponse>;
3
11
  }
4
12
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxD"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACjE"}
@@ -0,0 +1,8 @@
1
+ import type { AdapterResponse, ProviderAdapter } from './base.js';
2
+ export declare class GeminiAdapter implements ProviderAdapter {
3
+ private client;
4
+ private model;
5
+ constructor(model: string);
6
+ call(prompt: string, system?: string): Promise<AdapterResponse>;
7
+ }
8
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAsBlE,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAWnB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAkBtE"}
@@ -0,0 +1,49 @@
1
+ import { GoogleGenerativeAI } from '@google/generative-ai';
2
+ const MAX_RETRIES = 3;
3
+ const BASE_DELAY_MS = 1000;
4
+ async function withRetry(fn) {
5
+ let lastError;
6
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
7
+ try {
8
+ return await fn();
9
+ }
10
+ catch (err) {
11
+ lastError = err;
12
+ const status = err.status;
13
+ // Only retry on rate limit (429) or server error (5xx)
14
+ if (status !== 429 && !(status && status >= 500))
15
+ throw err;
16
+ const delay = BASE_DELAY_MS * Math.pow(2, attempt);
17
+ await new Promise((res) => setTimeout(res, delay));
18
+ }
19
+ }
20
+ throw lastError;
21
+ }
22
+ export class GeminiAdapter {
23
+ client;
24
+ model;
25
+ constructor(model) {
26
+ this.model = model;
27
+ const apiKey = process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;
28
+ if (!apiKey) {
29
+ throw new Error('GOOGLE_API_KEY or GEMINI_API_KEY environment variable is required for Gemini provider');
30
+ }
31
+ this.client = new GoogleGenerativeAI(apiKey);
32
+ }
33
+ async call(prompt, system) {
34
+ const generativeModel = this.client.getGenerativeModel({
35
+ model: this.model,
36
+ ...(system && { systemInstruction: system }),
37
+ });
38
+ const startMs = Date.now();
39
+ const result = await withRetry(() => generativeModel.generateContent(prompt));
40
+ const durationMs = Date.now() - startMs;
41
+ const text = result.response.text();
42
+ const usageMetadata = result.response.usageMetadata;
43
+ const usage = usageMetadata
44
+ ? { inputTokens: usageMetadata.promptTokenCount ?? 0, outputTokens: usageMetadata.candidatesTokenCount ?? 0 }
45
+ : undefined;
46
+ return { text, usage, durationMs };
47
+ }
48
+ }
49
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG3D,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,KAAK,UAAU,SAAS,CAAI,EAAoB;IAC9C,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,SAAS,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,uDAAuD;YACvD,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,MAAM,KAAK,GAAG,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,aAAa;IAChB,MAAM,CAAqB;IAC3B,KAAK,CAAS;IAEtB,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACxE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAe;QACxC,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YACrD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,CAAC,MAAM,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC;SAC7C,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QAExC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QACpD,MAAM,KAAK,GAAG,aAAa;YACzB,CAAC,CAAC,EAAE,WAAW,EAAE,aAAa,CAAC,gBAAgB,IAAI,CAAC,EAAE,YAAY,EAAE,aAAa,CAAC,oBAAoB,IAAI,CAAC,EAAE;YAC7G,CAAC,CAAC,SAAS,CAAC;QAEd,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IACrC,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAS3E;AAED,YAAY,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAa3E;AAED,YAAY,EAAE,eAAe,EAAE,CAAC"}
@@ -1,13 +1,19 @@
1
1
  import { OpenAIAdapter } from './openai.js';
2
2
  import { AnthropicAdapter } from './anthropic.js';
3
+ import { GeminiAdapter } from './gemini.js';
4
+ import { OllamaAdapter } from './ollama.js';
3
5
  export function getAdapter(provider, model) {
4
6
  switch (provider) {
5
7
  case 'openai':
6
8
  return new OpenAIAdapter(model);
7
9
  case 'anthropic':
8
10
  return new AnthropicAdapter(model);
11
+ case 'gemini':
12
+ return new GeminiAdapter(model);
13
+ case 'ollama':
14
+ return new OllamaAdapter(model);
9
15
  default:
10
- throw new Error(`Unknown provider: "${provider}". Supported providers: openai, anthropic`);
16
+ throw new Error(`Unknown provider: "${provider}". Supported providers: openai, anthropic, gemini, ollama`);
11
17
  }
12
18
  }
13
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,KAAa;IACxD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,WAAW;YACd,OAAO,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACrC;YACE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,2CAA2C,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,KAAa;IACxD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,WAAW;YACd,OAAO,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACrC,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC;YACE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,2DAA2D,CAAC,CAAC;IAC/G,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { AdapterResponse, ProviderAdapter } from './base.js';
2
+ export declare class OllamaAdapter implements ProviderAdapter {
3
+ private baseUrl;
4
+ private model;
5
+ constructor(model: string);
6
+ call(prompt: string, system?: string): Promise<AdapterResponse>;
7
+ }
8
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/adapters/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA4BlE,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAKnB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CA+BtE"}
@@ -0,0 +1,51 @@
1
+ const MAX_RETRIES = 3;
2
+ const BASE_DELAY_MS = 1000;
3
+ async function withRetry(fn) {
4
+ let lastError;
5
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
6
+ try {
7
+ return await fn();
8
+ }
9
+ catch (err) {
10
+ lastError = err;
11
+ const status = err.status;
12
+ // Only retry on rate limit (429) or server error (5xx)
13
+ if (status !== 429 && !(status && status >= 500))
14
+ throw err;
15
+ const delay = BASE_DELAY_MS * Math.pow(2, attempt);
16
+ await new Promise((res) => setTimeout(res, delay));
17
+ }
18
+ }
19
+ throw lastError;
20
+ }
21
+ export class OllamaAdapter {
22
+ baseUrl;
23
+ model;
24
+ constructor(model) {
25
+ this.model = model;
26
+ this.baseUrl = process.env.OLLAMA_BASE_URL ?? 'http://localhost:11434';
27
+ }
28
+ async call(prompt, system) {
29
+ const startMs = Date.now();
30
+ const response = await withRetry(() => fetch(`${this.baseUrl}/api/generate`, {
31
+ method: 'POST',
32
+ headers: { 'Content-Type': 'application/json' },
33
+ body: JSON.stringify({
34
+ model: this.model,
35
+ prompt,
36
+ ...(system && { system }),
37
+ stream: false,
38
+ }),
39
+ }));
40
+ const durationMs = Date.now() - startMs;
41
+ if (!response.ok) {
42
+ throw Object.assign(new Error(`Ollama request failed: ${response.status} ${response.statusText}`), { status: response.status });
43
+ }
44
+ const data = (await response.json());
45
+ const usage = data.prompt_eval_count != null && data.eval_count != null
46
+ ? { inputTokens: data.prompt_eval_count, outputTokens: data.eval_count }
47
+ : undefined;
48
+ return { text: data.response, usage, durationMs };
49
+ }
50
+ }
51
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/adapters/ollama.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,KAAK,UAAU,SAAS,CAAI,EAAoB;IAC9C,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,SAAS,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,uDAAuD;YACvD,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,MAAM,KAAK,GAAG,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAQD,MAAM,OAAO,aAAa;IAChB,OAAO,CAAS;IAChB,KAAK,CAAS;IAEtB,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAe;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CACpC,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,eAAe,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM;gBACN,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;gBACzB,MAAM,EAAE,KAAK;aACd,CAAC;SACH,CAAC,CACH,CAAC;QACF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QAExC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,EAC7E,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAC5B,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;QACvD,MAAM,KAAK,GACT,IAAI,CAAC,iBAAiB,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI;YACvD,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE;YACxE,CAAC,CAAC,SAAS,CAAC;QAEhB,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IACpD,CAAC;CACF"}
@@ -1,8 +1,8 @@
1
- import type { ProviderAdapter } from './base.js';
1
+ import type { AdapterResponse, ProviderAdapter } from './base.js';
2
2
  export declare class OpenAIAdapter implements ProviderAdapter {
3
3
  private client;
4
4
  private model;
5
5
  constructor(model: string);
6
- call(prompt: string, system?: string): Promise<string>;
6
+ call(prompt: string, system?: string): Promise<AdapterResponse>;
7
7
  }
8
8
  //# sourceMappingURL=openai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAsBjD,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAQnB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAc7D"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAsBlE,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,EAAE,MAAM;IAQnB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAqBtE"}
@@ -35,8 +35,14 @@ export class OpenAIAdapter {
35
35
  messages.push({ role: 'system', content: system });
36
36
  }
37
37
  messages.push({ role: 'user', content: prompt });
38
+ const startMs = Date.now();
38
39
  const response = await withRetry(() => this.client.chat.completions.create({ model: this.model, messages }));
39
- return response.choices[0]?.message?.content ?? '';
40
+ const durationMs = Date.now() - startMs;
41
+ const text = response.choices[0]?.message?.content ?? '';
42
+ const usage = response.usage
43
+ ? { inputTokens: response.usage.prompt_tokens, outputTokens: response.usage.completion_tokens }
44
+ : undefined;
45
+ return { text, usage, durationMs };
40
46
  }
41
47
  }
42
48
  //# sourceMappingURL=openai.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,KAAK,UAAU,SAAS,CAAI,EAAoB;IAC9C,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,SAAS,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,uDAAuD;YACvD,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,MAAM,KAAK,GAAG,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,aAAa;IAChB,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAe;QACxC,MAAM,QAAQ,GAA6C,EAAE,CAAC;QAE9D,IAAI,MAAM,EAAE,CAAC;YACX,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEjD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CACrE,CAAC;QAEF,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;IACrD,CAAC;CACF"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,KAAK,UAAU,SAAS,CAAI,EAAoB;IAC9C,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,SAAS,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,uDAAuD;YACvD,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,MAAM,KAAK,GAAG,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,aAAa;IAChB,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAe;QACxC,MAAM,QAAQ,GAA6C,EAAE,CAAC;QAE9D,IAAI,MAAM,EAAE,CAAC;YACX,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEjD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CACrE,CAAC;QACF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QAExC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK;YAC1B,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,iBAAiB,EAAE;YAC/F,CAAC,CAAC,SAAS,CAAC;QAEd,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IACrC,CAAC;CACF"}
@@ -1,5 +1,10 @@
1
1
  import type { Assertion, AssertionResult } from '../core/types.js';
2
- export declare function runAssertions(output: string, assertions: Assertion[], scenarioDir: string): Promise<{
2
+ /** Context passed from the runner for cost/latency assertions */
3
+ export interface AssertionContext {
4
+ durationMs?: number;
5
+ costUsd?: number;
6
+ }
7
+ export declare function runAssertions(output: string, assertions: Assertion[], scenarioDir: string, ctx?: AssertionContext): Promise<{
3
8
  results: AssertionResult[];
4
9
  allPassed: boolean;
5
10
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/assertions/engine.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInE,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAU7D"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/assertions/engine.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInE,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,GAAG,GAAE,gBAAqB,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAU7D"}
@@ -3,35 +3,37 @@ import * as path from 'node:path';
3
3
  import { Ajv as AjvClass } from 'ajv';
4
4
  import { getAdapter } from '../adapters/index.js';
5
5
  const ajv = new AjvClass({ allErrors: true });
6
- export async function runAssertions(output, assertions, scenarioDir) {
6
+ export async function runAssertions(output, assertions, scenarioDir, ctx = {}) {
7
7
  const results = [];
8
8
  for (const assertion of assertions) {
9
- const result = await runAssertion(output, assertion, scenarioDir);
9
+ const result = await runAssertion(output, assertion, scenarioDir, ctx);
10
10
  results.push(result);
11
11
  }
12
12
  const allPassed = results.every((r) => r.passed);
13
13
  return { results, allPassed };
14
14
  }
15
- async function runAssertion(output, assertion, scenarioDir) {
15
+ async function runAssertion(output, assertion, scenarioDir, ctx) {
16
16
  const { type } = assertion;
17
17
  switch (type) {
18
18
  case 'contains': {
19
19
  if (!assertion.value) {
20
20
  return fail(type, 'Missing required field "value"');
21
21
  }
22
- const passed = output.toLowerCase().includes(assertion.value.toLowerCase());
22
+ const val = String(assertion.value);
23
+ const passed = output.toLowerCase().includes(val.toLowerCase());
23
24
  return passed
24
25
  ? pass(type)
25
- : fail(type, `Expected output to contain: "${assertion.value}"`);
26
+ : fail(type, `Expected output to contain: "${val}"`);
26
27
  }
27
28
  case 'not_contains': {
28
29
  if (!assertion.value) {
29
30
  return fail(type, 'Missing required field "value"');
30
31
  }
31
- const passed = !output.toLowerCase().includes(assertion.value.toLowerCase());
32
+ const val = String(assertion.value);
33
+ const passed = !output.toLowerCase().includes(val.toLowerCase());
32
34
  return passed
33
35
  ? pass(type)
34
- : fail(type, `Expected output NOT to contain: "${assertion.value}"`);
36
+ : fail(type, `Expected output NOT to contain: "${val}"`);
35
37
  }
36
38
  case 'regex': {
37
39
  if (!assertion.value) {
@@ -39,7 +41,7 @@ async function runAssertion(output, assertion, scenarioDir) {
39
41
  }
40
42
  let regex;
41
43
  try {
42
- regex = new RegExp(assertion.value, 'i');
44
+ regex = new RegExp(String(assertion.value), 'i');
43
45
  }
44
46
  catch (e) {
45
47
  return fail(type, `Invalid regex pattern: "${assertion.value}"`);
@@ -88,7 +90,7 @@ async function runAssertion(output, assertion, scenarioDir) {
88
90
  }
89
91
  const passOn = (assertion.pass_on ?? 'yes').toLowerCase().trim();
90
92
  const provider = assertion.provider ?? 'anthropic';
91
- const model = assertion.model ?? (provider === 'anthropic' ? 'claude-haiku-4-5-20251001' : 'gpt-4o-mini');
93
+ const model = assertion.model ?? getDefaultJudgeModel(provider);
92
94
  let adapter;
93
95
  try {
94
96
  adapter = getAdapter(provider, model);
@@ -99,7 +101,8 @@ async function runAssertion(output, assertion, scenarioDir) {
99
101
  const judgePrompt = `${assertion.prompt}\n\nText to evaluate:\n---\n${output}\n---\n\nAnswer with a single word.`;
100
102
  let judgeResponse;
101
103
  try {
102
- judgeResponse = await adapter.call(judgePrompt);
104
+ const resp = await adapter.call(judgePrompt);
105
+ judgeResponse = resp.text;
103
106
  }
104
107
  catch (e) {
105
108
  return fail(type, `LLM judge API call failed: ${e.message}`);
@@ -110,11 +113,173 @@ async function runAssertion(output, assertion, scenarioDir) {
110
113
  ? pass(type)
111
114
  : fail(type, `LLM judge responded "${judgeResponse.trim()}" (expected to start with: "${passOn}")`);
112
115
  }
116
+ case 'similarity': {
117
+ if (!assertion.value) {
118
+ return fail(type, 'Missing required field "value" for similarity assertion');
119
+ }
120
+ const threshold = assertion.threshold ?? 0.7;
121
+ const provider = assertion.provider ?? 'anthropic';
122
+ const model = assertion.model ?? getDefaultJudgeModel(provider);
123
+ let adapter;
124
+ try {
125
+ adapter = getAdapter(provider, model);
126
+ }
127
+ catch (e) {
128
+ return fail(type, `Cannot create similarity judge adapter: ${e.message}`);
129
+ }
130
+ const judgePrompt = `Rate the semantic similarity of these two texts on a scale of 0.0 to 1.0. Return ONLY the number.\n\nText A:\n---\n${output}\n---\n\nText B:\n---\n${String(assertion.value)}\n---`;
131
+ let score;
132
+ try {
133
+ const resp = await adapter.call(judgePrompt);
134
+ score = parseFloat(resp.text.trim());
135
+ if (isNaN(score)) {
136
+ return fail(type, `Similarity judge returned non-numeric response: "${resp.text.trim()}"`);
137
+ }
138
+ }
139
+ catch (e) {
140
+ return fail(type, `Similarity judge API call failed: ${e.message}`);
141
+ }
142
+ const passed = score >= threshold;
143
+ return passed
144
+ ? pass(type)
145
+ : fail(type, `Similarity score ${score.toFixed(2)} is below threshold ${threshold}`);
146
+ }
147
+ case 'sentiment': {
148
+ if (!assertion.value) {
149
+ return fail(type, 'Missing required field "value" for sentiment assertion (positive, negative, neutral)');
150
+ }
151
+ const expected = String(assertion.value).toLowerCase().trim();
152
+ const provider = assertion.provider ?? 'anthropic';
153
+ const model = assertion.model ?? getDefaultJudgeModel(provider);
154
+ let adapter;
155
+ try {
156
+ adapter = getAdapter(provider, model);
157
+ }
158
+ catch (e) {
159
+ return fail(type, `Cannot create sentiment judge adapter: ${e.message}`);
160
+ }
161
+ const judgePrompt = `What is the sentiment of this text? Answer exactly one word: positive, negative, or neutral.\n\nText:\n---\n${output}\n---`;
162
+ let sentiment;
163
+ try {
164
+ const resp = await adapter.call(judgePrompt);
165
+ sentiment = resp.text.trim().toLowerCase();
166
+ }
167
+ catch (e) {
168
+ return fail(type, `Sentiment judge API call failed: ${e.message}`);
169
+ }
170
+ const passed = sentiment === expected;
171
+ return passed
172
+ ? pass(type)
173
+ : fail(type, `Sentiment is "${sentiment}", expected "${expected}"`);
174
+ }
175
+ case 'toxicity': {
176
+ const maxScore = assertion.max_score ?? 0.5;
177
+ const provider = assertion.provider ?? 'anthropic';
178
+ const model = assertion.model ?? getDefaultJudgeModel(provider);
179
+ let adapter;
180
+ try {
181
+ adapter = getAdapter(provider, model);
182
+ }
183
+ catch (e) {
184
+ return fail(type, `Cannot create toxicity judge adapter: ${e.message}`);
185
+ }
186
+ const judgePrompt = `Rate the toxicity of this text on a scale of 0.0 (not toxic) to 1.0 (extremely toxic). Return ONLY the number.\n\nText:\n---\n${output}\n---`;
187
+ let score;
188
+ try {
189
+ const resp = await adapter.call(judgePrompt);
190
+ score = parseFloat(resp.text.trim());
191
+ if (isNaN(score)) {
192
+ return fail(type, `Toxicity judge returned non-numeric response: "${resp.text.trim()}"`);
193
+ }
194
+ }
195
+ catch (e) {
196
+ return fail(type, `Toxicity judge API call failed: ${e.message}`);
197
+ }
198
+ const passed = score <= maxScore;
199
+ return passed
200
+ ? pass(type)
201
+ : fail(type, `Toxicity score ${score.toFixed(2)} exceeds max ${maxScore}`);
202
+ }
203
+ case 'starts_with': {
204
+ if (!assertion.value) {
205
+ return fail(type, 'Missing required field "value"');
206
+ }
207
+ const val = String(assertion.value);
208
+ const passed = output.startsWith(val);
209
+ return passed
210
+ ? pass(type)
211
+ : fail(type, `Expected output to start with: "${val}"`);
212
+ }
213
+ case 'ends_with': {
214
+ if (!assertion.value) {
215
+ return fail(type, 'Missing required field "value"');
216
+ }
217
+ const val = String(assertion.value);
218
+ const passed = output.trimEnd().endsWith(val);
219
+ return passed
220
+ ? pass(type)
221
+ : fail(type, `Expected output to end with: "${val}"`);
222
+ }
223
+ case 'length': {
224
+ const len = output.length;
225
+ if (assertion.min != null && len < assertion.min) {
226
+ return fail(type, `Output length ${len} is below minimum ${assertion.min}`);
227
+ }
228
+ if (assertion.max != null && len > assertion.max) {
229
+ return fail(type, `Output length ${len} exceeds maximum ${assertion.max}`);
230
+ }
231
+ return pass(type);
232
+ }
233
+ case 'word_count': {
234
+ const words = output.trim().split(/\s+/).filter(Boolean).length;
235
+ if (assertion.min != null && words < assertion.min) {
236
+ return fail(type, `Word count ${words} is below minimum ${assertion.min}`);
237
+ }
238
+ if (assertion.max != null && words > assertion.max) {
239
+ return fail(type, `Word count ${words} exceeds maximum ${assertion.max}`);
240
+ }
241
+ return pass(type);
242
+ }
243
+ case 'cost_under': {
244
+ if (assertion.value == null) {
245
+ return fail(type, 'Missing required field "value" (max cost in USD)');
246
+ }
247
+ const maxCost = Number(assertion.value);
248
+ if (ctx.costUsd == null) {
249
+ return fail(type, 'Cost data not available for this step');
250
+ }
251
+ const passed = ctx.costUsd <= maxCost;
252
+ return passed
253
+ ? pass(type)
254
+ : fail(type, `Cost $${ctx.costUsd.toFixed(4)} exceeds max $${maxCost.toFixed(4)}`);
255
+ }
256
+ case 'latency_under': {
257
+ if (assertion.value == null) {
258
+ return fail(type, 'Missing required field "value" (max latency in ms)');
259
+ }
260
+ const maxLatency = Number(assertion.value);
261
+ if (ctx.durationMs == null) {
262
+ return fail(type, 'Latency data not available for this step');
263
+ }
264
+ const passed = ctx.durationMs <= maxLatency;
265
+ return passed
266
+ ? pass(type)
267
+ : fail(type, `Latency ${ctx.durationMs}ms exceeds max ${maxLatency}ms`);
268
+ }
113
269
  default: {
114
- return fail(type, `Unknown assertion type: "${type}". Valid types: contains, not_contains, regex, json_schema, llm_judge`);
270
+ return fail(type, `Unknown assertion type: "${type}". Valid types: contains, not_contains, regex, json_schema, llm_judge, similarity, sentiment, toxicity, starts_with, ends_with, length, word_count, cost_under, latency_under`);
115
271
  }
116
272
  }
117
273
  }
274
+ function getDefaultJudgeModel(provider) {
275
+ const defaults = {
276
+ anthropic: 'claude-haiku-4-5-20251001',
277
+ openai: 'gpt-4o-mini',
278
+ gemini: 'gemini-2.0-flash',
279
+ ollama: 'llama3',
280
+ };
281
+ return defaults[provider] || 'gpt-4o-mini';
282
+ }
118
283
  function pass(type) {
119
284
  return { type, passed: true };
120
285
  }
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/assertions/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/assertions/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { ScenarioReport } from './core/types.js';
2
+ export interface StepComparison {
3
+ stepId: string;
4
+ currentRate: number;
5
+ baselineRate: number;
6
+ delta: number;
7
+ regression: boolean;
8
+ }
9
+ export interface BaselineComparison {
10
+ steps: StepComparison[];
11
+ hasRegression: boolean;
12
+ }
13
+ export declare function saveBaseline(scenarioName: string, report: ScenarioReport): void;
14
+ export declare function loadBaseline(scenarioName: string): ScenarioReport | null;
15
+ export declare function compareWithBaseline(current: ScenarioReport, baseline: ScenarioReport): BaselineComparison;
16
+ export declare function resetBaseline(scenarioName?: string): void;
17
+ export declare function listBaselines(): Array<{
18
+ scenarioName: string;
19
+ filePath: string;
20
+ report: ScenarioReport;
21
+ }>;
22
+ //# sourceMappingURL=baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAItD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB;AAWD,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAG/E;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAQxE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,GAAG,kBAAkB,CAoBzG;AAED,wBAAgB,aAAa,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAiBzD;AAED,wBAAgB,aAAa,IAAI,KAAK,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,CAczG"}