@qcobro/ctl 1.40.1 → 1.41.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.
package/README.md CHANGED
@@ -38,7 +38,7 @@ $ npm install -g @qcobro/ctl
38
38
  $ qcobro COMMAND
39
39
  running command...
40
40
  $ qcobro (--version)
41
- @qcobro/ctl/1.39.3 darwin-arm64 node-v22.17.0
41
+ @qcobro/ctl/1.40.1 darwin-arm64 node-v22.17.0
42
42
  $ qcobro --help [COMMAND]
43
43
  USAGE
44
44
  $ qcobro COMMAND
@@ -103,31 +103,39 @@ EXAMPLES
103
103
 
104
104
  ## `qcobro agents:eval`
105
105
 
106
- evaluate a VOICE_AI/EMAIL/WHATSAPP agent's conversation logic — either an existing template plus a scenarios file, or a standalone YAML eval template (agent definition plus its own embedded scenarios) that is never created. Streams each turn's result as it happens, then a final pass/fail summary; exits non-zero when the run fails. Pass --json to stream the raw events as JSONL instead. For a static SMS/VOICE_PRERECORDED render (no conversation), use `agents:preview` instead.
106
+ evaluate a VOICE_AI/EMAIL/WHATSAPP agent's conversation logic — either an existing template plus a scenarios file, or a standalone YAML eval template (agent definition plus its own embedded scenarios) that is never created. Streams each turn's result as it happens, then a final pass/fail summary; exits non-zero when the run fails. Use --format to pick the output (text stream, JSONL, or an html/pdf report) and --output to write it to a file. For a static SMS/VOICE_PRERECORDED render (no conversation), use `agents:preview` instead.
107
107
 
108
108
  ```
109
109
  USAGE
110
- $ qcobro agents:eval [--template-id <value>] [--scenarios <value>] [--file <value>] [--json]
110
+ $ qcobro agents:eval [--template-id <value>] [--scenarios <value>] [--file <value>] [--format
111
+ text|json|html|pdf] [--output <value>] [--title <value>]
111
112
 
112
113
  FLAGS
113
114
  --file=<value> path to a standalone YAML eval template (agent definition + embedded scenarios)
114
- --json emit each evaluation event as a JSON line (JSONL) on stdout instead of human-readable output
115
+ --format=<option> [default: text] text = human-readable stream (default); json = JSONL of raw events; html/pdf =
116
+ a self-contained evaluation report (requires --output)
117
+ <options: text|json|html|pdf>
118
+ --output=<value> write output to this file instead of stdout (required for html/pdf)
115
119
  --scenarios=<value> path to a YAML file with the scenarios to run (used with --template-id)
116
120
  --template-id=<value> an existing agent template id
121
+ --title=<value> report title for --format html/pdf (default is generic; pass a client name at run time if you
122
+ want one)
117
123
 
118
124
  DESCRIPTION
119
125
  evaluate a VOICE_AI/EMAIL/WHATSAPP agent's conversation logic — either an existing template plus a scenarios file, or
120
126
  a standalone YAML eval template (agent definition plus its own embedded scenarios) that is never created. Streams each
121
- turn's result as it happens, then a final pass/fail summary; exits non-zero when the run fails. Pass --json to stream
122
- the raw events as JSONL instead. For a static SMS/VOICE_PRERECORDED render (no conversation), use `agents:preview`
123
- instead.
127
+ turn's result as it happens, then a final pass/fail summary; exits non-zero when the run fails. Use --format to pick
128
+ the output (text stream, JSONL, or an html/pdf report) and --output to write it to a file. For a static
129
+ SMS/VOICE_PRERECORDED render (no conversation), use `agents:preview` instead.
124
130
 
125
131
  EXAMPLES
126
132
  $ qcobro agents:eval --template-id <id> --scenarios scenarios.yaml
127
133
 
128
134
  $ qcobro agents:eval --file eval-template.yaml
129
135
 
130
- $ qcobro agents:eval --file eval-template.yaml --json | jq
136
+ $ qcobro agents:eval --file eval-template.yaml --format json --output run.json
137
+
138
+ $ qcobro agents:eval --file eval-template.yaml --format pdf --output report.pdf
131
139
  ```
132
140
 
133
141
  ## `qcobro agents:preview`
@@ -6,15 +6,19 @@ export default class Eval extends AuthenticatedCommand<typeof Eval> {
6
6
  "template-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  scenarios: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
8
  file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
- json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
12
  };
11
13
  run(): Promise<void>;
12
14
  private buildInput;
15
+ /** Builds `ref -> { description, turnCount, account }` from the parsed `scenarios[]` (either input mode). */
16
+ private scenarioMeta;
13
17
  /** Resolves a `--file` / `--scenarios` path, failing the command cleanly if it is missing. */
14
18
  private resolvePath;
15
19
  /** Whether an event signals a failed turn / scenario / run. */
16
20
  private failed;
17
- /** Renders one evaluation event (human or JSONL); returns true if it signals a failure. */
18
- private printEvent;
21
+ /** Renders one evaluation event as human-readable line(s) (no trailing newline). */
22
+ private humanLine;
19
23
  }
20
24
  //# sourceMappingURL=eval.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/eval.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,oBAAoB,CAAC,OAAO,IAAI,CAAC;IACjE,gBAAyB,WAAW,SAMwB;IAC5D,gBAAyB,QAAQ,WAI/B;IACF,gBAAyB,KAAK;;;;;MAa5B;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAYjC,OAAO,CAAC,UAAU;IAqBlB,8FAA8F;IAC9F,OAAO,CAAC,WAAW;IAQnB,+DAA+D;IAC/D,OAAO,CAAC,MAAM;IAOd,2FAA2F;IAC3F,OAAO,CAAC,UAAU;CAqBnB"}
1
+ {"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/eval.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAerE,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,oBAAoB,CAAC,OAAO,IAAI,CAAC;IACjE,gBAAyB,WAAW,SAON;IAC9B,gBAAyB,QAAQ,WAK/B;IACF,gBAAyB,KAAK;;;;;;;MAuB5B;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAqEjC,OAAO,CAAC,UAAU;IAuBlB,6GAA6G;IAC7G,OAAO,CAAC,YAAY;IA0BpB,8FAA8F;IAC9F,OAAO,CAAC,WAAW;IAQnB,+DAA+D;IAC/D,OAAO,CAAC,MAAM;IAOd,oFAAoF;IACpF,OAAO,CAAC,SAAS;CAkBlB"}
@@ -1,4 +1,5 @@
1
- import { readFileSync } from "node:fs";
1
+ import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname } from "node:path";
2
3
  import { Flags } from "@oclif/core";
3
4
  import { parse as parseYaml } from "yaml";
4
5
  import { AuthenticatedCommand } from "../../AuthenticatedCommand.js";
@@ -7,13 +8,15 @@ export default class Eval extends AuthenticatedCommand {
7
8
  static description = "evaluate a VOICE_AI/EMAIL/WHATSAPP agent's conversation logic — either an existing " +
8
9
  "template plus a scenarios file, or a standalone YAML eval template (agent definition " +
9
10
  "plus its own embedded scenarios) that is never created. Streams each turn's result as " +
10
- "it happens, then a final pass/fail summary; exits non-zero when the run fails. Pass " +
11
- "--json to stream the raw events as JSONL instead. For a static SMS/VOICE_PRERECORDED " +
12
- "render (no conversation), use `agents:preview` instead.";
11
+ "it happens, then a final pass/fail summary; exits non-zero when the run fails. Use " +
12
+ "--format to pick the output (text stream, JSONL, or an html/pdf report) and --output " +
13
+ "to write it to a file. For a static SMS/VOICE_PRERECORDED render (no conversation), use " +
14
+ "`agents:preview` instead.";
13
15
  static examples = [
14
16
  "<%= config.bin %> <%= command.id %> --template-id <id> --scenarios scenarios.yaml",
15
17
  "<%= config.bin %> <%= command.id %> --file eval-template.yaml",
16
- "<%= config.bin %> <%= command.id %> --file eval-template.yaml --json | jq"
18
+ "<%= config.bin %> <%= command.id %> --file eval-template.yaml --format json --output run.json",
19
+ "<%= config.bin %> <%= command.id %> --file eval-template.yaml --format pdf --output report.pdf"
17
20
  ];
18
21
  static flags = {
19
22
  "template-id": Flags.string({ description: "an existing agent template id" }),
@@ -23,24 +26,90 @@ export default class Eval extends AuthenticatedCommand {
23
26
  file: Flags.string({
24
27
  description: "path to a standalone YAML eval template (agent definition + embedded scenarios)"
25
28
  }),
26
- json: Flags.boolean({
27
- description: "emit each evaluation event as a JSON line (JSONL) on stdout instead of human-readable output",
28
- default: false
29
+ format: Flags.string({
30
+ options: ["text", "json", "html", "pdf"],
31
+ default: "text",
32
+ description: "text = human-readable stream (default); json = JSONL of raw events; html/pdf = a " +
33
+ "self-contained evaluation report (requires --output)"
34
+ }),
35
+ output: Flags.string({
36
+ description: "write output to this file instead of stdout (required for html/pdf)"
37
+ }),
38
+ title: Flags.string({
39
+ description: "report title for --format html/pdf (default is generic; pass a client name at run " +
40
+ "time if you want one)"
29
41
  })
30
42
  };
31
43
  async run() {
32
44
  const { flags } = await this.parse(Eval);
45
+ const { format, output } = flags;
46
+ if ((format === "html" || format === "pdf") && !output) {
47
+ this.error(`--format ${format} requires --output <file>`, { exit: 1 });
48
+ }
49
+ const { input, scenariosMeta } = this.buildInput(flags);
33
50
  const client = await this.createSdkClient();
51
+ const stdoutStream = !output && (format === "text" || format === "json");
52
+ if (output && (format === "text" || format === "json")) {
53
+ mkdirSync(dirname(output), { recursive: true });
54
+ writeFileSync(output, "");
55
+ }
56
+ const events = [];
34
57
  let anyFailed = false;
35
- for await (const event of client.agentEvaluations.evaluate(this.buildInput(flags))) {
36
- anyFailed = this.printEvent(event, flags.json) || anyFailed;
58
+ let scenarioCount = 0;
59
+ let scenarioPass = 0;
60
+ for await (const event of client.agentEvaluations.evaluate(input)) {
61
+ if (event.type === "scenarioSummary") {
62
+ scenarioCount += 1;
63
+ if (event.overallPassed)
64
+ scenarioPass += 1;
65
+ }
66
+ if (format === "text") {
67
+ const line = this.humanLine(event);
68
+ if (stdoutStream)
69
+ this.log(line);
70
+ else
71
+ appendFileSync(output, `${line}\n`);
72
+ }
73
+ else if (format === "json") {
74
+ const line = JSON.stringify(event);
75
+ if (stdoutStream)
76
+ this.log(line);
77
+ else
78
+ appendFileSync(output, `${line}\n`);
79
+ }
80
+ else {
81
+ events.push(event);
82
+ }
83
+ anyFailed = this.failed(event) || anyFailed;
84
+ if (!stdoutStream && event.type === "scenarioSummary") {
85
+ this.logToStderr(`[${event.scenarioRef}] ${event.overallPassed ? "PASSED" : "FAILED"}`);
86
+ }
87
+ }
88
+ let model;
89
+ if (format === "html" || format === "pdf") {
90
+ const { buildReportModel, renderHtml, renderPdf } = await import("../../evalReport.js");
91
+ model = buildReportModel(events, scenariosMeta, { title: flags.title });
92
+ mkdirSync(dirname(output), { recursive: true });
93
+ if (format === "html") {
94
+ writeFileSync(output, renderHtml(model), "utf8");
95
+ }
96
+ else {
97
+ writeFileSync(output, await renderPdf(model));
98
+ }
99
+ }
100
+ if (!stdoutStream) {
101
+ const pass = model?.summary.pass ?? scenarioPass;
102
+ const total = model?.summary.total ?? scenarioCount;
103
+ this.logToStderr(`wrote ${output} (${pass}/${total} scenarios)`);
37
104
  }
38
105
  if (anyFailed)
39
106
  this.exit(1);
40
107
  }
41
108
  buildInput(flags) {
42
109
  if (flags.file) {
43
- return { yaml: readFileSync(this.resolvePath(flags.file), "utf8") };
110
+ const yaml = readFileSync(this.resolvePath(flags.file), "utf8");
111
+ const parsed = parseYaml(yaml);
112
+ return { input: { yaml }, scenariosMeta: this.scenarioMeta(parsed?.scenarios) };
44
113
  }
45
114
  if (flags["template-id"] && flags.scenarios) {
46
115
  const parsed = parseYaml(readFileSync(this.resolvePath(flags.scenarios), "utf8"));
@@ -48,12 +117,35 @@ export default class Eval extends AuthenticatedCommand {
48
117
  ? parsed
49
118
  : (parsed.scenarios ?? parsed);
50
119
  return {
51
- agentTemplateId: flags["template-id"],
52
- scenarios: scenarios
120
+ input: { agentTemplateId: flags["template-id"], scenarios: scenarios },
121
+ scenariosMeta: this.scenarioMeta(scenarios)
53
122
  };
54
123
  }
55
124
  return this.error("Provide --file, or both --template-id and --scenarios.", { exit: 1 });
56
125
  }
126
+ /** Builds `ref -> { description, turnCount, account }` from the parsed `scenarios[]` (either input mode). */
127
+ scenarioMeta(raw) {
128
+ const meta = new Map();
129
+ if (!Array.isArray(raw))
130
+ return meta;
131
+ for (const entry of raw) {
132
+ if (!entry || typeof entry !== "object")
133
+ continue;
134
+ const scenario = entry;
135
+ if (typeof scenario.ref !== "string")
136
+ continue;
137
+ meta.set(scenario.ref, {
138
+ description: typeof scenario.description === "string" ? scenario.description : "",
139
+ turnCount: Array.isArray(scenario.turns) ? scenario.turns.length : 0,
140
+ account: scenario.account &&
141
+ typeof scenario.account === "object" &&
142
+ !Array.isArray(scenario.account)
143
+ ? scenario.account
144
+ : undefined
145
+ });
146
+ }
147
+ return meta;
148
+ }
57
149
  /** Resolves a `--file` / `--scenarios` path, failing the command cleanly if it is missing. */
58
150
  resolvePath(input) {
59
151
  try {
@@ -73,30 +165,24 @@ export default class Eval extends AuthenticatedCommand {
73
165
  return event.verdict === "fail";
74
166
  return true; // error
75
167
  }
76
- /** Renders one evaluation event (human or JSONL); returns true if it signals a failure. */
77
- printEvent(event, asJson) {
78
- if (asJson) {
79
- this.log(JSON.stringify(event));
80
- return this.failed(event);
81
- }
168
+ /** Renders one evaluation event as human-readable line(s) (no trailing newline). */
169
+ humanLine(event) {
82
170
  if (event.type === "turn") {
83
171
  const verdict = event.result.passed === undefined ? "" : event.result.passed ? " ✓" : " ✗";
84
172
  const detail = event.result.action ?? event.result.aiResponse ?? event.result.input;
85
- this.log(`[${event.scenarioRef}] turn ${event.result.turnIndex}: ${detail}${verdict}`);
173
+ let line = `[${event.scenarioRef}] turn ${event.result.turnIndex}: ${detail}${verdict}`;
86
174
  if (event.result.passed === false && event.result.errorMessage) {
87
- this.log(` ↳ ${event.result.errorMessage}`);
175
+ line += `\n ↳ ${event.result.errorMessage}`;
88
176
  }
177
+ return line;
89
178
  }
90
- else if (event.type === "scenarioSummary") {
91
- this.log(`[${event.scenarioRef}] scenario ${event.overallPassed ? "PASSED" : "FAILED"}`);
92
- }
93
- else if (event.type === "summary") {
94
- this.log(`Overall: ${event.verdict.toUpperCase()} (${event.scenarios.length} scenario(s))`);
179
+ if (event.type === "scenarioSummary") {
180
+ return `[${event.scenarioRef}] scenario ${event.overallPassed ? "PASSED" : "FAILED"}`;
95
181
  }
96
- else {
97
- this.log(`Error: ${event.message}`);
182
+ if (event.type === "summary") {
183
+ return `Overall: ${event.verdict.toUpperCase()} (${event.scenarios.length} scenario(s))`;
98
184
  }
99
- return this.failed(event);
185
+ return `Error: ${event.message}`;
100
186
  }
101
187
  }
102
188
  //# sourceMappingURL=eval.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eval.js","sourceRoot":"","sources":["../../../src/commands/agents/eval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,oBAAiC;IACjE,MAAM,CAAmB,WAAW,GAClC,qFAAqF;QACrF,uFAAuF;QACvF,wFAAwF;QACxF,sFAAsF;QACtF,uFAAuF;QACvF,yDAAyD,CAAC;IAC5D,MAAM,CAAmB,QAAQ,GAAG;QAClC,mFAAmF;QACnF,+DAA+D;QAC/D,2EAA2E;KAC5E,CAAC;IACF,MAAM,CAAmB,KAAK,GAAG;QAC/B,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC;QAC7E,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;YACtB,WAAW,EAAE,yEAAyE;SACvF,CAAC;QACF,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,iFAAiF;SAC/F,CAAC;QACF,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;YAClB,WAAW,EACT,8FAA8F;YAChG,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAE5C,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACnF,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC9D,CAAC;QAED,IAAI,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAEO,UAAU,CAAC,KAIlB;QACC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QACtE,CAAC;QACD,IAAI,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAClF,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBACrC,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,CAAE,MAAkC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;YAC9D,OAAO;gBACL,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC;gBACrC,SAAS,EAAE,SAAkB;aAC9B,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,wDAAwD,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,8FAA8F;IACtF,WAAW,CAAC,KAAa;QAC/B,IAAI,CAAC;YACH,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,+DAA+D;IACvD,MAAM,CAAC,KAAgB;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC;QAChE,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAAE,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;QAClE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC;QAC9D,OAAO,IAAI,CAAC,CAAC,QAAQ;IACvB,CAAC;IAED,2FAA2F;IACnF,UAAU,CAAC,KAAgB,EAAE,MAAe;QAClD,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3F,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;YACpF,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,UAAU,KAAK,CAAC,MAAM,CAAC,SAAS,KAAK,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC;YACvF,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;gBAC/D,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,cAAc,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3F,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,SAAS,CAAC,MAAM,eAAe,CAAC,CAAC;QAC9F,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC"}
1
+ {"version":3,"file":"eval.js","sourceRoot":"","sources":["../../../src/commands/agents/eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { EvalEvent } from "@qcobro/common";
2
+ export interface ReportTurn {
3
+ index: number;
4
+ input: string;
5
+ expected?: string;
6
+ actual?: string;
7
+ evaluationType?: "EXACT" | "SIMILAR";
8
+ passed?: boolean;
9
+ errorMessage?: string;
10
+ tools?: Array<{
11
+ expected: string;
12
+ actual?: string;
13
+ passed: boolean;
14
+ }>;
15
+ }
16
+ export interface ReportScenario {
17
+ ref: string;
18
+ description: string;
19
+ /** The scenario's `account` block — the per-call metadata handed to the agent. */
20
+ metadata?: Record<string, unknown>;
21
+ passed: boolean;
22
+ turns: ReportTurn[];
23
+ }
24
+ export interface ReportModel {
25
+ title: string;
26
+ generatedAt: string;
27
+ summary: {
28
+ pass: number;
29
+ total: number;
30
+ verdict: "pass" | "fail";
31
+ };
32
+ scenarios: ReportScenario[];
33
+ errors: string[];
34
+ }
35
+ /** Walk the streamed events once and fold them into a render-ready model. */
36
+ export declare function buildReportModel(events: EvalEvent[], scenariosMeta: Map<string, {
37
+ description: string;
38
+ turnCount: number;
39
+ account?: Record<string, unknown>;
40
+ }>, opts?: {
41
+ title?: string;
42
+ }): ReportModel;
43
+ /** Render the model as one self-contained HTML document string. */
44
+ export declare function renderHtml(model: ReportModel): string;
45
+ /** Render the model as a PDF document. */
46
+ export declare function renderPdf(model: ReportModel): Promise<Buffer>;
47
+ //# sourceMappingURL=evalReport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evalReport.d.ts","sourceRoot":"","sources":["../src/evalReport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAgBhD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACnE,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EAAE,EACnB,aAAa,EAAE,GAAG,CAChB,MAAM,EACN;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAC9E,EACD,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5B,WAAW,CAoEb;AA6HD,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA6ErD;AA+GD,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAyC7D"}
@@ -0,0 +1,408 @@
1
+ import pdfMake from "pdfmake/build/pdfmake.js";
2
+ import pdfFonts from "pdfmake/build/vfs_fonts.js";
3
+ /**
4
+ * Pure, oclif-free builders for the `agents:eval` html/pdf report. The report is
5
+ * deliberately GENERIC — no customer names, no per-scenario copy, no hardcoded
6
+ * scenario maps — so it is safe to hand to anyone. A caller who wants a client
7
+ * name on the cover passes `--title` at run time.
8
+ */
9
+ const DEFAULT_TITLE = "Reporte de Evaluación — Agente Conversacional";
10
+ const ACCENT = "#12805a";
11
+ const AMBER = "#b45309";
12
+ /** Walk the streamed events once and fold them into a render-ready model. */
13
+ export function buildReportModel(events, scenariosMeta, opts = {}) {
14
+ const byRef = new Map();
15
+ const errors = [];
16
+ let summaryPass;
17
+ let summaryTotal;
18
+ let summaryVerdict;
19
+ const ensure = (ref) => {
20
+ let scenario = byRef.get(ref);
21
+ if (!scenario) {
22
+ scenario = {
23
+ ref,
24
+ description: scenariosMeta.get(ref)?.description ?? "",
25
+ metadata: scenariosMeta.get(ref)?.account,
26
+ passed: false,
27
+ turns: []
28
+ };
29
+ byRef.set(ref, scenario);
30
+ }
31
+ return scenario;
32
+ };
33
+ for (const event of events) {
34
+ if (event.type === "turn") {
35
+ const r = event.result;
36
+ ensure(event.scenarioRef).turns.push({
37
+ index: r.turnIndex,
38
+ input: r.input,
39
+ expected: r.expectedResponse,
40
+ actual: r.aiResponse,
41
+ evaluationType: r.evaluationType,
42
+ passed: r.passed,
43
+ errorMessage: r.errorMessage,
44
+ tools: r.toolEvaluations?.map((t) => ({
45
+ expected: t.expectedTool,
46
+ actual: t.actualTool,
47
+ passed: t.passed
48
+ }))
49
+ });
50
+ }
51
+ else if (event.type === "scenarioSummary") {
52
+ ensure(event.scenarioRef).passed = event.overallPassed;
53
+ }
54
+ else if (event.type === "summary") {
55
+ summaryVerdict = event.verdict;
56
+ summaryTotal = event.scenarios.length;
57
+ summaryPass = event.scenarios.filter((s) => s.overallPassed).length;
58
+ }
59
+ else {
60
+ errors.push(event.message);
61
+ }
62
+ }
63
+ const scenarios = [...byRef.values()];
64
+ const summary = summaryVerdict !== undefined
65
+ ? { pass: summaryPass ?? 0, total: summaryTotal ?? scenarios.length, verdict: summaryVerdict }
66
+ : (() => {
67
+ const total = scenarios.length;
68
+ const pass = scenarios.filter((s) => s.passed).length;
69
+ const verdict = pass === total ? "pass" : "fail";
70
+ return { pass, total, verdict };
71
+ })();
72
+ return {
73
+ title: opts.title?.trim() || DEFAULT_TITLE,
74
+ generatedAt: new Date().toISOString(),
75
+ summary,
76
+ scenarios,
77
+ errors
78
+ };
79
+ }
80
+ /** HTML-escape a value for safe interpolation into the report markup. */
81
+ function esc(value) {
82
+ return String(value ?? "")
83
+ .replace(/&/g, "&amp;")
84
+ .replace(/</g, "&lt;")
85
+ .replace(/>/g, "&gt;")
86
+ .replace(/"/g, "&quot;");
87
+ }
88
+ /** Turn an ISO timestamp into something a human wants to read. */
89
+ function readableDate(iso) {
90
+ return `${iso.replace("T", " ").slice(0, 16)} UTC`;
91
+ }
92
+ /** The `account` block as printable `[key, value]` pairs, dropping empty/nullish fields. */
93
+ function metadataPairs(md) {
94
+ if (!md)
95
+ return [];
96
+ const pairs = [];
97
+ for (const [key, value] of Object.entries(md)) {
98
+ if (value === null || value === undefined || value === "")
99
+ continue;
100
+ pairs.push([key, typeof value === "object" ? JSON.stringify(value) : String(value)]);
101
+ }
102
+ return pairs;
103
+ }
104
+ /** One line describing any failed tool / function call on a turn, or "" if none failed. */
105
+ function toolFailureNote(tools) {
106
+ const failed = (tools ?? []).filter((t) => !t.passed);
107
+ if (!failed.length)
108
+ return "";
109
+ return failed
110
+ .map((t) => t.actual
111
+ ? `llamada a función: se esperaba "${t.expected}", se invocó "${t.actual}"`
112
+ : `llamada a función: se esperaba "${t.expected}", no se invocó`)
113
+ .join("; ");
114
+ }
115
+ function turnRows(turns) {
116
+ return turns
117
+ .map((turn) => {
118
+ const mark = turn.passed === undefined ? "" : turn.passed ? "✓" : "✗";
119
+ const type = turn.evaluationType
120
+ ? ` <span class="muted">${esc(turn.evaluationType)}</span>`
121
+ : "";
122
+ const failLines = [];
123
+ if (turn.passed === false && turn.errorMessage)
124
+ failLines.push(esc(turn.errorMessage));
125
+ if (turn.passed === false) {
126
+ const note = toolFailureNote(turn.tools);
127
+ if (note)
128
+ failLines.push(esc(note));
129
+ }
130
+ const err = failLines.length ? `<div class="err">${failLines.join("<br>")}</div>` : "";
131
+ const main = `<tr>
132
+ <td>${esc(turn.index)}</td>
133
+ <td>${esc(turn.input)}</td>
134
+ <td>${esc(turn.expected ?? "")}</td>
135
+ <td>${esc(turn.actual ?? "")}</td>
136
+ <td>${mark}${type}${err}</td>
137
+ </tr>`;
138
+ if (!turn.tools?.length)
139
+ return main;
140
+ const tools = turn.tools
141
+ .map((t) => `${t.passed ? "✓" : "✗"} ${esc(t.expected)}${t.actual && t.actual !== t.expected ? ` → ${esc(t.actual)}` : ""}`)
142
+ .join("<br>");
143
+ return `${main}
144
+ <tr class="tools"><td></td><td colspan="4"><strong>Herramientas:</strong><br>${tools}</td></tr>`;
145
+ })
146
+ .join("\n");
147
+ }
148
+ function scenarioSection(scenario) {
149
+ const badgeColor = scenario.passed ? ACCENT : AMBER;
150
+ const badgeText = scenario.passed ? "PASSED" : "FAILED";
151
+ const description = scenario.description
152
+ ? `<p class="muted">${esc(scenario.description)}</p>`
153
+ : "";
154
+ const pairs = metadataPairs(scenario.metadata);
155
+ const metaBlock = pairs.length
156
+ ? `<p class="meta"><strong>Metadata de la llamada:</strong> ${pairs
157
+ .map(([key, value]) => `${esc(key)}: ${esc(value)}`)
158
+ .join(" &middot; ")}</p>`
159
+ : "";
160
+ return `<section class="scenario" id="${esc(scenario.ref)}">
161
+ <h2>${esc(scenario.ref)}</h2>
162
+ ${description}
163
+ ${metaBlock}
164
+ <p><span class="badge" style="background:${badgeColor}">${badgeText}</span></p>
165
+ <table>
166
+ <thead>
167
+ <tr><th>#</th><th>Entrada</th><th>Esperado</th><th>Obtenido</th><th>Estado</th></tr>
168
+ </thead>
169
+ <tbody>
170
+ ${turnRows(scenario.turns)}
171
+ </tbody>
172
+ </table>
173
+ </section>`;
174
+ }
175
+ /** The up-front table: every scenario with its id, description and status. */
176
+ function summaryTable(scenarios) {
177
+ const rows = scenarios
178
+ .map((s, i) => `<tr>
179
+ <td>${i + 1}</td>
180
+ <td><a href="#${esc(s.ref)}">${esc(s.ref)}</a></td>
181
+ <td class="muted">${esc(s.description)}</td>
182
+ <td class="${s.passed ? "st-ok" : "st-fail"}">${s.passed ? "PASSED" : "FAILED"}</td>
183
+ </tr>`)
184
+ .join("\n");
185
+ return `<section class="summary">
186
+ <h2>Resumen</h2>
187
+ <table>
188
+ <thead><tr><th>#</th><th>ID</th><th>Descripción</th><th>Estado</th></tr></thead>
189
+ <tbody>${rows}</tbody>
190
+ </table>
191
+ </section>`;
192
+ }
193
+ /** Render the model as one self-contained HTML document string. */
194
+ export function renderHtml(model) {
195
+ const errorsSection = model.errors.length
196
+ ? `<section class="errors">
197
+ <h2>Errores</h2>
198
+ <ul>${model.errors.map((e) => `<li>${esc(e)}</li>`).join("")}</ul>
199
+ </section>`
200
+ : "";
201
+ return `<!doctype html>
202
+ <html lang="es">
203
+ <head>
204
+ <meta charset="utf-8">
205
+ <meta name="viewport" content="width=device-width, initial-scale=1">
206
+ <title>${esc(model.title)}</title>
207
+ <style>
208
+ :root { color-scheme: light; }
209
+ body {
210
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
211
+ color: #1a1a1a;
212
+ background: #fff;
213
+ margin: 0;
214
+ padding: 32px 20px;
215
+ }
216
+ .sheet { max-width: 820px; margin: 0 auto; }
217
+ .wordmark { font-size: 20px; font-weight: 700; color: ${ACCENT}; }
218
+ .wordmark .sub { font-weight: 400; color: #6b7280; font-size: 13px; }
219
+ h1 { font-size: 22px; margin: 16px 0 4px; }
220
+ h2 { font-size: 16px; margin: 0 0 6px; }
221
+ .muted { color: #6b7280; }
222
+ .meta { color: #374151; font-size: 11px; margin: 4px 0 8px; }
223
+ .score {
224
+ border: 1px solid #e5e7eb;
225
+ border-radius: 8px;
226
+ padding: 16px 20px;
227
+ margin: 20px 0 28px;
228
+ }
229
+ .score .big { font-size: 32px; font-weight: 700; color: ${ACCENT}; }
230
+ .badge {
231
+ display: inline-block;
232
+ color: #fff;
233
+ font-size: 11px;
234
+ font-weight: 700;
235
+ letter-spacing: 0.04em;
236
+ padding: 2px 8px;
237
+ border-radius: 4px;
238
+ }
239
+ table { width: 100%; border-collapse: collapse; font-size: 12px; }
240
+ th, td { border: 1px solid #e5e7eb; padding: 6px 8px; text-align: left; vertical-align: top; }
241
+ th { background: #f9fafb; }
242
+ tr.tools td { background: #f9fafb; font-size: 11px; }
243
+ .err { color: ${AMBER}; margin-top: 4px; font-size: 11px; }
244
+ .scenario { margin-bottom: 28px; }
245
+ .summary { margin-bottom: 28px; }
246
+ .st-ok { color: ${ACCENT}; font-weight: 700; }
247
+ .st-fail { color: ${AMBER}; font-weight: 700; }
248
+ @media print {
249
+ body { padding: 0; }
250
+ .summary { break-after: page; }
251
+ .scenario { break-before: page; }
252
+ }
253
+ </style>
254
+ </head>
255
+ <body>
256
+ <div class="sheet">
257
+ <div class="wordmark">QCobro <span class="sub">· producto de Fonoster</span></div>
258
+ <h1>${esc(model.title)}</h1>
259
+ <p class="muted">Generado: ${esc(readableDate(model.generatedAt))}</p>
260
+ <div class="score">
261
+ <div><span class="big">${model.summary.pass}/${model.summary.total}</span> escenarios aprobados</div>
262
+ <div class="muted">Veredicto: ${esc(model.summary.verdict.toUpperCase())}</div>
263
+ </div>
264
+ ${summaryTable(model.scenarios)}
265
+ ${model.scenarios.map(scenarioSection).join("\n")}
266
+ ${errorsSection}
267
+ </div>
268
+ </body>
269
+ </html>`;
270
+ }
271
+ // pdfmake ships no first-class ESM types for its build entry points; cast through
272
+ // `unknown` to a narrow local shape (this adapter is the one pdfmake boundary).
273
+ const fontModule = pdfFonts;
274
+ const resolvedVfs = fontModule.vfs ?? fontModule.pdfMake?.vfs ?? pdfFonts;
275
+ pdfMake.vfs = resolvedVfs;
276
+ function pdfTurnRows(turns) {
277
+ const rows = [];
278
+ for (const turn of turns) {
279
+ // Plain-text markers: pdfmake's bundled Roboto has no ✓/✗ glyphs.
280
+ const mark = turn.passed === undefined ? "—" : turn.passed ? "OK" : "FALLA";
281
+ const detail = [];
282
+ if (turn.passed === false && turn.errorMessage) {
283
+ detail.push({ text: turn.errorMessage, fontSize: 7, color: AMBER });
284
+ }
285
+ if (turn.passed === false) {
286
+ const note = toolFailureNote(turn.tools);
287
+ if (note)
288
+ detail.push({ text: note, fontSize: 7, color: AMBER });
289
+ }
290
+ const status = detail.length
291
+ ? {
292
+ stack: [{ text: `${mark} ${turn.evaluationType ?? ""}`.trim(), color: AMBER }, ...detail]
293
+ }
294
+ : {
295
+ text: `${mark} ${turn.evaluationType ?? ""}`.trim(),
296
+ color: turn.passed === false ? AMBER : turn.passed ? ACCENT : undefined
297
+ };
298
+ rows.push([String(turn.index), turn.input, turn.expected ?? "", turn.actual ?? "", status]);
299
+ if (turn.tools?.length) {
300
+ const toolText = turn.tools
301
+ .map((t) => `${t.passed ? "OK" : "FALLA"} ${t.expected}${t.actual && t.actual !== t.expected ? ` -> ${t.actual}` : ""}`)
302
+ .join("\n");
303
+ rows.push(["", { text: `Herramientas:\n${toolText}`, colSpan: 4, fontSize: 7 }, {}, {}, {}]);
304
+ }
305
+ }
306
+ return rows;
307
+ }
308
+ /** The up-front table: every scenario with its id, description and status. */
309
+ function pdfSummaryTable(scenarios) {
310
+ const header = [
311
+ { text: "#", bold: true },
312
+ { text: "ID", bold: true },
313
+ { text: "Descripción", bold: true },
314
+ { text: "Estado", bold: true }
315
+ ];
316
+ const rows = scenarios.map((s, i) => [
317
+ String(i + 1),
318
+ s.ref,
319
+ { text: s.description, color: "#6b7280" },
320
+ { text: s.passed ? "PASSED" : "FAILED", bold: true, color: s.passed ? ACCENT : AMBER }
321
+ ]);
322
+ return {
323
+ table: { headerRows: 1, widths: ["auto", "auto", "*", "auto"], body: [header, ...rows] },
324
+ layout: "lightHorizontalLines",
325
+ margin: [0, 0, 0, 12]
326
+ };
327
+ }
328
+ function pdfScenario(scenario) {
329
+ const body = [
330
+ [
331
+ { text: "#", bold: true },
332
+ { text: "Entrada", bold: true },
333
+ { text: "Esperado", bold: true },
334
+ { text: "Obtenido", bold: true },
335
+ { text: "Estado", bold: true }
336
+ ],
337
+ ...pdfTurnRows(scenario.turns)
338
+ ];
339
+ const pairs = metadataPairs(scenario.metadata);
340
+ const metaLine = pairs.map(([key, value]) => `${key}: ${value}`).join(" · ");
341
+ return [
342
+ { text: scenario.ref, style: "h2", pageBreak: "before" },
343
+ ...(scenario.description
344
+ ? [{ text: scenario.description, color: "#6b7280", margin: [0, 0, 0, 2] }]
345
+ : []),
346
+ ...(metaLine
347
+ ? [
348
+ {
349
+ text: [{ text: "Metadata de la llamada: ", bold: true }, metaLine],
350
+ fontSize: 7,
351
+ color: "#374151",
352
+ margin: [0, 0, 0, 4]
353
+ }
354
+ ]
355
+ : []),
356
+ {
357
+ text: scenario.passed ? "PASSED" : "FAILED",
358
+ bold: true,
359
+ color: scenario.passed ? ACCENT : AMBER,
360
+ margin: [0, 0, 0, 4]
361
+ },
362
+ {
363
+ table: { headerRows: 1, widths: ["auto", "*", "*", "*", 90], body },
364
+ layout: "lightHorizontalLines"
365
+ }
366
+ ];
367
+ }
368
+ /** Render the model as a PDF document. */
369
+ export function renderPdf(model) {
370
+ const content = [
371
+ {
372
+ stack: [
373
+ { text: "QCobro", color: ACCENT, bold: true, fontSize: 14 },
374
+ { text: model.title, fontSize: 13 },
375
+ { text: `Generado: ${readableDate(model.generatedAt)}`, fontSize: 8, color: "#6b7280" }
376
+ ],
377
+ margin: [0, 0, 0, 10]
378
+ },
379
+ {
380
+ text: `${model.summary.pass}/${model.summary.total} escenarios aprobados · ` +
381
+ `veredicto: ${model.summary.verdict}`,
382
+ margin: [0, 0, 0, 12]
383
+ },
384
+ { text: "Resumen", style: "h2", margin: [0, 4, 0, 4] },
385
+ pdfSummaryTable(model.scenarios),
386
+ ...model.scenarios.flatMap((scenario) => pdfScenario(scenario))
387
+ ];
388
+ if (model.errors.length) {
389
+ content.push({ text: "Errores", style: "h2", margin: [0, 12, 0, 4] });
390
+ content.push({ ul: model.errors });
391
+ }
392
+ const docDefinition = {
393
+ pageSize: "A4",
394
+ pageMargins: [40, 50, 40, 40],
395
+ defaultStyle: { fontSize: 8 },
396
+ styles: { h2: { fontSize: 11, bold: true, margin: [0, 8, 0, 4] } },
397
+ content
398
+ };
399
+ return new Promise((resolve, reject) => {
400
+ try {
401
+ pdfMake.createPdf(docDefinition).getBuffer((buf) => resolve(Buffer.from(buf)));
402
+ }
403
+ catch (err) {
404
+ reject(err instanceof Error ? err : new Error(String(err)));
405
+ }
406
+ });
407
+ }
408
+ //# sourceMappingURL=evalReport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evalReport.js","sourceRoot":"","sources":["../src/evalReport.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qcobro/ctl",
3
- "version": "1.40.1",
3
+ "version": "1.41.0",
4
4
  "description": "Command-line tool for QCobro developers, built on @qcobro/sdk.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,16 +41,18 @@
41
41
  "@oclif/core": "^4.0.34",
42
42
  "@oclif/plugin-warn-if-update-available": "^3.1.28",
43
43
  "@qcobro/common": "^1.40.1",
44
- "@qcobro/sdk": "^1.40.1",
44
+ "@qcobro/sdk": "^1.41.0",
45
45
  "chalk": "^5.3.0",
46
46
  "cliui": "^8.0.1",
47
+ "pdfmake": "^0.2",
47
48
  "yaml": "^2.9.0",
48
49
  "zod": "^4.0.0"
49
50
  },
50
51
  "devDependencies": {
51
52
  "@oclif/test": "^4.1.3",
52
- "@qcobro/apiserver": "^1.40.1",
53
+ "@qcobro/apiserver": "^1.41.0",
53
54
  "@types/node": "22.10.1",
55
+ "@types/pdfmake": "^0.2",
54
56
  "oclif": "^4.17.46",
55
57
  "tsx": "^4.0.0",
56
58
  "typescript": "^5.9.0"