@langwatch/scenario 0.2.13 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,3 @@
1
- import "../../chunk-7P6ASYW6.mjs";
2
-
3
1
  // src/integrations/vitest/config.ts
4
2
  import { defineConfig } from "vitest/config";
5
3
  function withScenario(config) {
@@ -38,7 +38,7 @@ var import_path = __toESM(require("path"));
38
38
  var import_chalk = __toESM(require("chalk"));
39
39
 
40
40
  // src/config/env.ts
41
- var import_zod = require("zod");
41
+ var import_v4 = require("zod/v4");
42
42
 
43
43
  // src/config/log-levels.ts
44
44
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
@@ -51,37 +51,37 @@ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
51
51
  var LOG_LEVELS = Object.values(LogLevel);
52
52
 
53
53
  // src/config/env.ts
54
- var envSchema = import_zod.z.object({
54
+ var envSchema = import_v4.z.object({
55
55
  /**
56
56
  * LangWatch API key for event reporting.
57
57
  * If not provided, events will not be sent to LangWatch.
58
58
  */
59
- LANGWATCH_API_KEY: import_zod.z.string().optional(),
59
+ LANGWATCH_API_KEY: import_v4.z.string().optional(),
60
60
  /**
61
61
  * LangWatch endpoint URL for event reporting.
62
62
  * Defaults to the production LangWatch endpoint.
63
63
  */
64
- LANGWATCH_ENDPOINT: import_zod.z.string().url().optional().default("https://app.langwatch.ai"),
64
+ LANGWATCH_ENDPOINT: import_v4.z.string().url().optional().default("https://app.langwatch.ai"),
65
65
  /**
66
66
  * Disables simulation report info messages when set to any truthy value.
67
67
  * Useful for CI/CD environments or when you want cleaner output.
68
68
  */
69
- SCENARIO_DISABLE_SIMULATION_REPORT_INFO: import_zod.z.string().optional().transform((val) => Boolean(val)),
69
+ SCENARIO_DISABLE_SIMULATION_REPORT_INFO: import_v4.z.string().optional().transform((val) => Boolean(val)),
70
70
  /**
71
71
  * Node environment - affects logging and behavior.
72
72
  * Defaults to 'development' if not specified.
73
73
  */
74
- NODE_ENV: import_zod.z.enum(["development", "production", "test"]).default("development"),
74
+ NODE_ENV: import_v4.z.enum(["development", "production", "test"]).default("development"),
75
75
  /**
76
76
  * Case-insensitive log level for the scenario package.
77
77
  * Defaults to 'info' if not specified.
78
78
  */
79
- LOG_LEVEL: import_zod.z.string().toUpperCase().pipe(import_zod.z.nativeEnum(LogLevel)).optional().default("INFO" /* INFO */),
79
+ LOG_LEVEL: import_v4.z.string().toUpperCase().pipe(import_v4.z.nativeEnum(LogLevel)).optional().default("INFO" /* INFO */),
80
80
  /**
81
81
  * Scenario batch run ID.
82
82
  * If not provided, a random ID will be generated.
83
83
  */
84
- SCENARIO_BATCH_RUN_ID: import_zod.z.string().optional()
84
+ SCENARIO_BATCH_RUN_ID: import_v4.z.string().optional()
85
85
  });
86
86
  function getEnv() {
87
87
  return envSchema.parse(process.env);
@@ -186,6 +186,27 @@ function getFullTestName(task) {
186
186
  }
187
187
  return name;
188
188
  }
189
+ function formatContentForLogging(content) {
190
+ if (typeof content !== "string") {
191
+ return "[Non-text content]";
192
+ }
193
+ if (/^[A-Za-z0-9+/]+=*$/.test(content) && content.length > 50) {
194
+ return "[Binary data]";
195
+ }
196
+ try {
197
+ const parsed = JSON.parse(content);
198
+ if (Array.isArray(parsed)) {
199
+ const hasBinaryData = parsed.some(
200
+ (part) => (part == null ? void 0 : part.type) === "file" && (part == null ? void 0 : part.data) && typeof part.data === "string" && /^[A-Za-z0-9+/]+=*$/.test(part.data) && part.data.length > 50
201
+ );
202
+ if (hasBinaryData) {
203
+ return "[Content with binary data]";
204
+ }
205
+ }
206
+ } catch {
207
+ }
208
+ return content.length > 100 ? `${content.slice(0, 100)}...` : content;
209
+ }
189
210
  function indent(str, n = 2) {
190
211
  return str.replace(/^/gm, " ".repeat(n));
191
212
  }
@@ -284,7 +305,7 @@ ${indent(parsedJson)}
284
305
  `);
285
306
  continue;
286
307
  } else roleLabel = import_chalk.default.yellow(role);
287
- console.log(`${roleLabel}: ${m.content}`);
308
+ console.log(`${roleLabel}: ${formatContentForLogging(m.content)}`);
288
309
  }
289
310
  lastMessageCount = allMessages.length;
290
311
  }
@@ -321,8 +342,12 @@ ${indent(parsedJson)}
321
342
  console.log();
322
343
  console.log(import_chalk.default.bold.cyan("=== Scenario Test Report ==="));
323
344
  console.log(`Total Scenarios: ${total}`);
324
- console.log(import_chalk.default.green(`Passed: ${passed}`));
325
- console.log(import_chalk.default.red(`Failed: ${failed}`));
345
+ console.log(
346
+ passed > 0 ? import_chalk.default.green(`Passed: ${passed}`) : `Passed: ${passed}`
347
+ );
348
+ console.log(
349
+ failed > 0 ? import_chalk.default.red(`Failed: ${failed}`) : `Failed: ${failed}`
350
+ );
326
351
  console.log(`Success Rate: ${import_chalk.default.bold(`${successRate}%`)}`);
327
352
  this.results.forEach((r, i) => {
328
353
  const statusColor = r.status === "SUCCESS" ? import_chalk.default.green : import_chalk.default.red;
@@ -1,12 +1,138 @@
1
- import {
2
- Logger
3
- } from "../../chunk-OL4RFXV4.mjs";
4
- import "../../chunk-7P6ASYW6.mjs";
5
-
6
1
  // src/integrations/vitest/reporter.ts
7
2
  import fs from "fs";
8
3
  import path from "path";
9
4
  import chalk from "chalk";
5
+
6
+ // src/config/env.ts
7
+ import { z } from "zod/v4";
8
+
9
+ // src/config/log-levels.ts
10
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
11
+ LogLevel2["ERROR"] = "ERROR";
12
+ LogLevel2["WARN"] = "WARN";
13
+ LogLevel2["INFO"] = "INFO";
14
+ LogLevel2["DEBUG"] = "DEBUG";
15
+ return LogLevel2;
16
+ })(LogLevel || {});
17
+ var LOG_LEVELS = Object.values(LogLevel);
18
+
19
+ // src/config/env.ts
20
+ var envSchema = z.object({
21
+ /**
22
+ * LangWatch API key for event reporting.
23
+ * If not provided, events will not be sent to LangWatch.
24
+ */
25
+ LANGWATCH_API_KEY: z.string().optional(),
26
+ /**
27
+ * LangWatch endpoint URL for event reporting.
28
+ * Defaults to the production LangWatch endpoint.
29
+ */
30
+ LANGWATCH_ENDPOINT: z.string().url().optional().default("https://app.langwatch.ai"),
31
+ /**
32
+ * Disables simulation report info messages when set to any truthy value.
33
+ * Useful for CI/CD environments or when you want cleaner output.
34
+ */
35
+ SCENARIO_DISABLE_SIMULATION_REPORT_INFO: z.string().optional().transform((val) => Boolean(val)),
36
+ /**
37
+ * Node environment - affects logging and behavior.
38
+ * Defaults to 'development' if not specified.
39
+ */
40
+ NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
41
+ /**
42
+ * Case-insensitive log level for the scenario package.
43
+ * Defaults to 'info' if not specified.
44
+ */
45
+ LOG_LEVEL: z.string().toUpperCase().pipe(z.nativeEnum(LogLevel)).optional().default("INFO" /* INFO */),
46
+ /**
47
+ * Scenario batch run ID.
48
+ * If not provided, a random ID will be generated.
49
+ */
50
+ SCENARIO_BATCH_RUN_ID: z.string().optional()
51
+ });
52
+ function getEnv() {
53
+ return envSchema.parse(process.env);
54
+ }
55
+
56
+ // src/utils/logger.ts
57
+ var Logger = class _Logger {
58
+ constructor(context) {
59
+ this.context = context;
60
+ }
61
+ /**
62
+ * Creates a logger with context (e.g., class name)
63
+ */
64
+ static create(context) {
65
+ return new _Logger(context);
66
+ }
67
+ /**
68
+ * Returns the current log level from environment.
69
+ * Uses a getter for clarity and idiomatic usage.
70
+ */
71
+ get LOG_LEVEL() {
72
+ return getEnv().LOG_LEVEL;
73
+ }
74
+ /**
75
+ * Returns the index of the given log level in the LOG_LEVELS array.
76
+ * @param level - The log level to get the index for.
77
+ * @returns The index of the log level in the LOG_LEVELS array.
78
+ */
79
+ getLogLevelIndexFor(level) {
80
+ return LOG_LEVELS.indexOf(level);
81
+ }
82
+ /**
83
+ * Checks if logging should occur based on LOG_LEVEL env var
84
+ */
85
+ shouldLog(level) {
86
+ const currentLevelIndex = this.getLogLevelIndexFor(this.LOG_LEVEL);
87
+ const requestedLevelIndex = this.getLogLevelIndexFor(level);
88
+ return currentLevelIndex >= 0 && requestedLevelIndex <= currentLevelIndex;
89
+ }
90
+ formatMessage(message) {
91
+ return this.context ? `[${this.context}] ${message}` : message;
92
+ }
93
+ error(message, data) {
94
+ if (this.shouldLog("ERROR" /* ERROR */)) {
95
+ const formattedMessage = this.formatMessage(message);
96
+ if (data) {
97
+ console.error(formattedMessage, data);
98
+ } else {
99
+ console.error(formattedMessage);
100
+ }
101
+ }
102
+ }
103
+ warn(message, data) {
104
+ if (this.shouldLog("WARN" /* WARN */)) {
105
+ const formattedMessage = this.formatMessage(message);
106
+ if (data) {
107
+ console.warn(formattedMessage, data);
108
+ } else {
109
+ console.warn(formattedMessage);
110
+ }
111
+ }
112
+ }
113
+ info(message, data) {
114
+ if (this.shouldLog("INFO" /* INFO */)) {
115
+ const formattedMessage = this.formatMessage(message);
116
+ if (data) {
117
+ console.info(formattedMessage, data);
118
+ } else {
119
+ console.info(formattedMessage);
120
+ }
121
+ }
122
+ }
123
+ debug(message, data) {
124
+ if (this.shouldLog("DEBUG" /* DEBUG */)) {
125
+ const formattedMessage = this.formatMessage(message);
126
+ if (data) {
127
+ console.log(formattedMessage, data);
128
+ } else {
129
+ console.log(formattedMessage);
130
+ }
131
+ }
132
+ }
133
+ };
134
+
135
+ // src/integrations/vitest/reporter.ts
10
136
  var logger = Logger.create("integrations:vitest:reporter");
11
137
  function getProjectRoot() {
12
138
  return process.cwd();
@@ -26,6 +152,27 @@ function getFullTestName(task) {
26
152
  }
27
153
  return name;
28
154
  }
155
+ function formatContentForLogging(content) {
156
+ if (typeof content !== "string") {
157
+ return "[Non-text content]";
158
+ }
159
+ if (/^[A-Za-z0-9+/]+=*$/.test(content) && content.length > 50) {
160
+ return "[Binary data]";
161
+ }
162
+ try {
163
+ const parsed = JSON.parse(content);
164
+ if (Array.isArray(parsed)) {
165
+ const hasBinaryData = parsed.some(
166
+ (part) => (part == null ? void 0 : part.type) === "file" && (part == null ? void 0 : part.data) && typeof part.data === "string" && /^[A-Za-z0-9+/]+=*$/.test(part.data) && part.data.length > 50
167
+ );
168
+ if (hasBinaryData) {
169
+ return "[Content with binary data]";
170
+ }
171
+ }
172
+ } catch {
173
+ }
174
+ return content.length > 100 ? `${content.slice(0, 100)}...` : content;
175
+ }
29
176
  function indent(str, n = 2) {
30
177
  return str.replace(/^/gm, " ".repeat(n));
31
178
  }
@@ -124,7 +271,7 @@ ${indent(parsedJson)}
124
271
  `);
125
272
  continue;
126
273
  } else roleLabel = chalk.yellow(role);
127
- console.log(`${roleLabel}: ${m.content}`);
274
+ console.log(`${roleLabel}: ${formatContentForLogging(m.content)}`);
128
275
  }
129
276
  lastMessageCount = allMessages.length;
130
277
  }
@@ -161,8 +308,12 @@ ${indent(parsedJson)}
161
308
  console.log();
162
309
  console.log(chalk.bold.cyan("=== Scenario Test Report ==="));
163
310
  console.log(`Total Scenarios: ${total}`);
164
- console.log(chalk.green(`Passed: ${passed}`));
165
- console.log(chalk.red(`Failed: ${failed}`));
311
+ console.log(
312
+ passed > 0 ? chalk.green(`Passed: ${passed}`) : `Passed: ${passed}`
313
+ );
314
+ console.log(
315
+ failed > 0 ? chalk.red(`Failed: ${failed}`) : `Failed: ${failed}`
316
+ );
166
317
  console.log(`Success Rate: ${chalk.bold(`${successRate}%`)}`);
167
318
  this.results.forEach((r, i) => {
168
319
  const statusColor = r.status === "SUCCESS" ? chalk.green : chalk.red;
@@ -1,5 +1,3 @@
1
- import "../../chunk-7P6ASYW6.mjs";
2
-
3
1
  // src/integrations/vitest/setup-global.ts
4
2
  import { generate } from "xksuid";
5
3
  function setup() {
@@ -31,10 +31,13 @@ var import_vitest = require("vitest");
31
31
  var import_rxjs = require("rxjs");
32
32
 
33
33
  // src/events/event-alert-message-logger.ts
34
+ var fs2 = __toESM(require("fs"));
35
+ var os = __toESM(require("os"));
36
+ var path2 = __toESM(require("path"));
34
37
  var import_open = __toESM(require("open"));
35
38
 
36
39
  // src/config/env.ts
37
- var import_zod = require("zod");
40
+ var import_v4 = require("zod/v4");
38
41
 
39
42
  // src/config/log-levels.ts
40
43
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
@@ -47,37 +50,37 @@ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
47
50
  var LOG_LEVELS = Object.values(LogLevel);
48
51
 
49
52
  // src/config/env.ts
50
- var envSchema = import_zod.z.object({
53
+ var envSchema = import_v4.z.object({
51
54
  /**
52
55
  * LangWatch API key for event reporting.
53
56
  * If not provided, events will not be sent to LangWatch.
54
57
  */
55
- LANGWATCH_API_KEY: import_zod.z.string().optional(),
58
+ LANGWATCH_API_KEY: import_v4.z.string().optional(),
56
59
  /**
57
60
  * LangWatch endpoint URL for event reporting.
58
61
  * Defaults to the production LangWatch endpoint.
59
62
  */
60
- LANGWATCH_ENDPOINT: import_zod.z.string().url().optional().default("https://app.langwatch.ai"),
63
+ LANGWATCH_ENDPOINT: import_v4.z.string().url().optional().default("https://app.langwatch.ai"),
61
64
  /**
62
65
  * Disables simulation report info messages when set to any truthy value.
63
66
  * Useful for CI/CD environments or when you want cleaner output.
64
67
  */
65
- SCENARIO_DISABLE_SIMULATION_REPORT_INFO: import_zod.z.string().optional().transform((val) => Boolean(val)),
68
+ SCENARIO_DISABLE_SIMULATION_REPORT_INFO: import_v4.z.string().optional().transform((val) => Boolean(val)),
66
69
  /**
67
70
  * Node environment - affects logging and behavior.
68
71
  * Defaults to 'development' if not specified.
69
72
  */
70
- NODE_ENV: import_zod.z.enum(["development", "production", "test"]).default("development"),
73
+ NODE_ENV: import_v4.z.enum(["development", "production", "test"]).default("development"),
71
74
  /**
72
75
  * Case-insensitive log level for the scenario package.
73
76
  * Defaults to 'info' if not specified.
74
77
  */
75
- LOG_LEVEL: import_zod.z.string().toUpperCase().pipe(import_zod.z.nativeEnum(LogLevel)).optional().default("INFO" /* INFO */),
78
+ LOG_LEVEL: import_v4.z.string().toUpperCase().pipe(import_v4.z.nativeEnum(LogLevel)).optional().default("INFO" /* INFO */),
76
79
  /**
77
80
  * Scenario batch run ID.
78
81
  * If not provided, a random ID will be generated.
79
82
  */
80
- SCENARIO_BATCH_RUN_ID: import_zod.z.string().optional()
83
+ SCENARIO_BATCH_RUN_ID: import_v4.z.string().optional()
81
84
  });
82
85
  function getEnv() {
83
86
  return envSchema.parse(process.env);
@@ -89,17 +92,28 @@ var import_node_path = __toESM(require("path"));
89
92
  var import_node_url = require("url");
90
93
 
91
94
  // src/domain/core/config.ts
92
- var import_zod2 = require("zod");
95
+ var import_v43 = require("zod/v4");
96
+
97
+ // src/domain/core/schemas/model.schema.ts
98
+ var import_v42 = require("zod/v4");
99
+
100
+ // src/domain/core/constants.ts
93
101
  var DEFAULT_TEMPERATURE = 0;
94
- var scenarioProjectConfigSchema = import_zod2.z.object({
95
- defaultModel: import_zod2.z.object({
96
- model: import_zod2.z.custom(),
97
- temperature: import_zod2.z.number().min(0).max(1).optional().default(DEFAULT_TEMPERATURE),
98
- maxTokens: import_zod2.z.number().optional()
99
- }).optional(),
100
- headless: import_zod2.z.boolean().optional().default(
101
- typeof process !== "undefined" ? !["false", "0"].includes(process.env.SCENARIO_HEADLESS || "false") : false
102
- )
102
+
103
+ // src/domain/core/schemas/model.schema.ts
104
+ var modelSchema = import_v42.z.object({
105
+ model: import_v42.z.custom((val) => Boolean(val), {
106
+ message: "A model is required. Configure it in scenario.config.js defaultModel or pass directly to the agent."
107
+ }).describe("The OpenAI Language Model to use for generating responses."),
108
+ temperature: import_v42.z.number().min(0).max(1).optional().describe("The temperature for the language model.").default(DEFAULT_TEMPERATURE),
109
+ maxTokens: import_v42.z.number().optional().describe("The maximum number of tokens to generate.")
110
+ });
111
+
112
+ // src/domain/core/config.ts
113
+ var headless = typeof process !== "undefined" ? process.env.SCENARIO_HEADLESS === "true" : false;
114
+ var scenarioProjectConfigSchema = import_v43.z.object({
115
+ defaultModel: modelSchema.optional(),
116
+ headless: import_v43.z.boolean().optional().default(headless)
103
117
  }).strict();
104
118
 
105
119
  // src/config/load.ts
@@ -273,8 +287,23 @@ function getISOWeekNumber(date) {
273
287
  }
274
288
 
275
289
  // src/events/event-alert-message-logger.ts
276
- var EventAlertMessageLogger = class _EventAlertMessageLogger {
277
- static shownBatchIds = /* @__PURE__ */ new Set();
290
+ var EventAlertMessageLogger = class {
291
+ /**
292
+ * Creates a coordination file to prevent duplicate messages across processes.
293
+ * Returns true if this process should show the message (first one to create the file).
294
+ */
295
+ createCoordinationFile(type) {
296
+ try {
297
+ const batchId = getBatchRunId();
298
+ const tmpDir = os.tmpdir();
299
+ const fileName = `scenario-${type}-${batchId}`;
300
+ const filePath = path2.join(tmpDir, fileName);
301
+ fs2.writeFileSync(filePath, process.pid.toString(), { flag: "wx" });
302
+ return true;
303
+ } catch {
304
+ return false;
305
+ }
306
+ }
278
307
  /**
279
308
  * Shows a fancy greeting message about simulation reporting status.
280
309
  * Only shows once per batch run to avoid spam.
@@ -283,10 +312,9 @@ var EventAlertMessageLogger = class _EventAlertMessageLogger {
283
312
  if (this.isGreetingDisabled()) {
284
313
  return;
285
314
  }
286
- if (_EventAlertMessageLogger.shownBatchIds.has(getBatchRunId())) {
315
+ if (!this.createCoordinationFile("greeting")) {
287
316
  return;
288
317
  }
289
- _EventAlertMessageLogger.shownBatchIds.add(getBatchRunId());
290
318
  this.displayGreeting();
291
319
  }
292
320
  /**
@@ -297,6 +325,9 @@ var EventAlertMessageLogger = class _EventAlertMessageLogger {
297
325
  if (this.isGreetingDisabled()) {
298
326
  return;
299
327
  }
328
+ if (!this.createCoordinationFile(`watch-${params.scenarioSetId}`)) {
329
+ return;
330
+ }
300
331
  await this.displayWatchMessage(params);
301
332
  }
302
333
  isGreetingDisabled() {
@@ -344,7 +375,7 @@ ${separator}`);
344
375
 
345
376
  // src/events/schema.ts
346
377
  var import_core = require("@ag-ui/core");
347
- var import_zod3 = require("zod");
378
+ var import_zod = require("zod");
348
379
  var Verdict = /* @__PURE__ */ ((Verdict2) => {
349
380
  Verdict2["SUCCESS"] = "success";
350
381
  Verdict2["FAILURE"] = "failure";
@@ -360,59 +391,59 @@ var ScenarioRunStatus = /* @__PURE__ */ ((ScenarioRunStatus2) => {
360
391
  ScenarioRunStatus2["FAILED"] = "FAILED";
361
392
  return ScenarioRunStatus2;
362
393
  })(ScenarioRunStatus || {});
363
- var baseEventSchema = import_zod3.z.object({
364
- type: import_zod3.z.nativeEnum(import_core.EventType),
365
- timestamp: import_zod3.z.number(),
366
- rawEvent: import_zod3.z.any().optional()
394
+ var baseEventSchema = import_zod.z.object({
395
+ type: import_zod.z.nativeEnum(import_core.EventType),
396
+ timestamp: import_zod.z.number(),
397
+ rawEvent: import_zod.z.any().optional()
367
398
  });
368
- var batchRunIdSchema = import_zod3.z.string();
369
- var scenarioRunIdSchema = import_zod3.z.string();
370
- var scenarioIdSchema = import_zod3.z.string();
399
+ var batchRunIdSchema = import_zod.z.string();
400
+ var scenarioRunIdSchema = import_zod.z.string();
401
+ var scenarioIdSchema = import_zod.z.string();
371
402
  var baseScenarioEventSchema = baseEventSchema.extend({
372
403
  batchRunId: batchRunIdSchema,
373
404
  scenarioId: scenarioIdSchema,
374
405
  scenarioRunId: scenarioRunIdSchema,
375
- scenarioSetId: import_zod3.z.string().optional().default("default")
406
+ scenarioSetId: import_zod.z.string().optional().default("default")
376
407
  });
377
408
  var scenarioRunStartedSchema = baseScenarioEventSchema.extend({
378
- type: import_zod3.z.literal("SCENARIO_RUN_STARTED" /* RUN_STARTED */),
379
- metadata: import_zod3.z.object({
380
- name: import_zod3.z.string().optional(),
381
- description: import_zod3.z.string().optional()
409
+ type: import_zod.z.literal("SCENARIO_RUN_STARTED" /* RUN_STARTED */),
410
+ metadata: import_zod.z.object({
411
+ name: import_zod.z.string().optional(),
412
+ description: import_zod.z.string().optional()
382
413
  })
383
414
  });
384
- var scenarioResultsSchema = import_zod3.z.object({
385
- verdict: import_zod3.z.nativeEnum(Verdict),
386
- reasoning: import_zod3.z.string().optional(),
387
- metCriteria: import_zod3.z.array(import_zod3.z.string()),
388
- unmetCriteria: import_zod3.z.array(import_zod3.z.string()),
389
- error: import_zod3.z.string().optional()
415
+ var scenarioResultsSchema = import_zod.z.object({
416
+ verdict: import_zod.z.nativeEnum(Verdict),
417
+ reasoning: import_zod.z.string().optional(),
418
+ metCriteria: import_zod.z.array(import_zod.z.string()),
419
+ unmetCriteria: import_zod.z.array(import_zod.z.string()),
420
+ error: import_zod.z.string().optional()
390
421
  });
391
422
  var scenarioRunFinishedSchema = baseScenarioEventSchema.extend({
392
- type: import_zod3.z.literal("SCENARIO_RUN_FINISHED" /* RUN_FINISHED */),
393
- status: import_zod3.z.nativeEnum(ScenarioRunStatus),
423
+ type: import_zod.z.literal("SCENARIO_RUN_FINISHED" /* RUN_FINISHED */),
424
+ status: import_zod.z.nativeEnum(ScenarioRunStatus),
394
425
  results: scenarioResultsSchema.optional().nullable()
395
426
  });
396
427
  var scenarioMessageSnapshotSchema = import_core.MessagesSnapshotEventSchema.merge(
397
428
  baseScenarioEventSchema.extend({
398
- type: import_zod3.z.literal("SCENARIO_MESSAGE_SNAPSHOT" /* MESSAGE_SNAPSHOT */)
429
+ type: import_zod.z.literal("SCENARIO_MESSAGE_SNAPSHOT" /* MESSAGE_SNAPSHOT */)
399
430
  })
400
431
  );
401
- var scenarioEventSchema = import_zod3.z.discriminatedUnion("type", [
432
+ var scenarioEventSchema = import_zod.z.discriminatedUnion("type", [
402
433
  scenarioRunStartedSchema,
403
434
  scenarioRunFinishedSchema,
404
435
  scenarioMessageSnapshotSchema
405
436
  ]);
406
- var successSchema = import_zod3.z.object({ success: import_zod3.z.boolean() });
407
- var errorSchema = import_zod3.z.object({ error: import_zod3.z.string() });
408
- var stateSchema = import_zod3.z.object({
409
- state: import_zod3.z.object({
410
- messages: import_zod3.z.array(import_zod3.z.any()),
411
- status: import_zod3.z.string()
437
+ var successSchema = import_zod.z.object({ success: import_zod.z.boolean() });
438
+ var errorSchema = import_zod.z.object({ error: import_zod.z.string() });
439
+ var stateSchema = import_zod.z.object({
440
+ state: import_zod.z.object({
441
+ messages: import_zod.z.array(import_zod.z.any()),
442
+ status: import_zod.z.string()
412
443
  })
413
444
  });
414
- var runsSchema = import_zod3.z.object({ runs: import_zod3.z.array(import_zod3.z.string()) });
415
- var eventsSchema = import_zod3.z.object({ events: import_zod3.z.array(scenarioEventSchema) });
445
+ var runsSchema = import_zod.z.object({ runs: import_zod.z.array(import_zod.z.string()) });
446
+ var eventsSchema = import_zod.z.object({ events: import_zod.z.array(scenarioEventSchema) });
416
447
 
417
448
  // src/events/event-reporter.ts
418
449
  var EventReporter = class {
@@ -456,6 +487,7 @@ var EventReporter = class {
456
487
  } else {
457
488
  const errorText = await response.text();
458
489
  this.logger.error(`[${event.type}] Event POST failed:`, {
490
+ endpoint: this.eventsEndpoint.href,
459
491
  status: response.status,
460
492
  statusText: response.statusText,
461
493
  error: errorText,