@outputai/cli 0.15.1-next.4a437bf.0 → 0.15.1-next.5db73d3.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 (32) hide show
  1. package/dist/assets/docker/docker-compose-dev.yml +1 -1
  2. package/dist/commands/workflow/test.d.ts +1 -1
  3. package/dist/commands/workflow/test.js +3 -1
  4. package/dist/commands/workflow/test.spec.js +2 -1
  5. package/dist/generated/framework_version.json +1 -1
  6. package/dist/services/cost_calculator.js +1 -1
  7. package/dist/services/datasets.d.ts +1 -1
  8. package/dist/services/datasets.js +1 -1
  9. package/dist/services/workflow_planner.js +1 -1
  10. package/dist/services/workflow_planner.spec.js +2 -2
  11. package/dist/templates/agent_instructions/CLAUDE.md.template +3 -3
  12. package/dist/templates/project/README.md.template +1 -1
  13. package/dist/templates/project/package.json.template +2 -0
  14. package/dist/templates/project/src/clients/jina.ts.template +1 -1
  15. package/dist/templates/project/src/workflows/blog_evaluator/evaluators.ts.template +1 -1
  16. package/dist/templates/workflow/README.md.template +2 -2
  17. package/dist/templates/workflow/evaluators.ts.template +1 -1
  18. package/dist/templates/workflow/steps.ts.template +1 -1
  19. package/dist/test_helpers/mocks.d.ts +1 -1
  20. package/dist/test_helpers/mocks.js +1 -1
  21. package/dist/types/cost.d.ts +1 -1
  22. package/dist/utils/eval_diagnostics.js +1 -1
  23. package/dist/utils/eval_naming.d.ts +1 -0
  24. package/dist/utils/eval_naming.js +2 -0
  25. package/dist/utils/eval_naming.spec.d.ts +1 -0
  26. package/dist/utils/eval_naming.spec.js +10 -0
  27. package/dist/utils/eval_render.d.ts +3 -0
  28. package/dist/utils/eval_render.js +75 -0
  29. package/dist/utils/eval_render.spec.d.ts +1 -0
  30. package/dist/utils/eval_render.spec.js +171 -0
  31. package/oclif.manifest.json +1 -1
  32. package/package.json +4 -5
@@ -80,7 +80,7 @@ services:
80
80
  condition: service_healthy
81
81
  worker:
82
82
  condition: service_healthy
83
- image: outputai/api:${OUTPUT_API_VERSION:-0.15.1-next.4a437bf.0}
83
+ image: outputai/api:${OUTPUT_API_VERSION:-0.15.1-next.5db73d3.0}
84
84
  init: true
85
85
  networks:
86
86
  - main
@@ -1,5 +1,5 @@
1
1
  import { Command } from '@oclif/core';
2
- import type { EvalOutput } from '@outputai/evals';
2
+ import type { EvalOutput } from '@outputai/core/evals';
3
3
  export default class WorkflowTest extends Command {
4
4
  static description: string;
5
5
  static enableJsonFlag: boolean;
@@ -5,7 +5,9 @@ import { readAllDatasets, writeDataset } from '#services/datasets.js';
5
5
  import { fetchWorkflowCatalog } from '#api/workflow_catalog.js';
6
6
  import { diagnoseMissingEvalWorkflow } from '#utils/eval_diagnostics.js';
7
7
  import { handleApiError } from '#utils/error_handler.js';
8
- import { getEvalWorkflowName, renderEvalOutput, computeExitCode, EvalOutputSchema } from '@outputai/evals';
8
+ import { getEvalWorkflowName } from '#utils/eval_naming.js';
9
+ import { renderEvalOutput, computeExitCode } from '#utils/eval_render.js';
10
+ import { EvalOutputSchema } from '@outputai/core/evals';
9
11
  export default class WorkflowTest extends Command {
10
12
  static description = 'Run evaluations against a workflow using its datasets';
11
13
  static enableJsonFlag = true;
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
- import { getEvalWorkflowName, renderEvalOutput } from '@outputai/evals';
3
+ import { getEvalWorkflowName } from '#utils/eval_naming.js';
4
+ import { renderEvalOutput } from '#utils/eval_render.js';
4
5
  vi.mock('#api/generated/api.js', () => ({
5
6
  postWorkflowRun: vi.fn()
6
7
  }));
@@ -1,3 +1,3 @@
1
1
  {
2
- "framework": "0.15.1-next.4a437bf.0"
2
+ "framework": "0.15.1-next.5db73d3.0"
3
3
  }
@@ -32,7 +32,7 @@ function priceLines(lines, pricing) {
32
32
  }, 0);
33
33
  }
34
34
  // Token counts for display. The producer's 'input' line excludes cached tokens
35
- // (sdk/llm emits input − cached), while AI SDK reports inputTokens as the
35
+ // (core/llm emits input − cached), while AI SDK reports inputTokens as the
36
36
  // total — add cached back so the columns match what providers report.
37
37
  function eventTokenUsage(lines) {
38
38
  const sumOf = (type) => lines.filter(l => l.type === type).reduce((s, l) => s + l.amount, 0);
@@ -1,4 +1,4 @@
1
- import type { Dataset } from '@outputai/evals';
1
+ import type { Dataset } from '@outputai/core/evals';
2
2
  export interface DatasetInfo {
3
3
  name: string;
4
4
  path: string;
@@ -2,7 +2,7 @@ import { readFile, writeFile, readdir, mkdir } from 'node:fs/promises';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { resolve, join } from 'node:path';
4
4
  import { load as parseYaml, dump as stringifyYaml } from 'js-yaml';
5
- import { DatasetSchema } from '@outputai/evals';
5
+ import { DatasetSchema } from '@outputai/core/evals';
6
6
  import { getTrace } from '#services/trace_reader.js';
7
7
  import { sanitizeSecrets } from '#utils/secret_sanitizer.js';
8
8
  import { resolveWorkflowDir, WORKFLOWS_PATHS } from '#utils/workflow_dir.js';
@@ -1,5 +1,5 @@
1
1
  import { initializeAgentConfig } from './coding_agents.js';
2
- import { generateText } from '@outputai/llm';
2
+ import { generateText } from '@outputai/core/llm';
3
3
  import fs from 'node:fs/promises';
4
4
  import path from 'node:path';
5
5
  import { config } from '#config.js';
@@ -1,10 +1,10 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
2
  import { generatePlanName, writePlanFile, updateAgentTemplates } from './workflow_planner.js';
3
3
  import { initializeAgentConfig } from './coding_agents.js';
4
- import { generateText } from '@outputai/llm';
4
+ import { generateText } from '@outputai/core/llm';
5
5
  import fs from 'node:fs/promises';
6
6
  vi.mock('./coding_agents.js');
7
- vi.mock('@outputai/llm');
7
+ vi.mock('@outputai/core/llm');
8
8
  vi.mock('node:fs/promises');
9
9
  const mockGenerateTextResult = (text) => ({
10
10
  text,
@@ -35,7 +35,7 @@ src/
35
35
  types.ts # Zod schemas and TypeScript types
36
36
  prompts/ # .prompt files (Liquid.js templates with YAML frontmatter)
37
37
  scenarios/ # Test scenario JSON files
38
- clients/ # Shared HTTP clients (use @outputai/http, not fetch/axios)
38
+ clients/ # Shared HTTP clients (use @outputai/core/http, not fetch/axios)
39
39
  shared/ # Shared utilities across workflows
40
40
  config/
41
41
  costs.yml # Token/API pricing overrides
@@ -46,8 +46,8 @@ config/
46
46
  ## Key Conventions
47
47
 
48
48
  - **Workflows are deterministic**: No I/O, no `Date.now()`, no `Math.random()` in `workflow.ts`. All side effects go in steps or evaluators.
49
- - **HTTP clients**: Use `outputFetch` or `createKyClient` from `@outputai/http` instead of raw `fetch` or `axios`. Requests are automatically traced; for paid APIs, attach spend via `addRequestCost` in an `afterResponse` hook (`output-dev-http-client-create`) and forward cost events with `output-dev-cost-hooks`.
50
- - **LLM calls**: Use `generateText` from `@outputai/llm` with `.prompt` files. Never call LLM APIs directly.
49
+ - **HTTP clients**: Use `outputFetch` or `createKyClient` from `@outputai/core/http` instead of raw `fetch` or `axios`. Requests are automatically traced; for paid APIs, attach spend via `addRequestCost` in an `afterResponse` hook (`output-dev-http-client-create`) and forward cost events with `output-dev-cost-hooks`.
50
+ - **LLM calls**: Use `generateText` from `@outputai/core/llm` with `.prompt` files. Never call LLM APIs directly.
51
51
 
52
52
  ---
53
53
 
@@ -27,7 +27,7 @@ src/
27
27
 
28
28
  ### Clients Directory
29
29
 
30
- The `src/clients/` directory contains API clients using `@outputai/http` for external services.
30
+ The `src/clients/` directory contains API clients using `@outputai/core/http` for external services.
31
31
 
32
32
  ### Shared Directory
33
33
 
@@ -14,6 +14,8 @@
14
14
  "output:dev": "output dev"
15
15
  },
16
16
  "dependencies": {
17
+ "@ai-sdk/anthropic": "4.0.61",
18
+ "@ai-sdk/openai": "4.0.73",
17
19
  "@outputai/output": "{{frameworkVersion}}"
18
20
  },
19
21
  "devDependencies": {
@@ -1,4 +1,4 @@
1
- import { createKyClient } from '@outputai/http';
1
+ import { createKyClient } from '@outputai/core/http';
2
2
 
3
3
  export interface JinaReaderResponse {
4
4
  code: number;
@@ -1,6 +1,6 @@
1
1
  import { evaluator, EvaluationNumberResult } from '@outputai/core';
2
2
  import type { EvaluationResultArgs } from '@outputai/core';
3
- import { generateText, aiSdk } from '@outputai/llm';
3
+ import { generateText, aiSdk } from '@outputai/core/llm';
4
4
  import { blogContentSchema } from './types.js';
5
5
  import type { BlogContent } from './types.js';
6
6
 
@@ -123,7 +123,7 @@ Define steps in `steps.ts` with schemas:
123
123
 
124
124
  ```typescript
125
125
  import { step, z } from '@outputai/core';
126
- import { generateText, aiSdk } from '@outputai/llm';
126
+ import { generateText, aiSdk } from '@outputai/core/llm';
127
127
 
128
128
  export const myStep = step( {
129
129
  name: 'my_step',
@@ -153,7 +153,7 @@ Define evaluators in `evaluators.ts`:
153
153
 
154
154
  ```typescript
155
155
  import { evaluator, z, EvaluationVerdictResult } from '@outputai/core';
156
- import { generateText, aiSdk } from '@outputai/llm';
156
+ import { generateText, aiSdk } from '@outputai/core/llm';
157
157
 
158
158
  export const evaluateQuality = evaluator( {
159
159
  name: 'evaluate_quality',
@@ -1,5 +1,5 @@
1
1
  import { evaluator, z, EvaluationVerdictResult } from '@outputai/core';
2
- import { generateText, aiSdk } from '@outputai/llm';
2
+ import { generateText, aiSdk } from '@outputai/core/llm';
3
3
 
4
4
  // TODO: Update the evaluator to assess your workflow's output quality
5
5
  export const evaluate{{WorkflowName}} = evaluator( {
@@ -1,5 +1,5 @@
1
1
  import { step, z } from '@outputai/core';
2
- import { generateText } from '@outputai/llm';
2
+ import { generateText } from '@outputai/core/llm';
3
3
 
4
4
  export const processText = step( {
5
5
  name: 'process_text',
@@ -6,7 +6,7 @@ export declare const mockClaudeAgentSDK: {
6
6
  Agent: Mock;
7
7
  };
8
8
  /**
9
- * Mock for @outputai/llm
9
+ * Mock for @outputai/core/llm
10
10
  */
11
11
  export declare const mockLLM: {
12
12
  generateText: Mock;
@@ -13,7 +13,7 @@ export const mockClaudeAgentSDK = {
13
13
  }))
14
14
  };
15
15
  /**
16
- * Mock for @outputai/llm
16
+ * Mock for @outputai/core/llm
17
17
  */
18
18
  export const mockLLM = {
19
19
  generateText: vi.fn().mockResolvedValue({
@@ -13,7 +13,7 @@ export interface TokenUsage {
13
13
  cachedInputTokens?: number;
14
14
  reasoningTokens?: number;
15
15
  }
16
- import type { LLMGenerationCost, LLMGenerationUsage, LLMUsageEvent } from '@outputai/llm';
16
+ import type { LLMGenerationCost, LLMGenerationUsage, LLMUsageEvent } from '@outputai/core/llm';
17
17
  export type LLMUsageLine = LLMUsageEvent['usage'][number];
18
18
  export interface HTTPCostEvent {
19
19
  type: 'http:request:cost';
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { resolve } from 'node:path';
3
- import { getEvalWorkflowName } from '@outputai/evals';
4
3
  import { resolveWorkflowDir } from '#utils/workflow_dir.js';
4
+ import { getEvalWorkflowName } from '#utils/eval_naming.js';
5
5
  const EVAL_WORKFLOW_FILES = ['tests/evals/workflow.ts', 'tests/evals/workflow.js'];
6
6
  /**
7
7
  * Explain why a `<wf>_eval` workflow isn't registered. When the eval source
@@ -0,0 +1 @@
1
+ export declare const getEvalWorkflowName: (workflowName: string) => string;
@@ -0,0 +1,2 @@
1
+ const EVAL_SUFFIX = '_eval';
2
+ export const getEvalWorkflowName = (workflowName) => `${workflowName}${EVAL_SUFFIX}`;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getEvalWorkflowName } from './eval_naming.js';
3
+ describe('naming', () => {
4
+ describe('getEvalWorkflowName', () => {
5
+ it('appends _eval suffix', () => {
6
+ expect(getEvalWorkflowName('simple')).toBe('simple_eval');
7
+ expect(getEvalWorkflowName('my_workflow')).toBe('my_workflow_eval');
8
+ });
9
+ });
10
+ });
@@ -0,0 +1,3 @@
1
+ import type { EvalOutput } from '@outputai/core/evals';
2
+ export declare function renderEvalOutput(evalOutput: EvalOutput, evalName?: string): string;
3
+ export declare function computeExitCode(evalOutput: EvalOutput): number;
@@ -0,0 +1,75 @@
1
+ import { VERDICT, CRITICALITY } from '@outputai/core/evals';
2
+ const COLORS = {
3
+ reset: '\x1b[0m',
4
+ green: '\x1b[32m',
5
+ yellow: '\x1b[33m',
6
+ red: '\x1b[31m',
7
+ dim: '\x1b[2m',
8
+ bold: '\x1b[1m',
9
+ cyan: '\x1b[36m'
10
+ };
11
+ const VERDICT_STYLE = {
12
+ [VERDICT.PASS]: { label: 'PASS', color: COLORS.green },
13
+ [VERDICT.PARTIAL]: { label: 'PARTIAL', color: COLORS.yellow },
14
+ [VERDICT.FAIL]: { label: 'FAIL', color: COLORS.red }
15
+ };
16
+ function colorize(text, color) {
17
+ return `${color}${text}${COLORS.reset}`;
18
+ }
19
+ function padWithDots(label, width = 30) {
20
+ const dotCount = Math.max(2, width - label.length);
21
+ return ` ${'.'.repeat(dotCount)} `;
22
+ }
23
+ function renderEvaluator(evaluator) {
24
+ const lines = [];
25
+ const style = VERDICT_STYLE[evaluator.verdict];
26
+ const prefix = evaluator.criticality === CRITICALITY.INFORMATIONAL ?
27
+ `${COLORS.dim}(info)${COLORS.reset} ` :
28
+ '';
29
+ lines.push(` ${prefix}${evaluator.name}${padWithDots(evaluator.name, 24)}${colorize(evaluator.verdict, style.color)}`);
30
+ if (evaluator.reasoning && evaluator.verdict !== VERDICT.PASS) {
31
+ lines.push(` ${COLORS.dim}-> ${evaluator.reasoning}${COLORS.reset}`);
32
+ }
33
+ if (evaluator.feedback) {
34
+ for (const fb of evaluator.feedback) {
35
+ const item = fb;
36
+ if (item.issue) {
37
+ lines.push(` ${COLORS.dim}-> ${item.issue}${COLORS.reset}`);
38
+ }
39
+ }
40
+ }
41
+ return lines;
42
+ }
43
+ function renderCase(evalCase) {
44
+ const caseStyle = VERDICT_STYLE[evalCase.verdict];
45
+ const lines = [
46
+ ` ${evalCase.datasetName}${padWithDots(evalCase.datasetName)}${colorize(caseStyle.label, caseStyle.color)}`
47
+ ];
48
+ evalCase.evaluators.forEach(evaluator => lines.push(...renderEvaluator(evaluator)));
49
+ lines.push('');
50
+ return lines;
51
+ }
52
+ export function renderEvalOutput(evalOutput, evalName) {
53
+ const lines = [];
54
+ if (evalName) {
55
+ lines.push(colorize(evalName, COLORS.bold));
56
+ lines.push('');
57
+ }
58
+ evalOutput.cases.forEach(evalCase => lines.push(...renderCase(evalCase)));
59
+ const { summary } = evalOutput;
60
+ const parts = [];
61
+ if (summary.passed > 0) {
62
+ parts.push(colorize(`${summary.passed} passed`, COLORS.green));
63
+ }
64
+ if (summary.partial > 0) {
65
+ parts.push(colorize(`${summary.partial} partial`, COLORS.yellow));
66
+ }
67
+ if (summary.failed > 0) {
68
+ parts.push(colorize(`${summary.failed} failed`, COLORS.red));
69
+ }
70
+ lines.push(`${parts.join(', ')} (${Math.round(summary.acceptableRate * 100)}% acceptable)`);
71
+ return lines.join('\n');
72
+ }
73
+ export function computeExitCode(evalOutput) {
74
+ return evalOutput.cases.some(c => c.verdict === VERDICT.FAIL) ? 1 : 0;
75
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,171 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { renderEvalOutput, computeExitCode } from './eval_render.js';
3
+ const makeOutput = (cases, overrides) => {
4
+ const passed = cases.filter(c => c.verdict === 'pass').length;
5
+ const partial = cases.filter(c => c.verdict === 'partial').length;
6
+ const failed = cases.filter(c => c.verdict === 'fail').length;
7
+ const total = cases.length;
8
+ return {
9
+ cases,
10
+ summary: {
11
+ total,
12
+ passed,
13
+ partial,
14
+ failed,
15
+ acceptableRate: total > 0 ? (passed + partial) / total : 0,
16
+ ...overrides
17
+ }
18
+ };
19
+ };
20
+ describe('computeExitCode', () => {
21
+ it('returns 0 when all cases pass', () => {
22
+ const output = makeOutput([
23
+ { datasetName: 'a', verdict: 'pass', evaluators: [] }
24
+ ]);
25
+ expect(computeExitCode(output)).toBe(0);
26
+ });
27
+ it('returns 0 when cases are partial but none fail', () => {
28
+ const output = makeOutput([
29
+ { datasetName: 'a', verdict: 'partial', evaluators: [] }
30
+ ]);
31
+ expect(computeExitCode(output)).toBe(0);
32
+ });
33
+ it('returns 1 when any case fails', () => {
34
+ const output = makeOutput([
35
+ { datasetName: 'a', verdict: 'pass', evaluators: [] },
36
+ { datasetName: 'b', verdict: 'fail', evaluators: [] }
37
+ ]);
38
+ expect(computeExitCode(output)).toBe(1);
39
+ });
40
+ it('returns 0 for empty cases', () => {
41
+ const output = makeOutput([]);
42
+ expect(computeExitCode(output)).toBe(0);
43
+ });
44
+ });
45
+ describe('renderEvalOutput', () => {
46
+ it('includes eval name when provided', () => {
47
+ const output = makeOutput([
48
+ { datasetName: 'test', verdict: 'pass', evaluators: [] }
49
+ ]);
50
+ const rendered = renderEvalOutput(output, 'my_eval');
51
+ expect(rendered).toContain('my_eval');
52
+ });
53
+ it('includes dataset names', () => {
54
+ const output = makeOutput([
55
+ { datasetName: 'basic_input', verdict: 'pass', evaluators: [] },
56
+ { datasetName: 'edge_case', verdict: 'fail', evaluators: [] }
57
+ ]);
58
+ const rendered = renderEvalOutput(output);
59
+ expect(rendered).toContain('basic_input');
60
+ expect(rendered).toContain('edge_case');
61
+ });
62
+ it('includes verdict labels', () => {
63
+ const output = makeOutput([
64
+ { datasetName: 'a', verdict: 'pass', evaluators: [] },
65
+ { datasetName: 'b', verdict: 'fail', evaluators: [] }
66
+ ]);
67
+ const rendered = renderEvalOutput(output);
68
+ expect(rendered).toContain('PASS');
69
+ expect(rendered).toContain('FAIL');
70
+ });
71
+ it('shows reasoning for failed evaluators', () => {
72
+ const output = makeOutput([
73
+ {
74
+ datasetName: 'test',
75
+ verdict: 'fail',
76
+ evaluators: [{
77
+ name: 'check',
78
+ verdict: 'fail',
79
+ criticality: 'required',
80
+ reasoning: 'Expected 15, got null'
81
+ }]
82
+ }
83
+ ]);
84
+ const rendered = renderEvalOutput(output);
85
+ expect(rendered).toContain('Expected 15, got null');
86
+ });
87
+ it('hides reasoning for passing evaluators', () => {
88
+ const output = makeOutput([
89
+ {
90
+ datasetName: 'test',
91
+ verdict: 'pass',
92
+ evaluators: [{
93
+ name: 'check',
94
+ verdict: 'pass',
95
+ criticality: 'required',
96
+ reasoning: 'All good'
97
+ }]
98
+ }
99
+ ]);
100
+ const rendered = renderEvalOutput(output);
101
+ expect(rendered).not.toContain('All good');
102
+ });
103
+ it('shows summary with acceptable rate', () => {
104
+ const output = makeOutput([
105
+ { datasetName: 'a', verdict: 'pass', evaluators: [] },
106
+ { datasetName: 'b', verdict: 'fail', evaluators: [] }
107
+ ]);
108
+ const rendered = renderEvalOutput(output);
109
+ expect(rendered).toContain('1 passed');
110
+ expect(rendered).toContain('1 failed');
111
+ expect(rendered).toContain('50% acceptable');
112
+ });
113
+ it('includes PARTIAL verdict label', () => {
114
+ const output = makeOutput([
115
+ { datasetName: 'a', verdict: 'partial', evaluators: [] }
116
+ ]);
117
+ const rendered = renderEvalOutput(output);
118
+ expect(rendered).toContain('PARTIAL');
119
+ });
120
+ it('shows reasoning for partial evaluators', () => {
121
+ const output = makeOutput([
122
+ {
123
+ datasetName: 'test',
124
+ verdict: 'partial',
125
+ evaluators: [{
126
+ name: 'check',
127
+ verdict: 'partial',
128
+ criticality: 'required',
129
+ reasoning: 'Close but not quite'
130
+ }]
131
+ }
132
+ ]);
133
+ const rendered = renderEvalOutput(output);
134
+ expect(rendered).toContain('Close but not quite');
135
+ });
136
+ it('renders feedback issues', () => {
137
+ const output = makeOutput([
138
+ {
139
+ datasetName: 'test',
140
+ verdict: 'fail',
141
+ evaluators: [{
142
+ name: 'check',
143
+ verdict: 'fail',
144
+ criticality: 'required',
145
+ feedback: [
146
+ { issue: 'Missing required field' },
147
+ { issue: 'Invalid format' }
148
+ ]
149
+ }]
150
+ }
151
+ ]);
152
+ const rendered = renderEvalOutput(output);
153
+ expect(rendered).toContain('Missing required field');
154
+ expect(rendered).toContain('Invalid format');
155
+ });
156
+ it('marks informational evaluators with (info) prefix', () => {
157
+ const output = makeOutput([
158
+ {
159
+ datasetName: 'test',
160
+ verdict: 'pass',
161
+ evaluators: [{
162
+ name: 'info_check',
163
+ verdict: 'fail',
164
+ criticality: 'informational'
165
+ }]
166
+ }
167
+ ]);
168
+ const rendered = renderEvalOutput(output);
169
+ expect(rendered).toContain('(info)');
170
+ });
171
+ });
@@ -1772,5 +1772,5 @@
1772
1772
  ]
1773
1773
  }
1774
1774
  },
1775
- "version": "0.15.1-next.4a437bf.0"
1775
+ "version": "0.15.1-next.5db73d3.0"
1776
1776
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outputai/cli",
3
- "version": "0.15.1-next.4a437bf.0",
3
+ "version": "0.15.1-next.5db73d3.0",
4
4
  "description": "CLI for Output.ai workflow generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -17,6 +17,7 @@
17
17
  "output": "./bin/run.js"
18
18
  },
19
19
  "dependencies": {
20
+ "@ai-sdk/anthropic": "4.0.61",
20
21
  "@anthropic-ai/claude-agent-sdk": "0.3.281",
21
22
  "@hackylabs/deep-redact": "3.0.5",
22
23
  "@inquirer/prompts": "8.7.2",
@@ -35,10 +36,8 @@
35
36
  "ky": "2.0.2",
36
37
  "react": "19.3.0",
37
38
  "semver": "7.8.5",
38
- "undici": "8.11.0",
39
- "@outputai/evals": "0.15.1-next.4a437bf.0",
40
- "@outputai/core": "0.15.1-next.4a437bf.0",
41
- "@outputai/llm": "0.15.1-next.4a437bf.0"
39
+ "undici": "8.10.2",
40
+ "@outputai/core": "0.15.1-next.5db73d3.0"
42
41
  },
43
42
  "devDependencies": {
44
43
  "@types/cli-progress": "3.11.6",