@langwatch/scenario 0.2.0 → 0.2.1
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/dist/chunk-ZMHTHRDR.mjs +618 -0
- package/dist/index.js +232 -87
- package/dist/index.mjs +44 -167
- package/dist/integrations/vitest/setup.js +280 -105
- package/dist/integrations/vitest/setup.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-ORWSJC5F.mjs +0 -309
package/dist/index.js
CHANGED
|
@@ -63,7 +63,7 @@ __export(agents_exports, {
|
|
|
63
63
|
|
|
64
64
|
// src/agents/judge-agent.ts
|
|
65
65
|
var import_ai = require("ai");
|
|
66
|
-
var
|
|
66
|
+
var import_zod3 = require("zod");
|
|
67
67
|
|
|
68
68
|
// src/domain/index.ts
|
|
69
69
|
var domain_exports = {};
|
|
@@ -218,21 +218,25 @@ var Logger = class _Logger {
|
|
|
218
218
|
static create(context) {
|
|
219
219
|
return new _Logger(context);
|
|
220
220
|
}
|
|
221
|
+
getLogLevel() {
|
|
222
|
+
return env.SCENARIO_LOG_LEVEL ?? "INFO" /* INFO */;
|
|
223
|
+
}
|
|
224
|
+
getLogLevelIndex(level) {
|
|
225
|
+
return Object.values(LogLevel).indexOf(level);
|
|
226
|
+
}
|
|
221
227
|
/**
|
|
222
228
|
* Checks if logging should occur based on LOG_LEVEL env var
|
|
223
229
|
*/
|
|
224
230
|
shouldLog(level) {
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
-
const currentLevelIndex = levels.indexOf(logLevel);
|
|
228
|
-
const requestedLevelIndex = levels.indexOf(level);
|
|
231
|
+
const currentLevelIndex = this.getLogLevelIndex(this.getLogLevel());
|
|
232
|
+
const requestedLevelIndex = this.getLogLevelIndex(level);
|
|
229
233
|
return currentLevelIndex >= 0 && requestedLevelIndex <= currentLevelIndex;
|
|
230
234
|
}
|
|
231
235
|
formatMessage(message2) {
|
|
232
236
|
return this.context ? `[${this.context}] ${message2}` : message2;
|
|
233
237
|
}
|
|
234
238
|
error(message2, data) {
|
|
235
|
-
if (this.shouldLog("
|
|
239
|
+
if (this.shouldLog("ERROR" /* ERROR */)) {
|
|
236
240
|
const formattedMessage = this.formatMessage(message2);
|
|
237
241
|
if (data) {
|
|
238
242
|
console.error(formattedMessage, data);
|
|
@@ -242,7 +246,7 @@ var Logger = class _Logger {
|
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
248
|
warn(message2, data) {
|
|
245
|
-
if (this.shouldLog("
|
|
249
|
+
if (this.shouldLog("WARN" /* WARN */)) {
|
|
246
250
|
const formattedMessage = this.formatMessage(message2);
|
|
247
251
|
if (data) {
|
|
248
252
|
console.warn(formattedMessage, data);
|
|
@@ -252,7 +256,7 @@ var Logger = class _Logger {
|
|
|
252
256
|
}
|
|
253
257
|
}
|
|
254
258
|
info(message2, data) {
|
|
255
|
-
if (this.shouldLog("
|
|
259
|
+
if (this.shouldLog("INFO" /* INFO */)) {
|
|
256
260
|
const formattedMessage = this.formatMessage(message2);
|
|
257
261
|
if (data) {
|
|
258
262
|
console.info(formattedMessage, data);
|
|
@@ -262,7 +266,7 @@ var Logger = class _Logger {
|
|
|
262
266
|
}
|
|
263
267
|
}
|
|
264
268
|
debug(message2, data) {
|
|
265
|
-
if (this.shouldLog("
|
|
269
|
+
if (this.shouldLog("DEBUG" /* DEBUG */)) {
|
|
266
270
|
const formattedMessage = this.formatMessage(message2);
|
|
267
271
|
if (data) {
|
|
268
272
|
console.log(formattedMessage, data);
|
|
@@ -273,6 +277,53 @@ var Logger = class _Logger {
|
|
|
273
277
|
}
|
|
274
278
|
};
|
|
275
279
|
|
|
280
|
+
// src/config/env.ts
|
|
281
|
+
var import_zod2 = require("zod");
|
|
282
|
+
|
|
283
|
+
// src/config/log-levels.ts
|
|
284
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
285
|
+
LogLevel2["ERROR"] = "ERROR";
|
|
286
|
+
LogLevel2["WARN"] = "WARN";
|
|
287
|
+
LogLevel2["INFO"] = "INFO";
|
|
288
|
+
LogLevel2["DEBUG"] = "DEBUG";
|
|
289
|
+
return LogLevel2;
|
|
290
|
+
})(LogLevel || {});
|
|
291
|
+
|
|
292
|
+
// src/config/env.ts
|
|
293
|
+
var envSchema = import_zod2.z.object({
|
|
294
|
+
/**
|
|
295
|
+
* LangWatch API key for event reporting.
|
|
296
|
+
* If not provided, events will not be sent to LangWatch.
|
|
297
|
+
*/
|
|
298
|
+
LANGWATCH_API_KEY: import_zod2.z.string().optional(),
|
|
299
|
+
/**
|
|
300
|
+
* LangWatch endpoint URL for event reporting.
|
|
301
|
+
* Defaults to the production LangWatch endpoint.
|
|
302
|
+
*/
|
|
303
|
+
LANGWATCH_ENDPOINT: import_zod2.z.string().url().default("https://app.langwatch.ai"),
|
|
304
|
+
/**
|
|
305
|
+
* Disables simulation report info messages when set to any truthy value.
|
|
306
|
+
* Useful for CI/CD environments or when you want cleaner output.
|
|
307
|
+
*/
|
|
308
|
+
SCENARIO_DISABLE_SIMULATION_REPORT_INFO: import_zod2.z.string().optional().transform((val) => Boolean(val)),
|
|
309
|
+
/**
|
|
310
|
+
* Node environment - affects logging and behavior.
|
|
311
|
+
* Defaults to 'development' if not specified.
|
|
312
|
+
*/
|
|
313
|
+
NODE_ENV: import_zod2.z.enum(["development", "production", "test"]).default("development"),
|
|
314
|
+
/**
|
|
315
|
+
* Log level for the scenario package.
|
|
316
|
+
* Defaults to 'info' if not specified.
|
|
317
|
+
*/
|
|
318
|
+
SCENARIO_LOG_LEVEL: import_zod2.z.nativeEnum(LogLevel).optional(),
|
|
319
|
+
/**
|
|
320
|
+
* Scenario batch run ID.
|
|
321
|
+
* If not provided, a random ID will be generated.
|
|
322
|
+
*/
|
|
323
|
+
SCENARIO_BATCH_RUN_ID: import_zod2.z.string().optional()
|
|
324
|
+
});
|
|
325
|
+
var env = envSchema.parse(process.env);
|
|
326
|
+
|
|
276
327
|
// src/config/index.ts
|
|
277
328
|
var logger = new Logger("scenario.config");
|
|
278
329
|
var configLoaded = false;
|
|
@@ -352,24 +403,24 @@ ${criteriaList}
|
|
|
352
403
|
function buildContinueTestTool() {
|
|
353
404
|
return (0, import_ai.tool)({
|
|
354
405
|
description: "Continue the test with the next step",
|
|
355
|
-
parameters:
|
|
406
|
+
parameters: import_zod3.z.object({})
|
|
356
407
|
});
|
|
357
408
|
}
|
|
358
409
|
function buildFinishTestTool(criteria) {
|
|
359
410
|
const criteriaNames = criteria.map(criterionToParamName);
|
|
360
411
|
return (0, import_ai.tool)({
|
|
361
412
|
description: "Complete the test with a final verdict",
|
|
362
|
-
parameters:
|
|
363
|
-
criteria:
|
|
413
|
+
parameters: import_zod3.z.object({
|
|
414
|
+
criteria: import_zod3.z.object(
|
|
364
415
|
Object.fromEntries(
|
|
365
416
|
criteriaNames.map((name, idx) => [
|
|
366
417
|
name,
|
|
367
|
-
|
|
418
|
+
import_zod3.z.enum(["true", "false", "inconclusive"]).describe(criteria[idx])
|
|
368
419
|
])
|
|
369
420
|
)
|
|
370
421
|
).strict().describe("Strict verdict for each criterion"),
|
|
371
|
-
reasoning:
|
|
372
|
-
verdict:
|
|
422
|
+
reasoning: import_zod3.z.string().describe("Explanation of what the final verdict should be"),
|
|
423
|
+
verdict: import_zod3.z.enum(["success", "failure", "inconclusive"]).describe("The final verdict of the test")
|
|
373
424
|
})
|
|
374
425
|
});
|
|
375
426
|
}
|
|
@@ -522,7 +573,6 @@ var import_rxjs = require("rxjs");
|
|
|
522
573
|
|
|
523
574
|
// src/utils/ids.ts
|
|
524
575
|
var import_xksuid = require("xksuid");
|
|
525
|
-
var batchRunId = null;
|
|
526
576
|
function generateThreadId() {
|
|
527
577
|
return `thread_${(0, import_xksuid.generate)()}`;
|
|
528
578
|
}
|
|
@@ -533,10 +583,10 @@ function generateScenarioId() {
|
|
|
533
583
|
return `scenario_${(0, import_xksuid.generate)()}`;
|
|
534
584
|
}
|
|
535
585
|
function getBatchRunId() {
|
|
536
|
-
if (!
|
|
537
|
-
|
|
586
|
+
if (!env.SCENARIO_BATCH_RUN_ID) {
|
|
587
|
+
env.SCENARIO_BATCH_RUN_ID = `scenariobatchrun_${(0, import_xksuid.generate)()}`;
|
|
538
588
|
}
|
|
539
|
-
return
|
|
589
|
+
return env.SCENARIO_BATCH_RUN_ID;
|
|
540
590
|
}
|
|
541
591
|
function generateMessageId() {
|
|
542
592
|
return `scenariomsg_${(0, import_xksuid.generate)()}`;
|
|
@@ -615,7 +665,7 @@ var ScenarioExecutionState = class {
|
|
|
615
665
|
|
|
616
666
|
// src/events/schema.ts
|
|
617
667
|
var import_core = require("@ag-ui/core");
|
|
618
|
-
var
|
|
668
|
+
var import_zod4 = require("zod");
|
|
619
669
|
var Verdict = /* @__PURE__ */ ((Verdict2) => {
|
|
620
670
|
Verdict2["SUCCESS"] = "success";
|
|
621
671
|
Verdict2["FAILURE"] = "failure";
|
|
@@ -631,62 +681,62 @@ var ScenarioRunStatus = /* @__PURE__ */ ((ScenarioRunStatus2) => {
|
|
|
631
681
|
ScenarioRunStatus2["FAILED"] = "FAILED";
|
|
632
682
|
return ScenarioRunStatus2;
|
|
633
683
|
})(ScenarioRunStatus || {});
|
|
634
|
-
var baseEventSchema =
|
|
635
|
-
type:
|
|
636
|
-
timestamp:
|
|
637
|
-
rawEvent:
|
|
684
|
+
var baseEventSchema = import_zod4.z.object({
|
|
685
|
+
type: import_zod4.z.nativeEnum(import_core.EventType),
|
|
686
|
+
timestamp: import_zod4.z.number(),
|
|
687
|
+
rawEvent: import_zod4.z.any().optional()
|
|
638
688
|
});
|
|
639
|
-
var batchRunIdSchema =
|
|
640
|
-
var scenarioRunIdSchema =
|
|
641
|
-
var scenarioIdSchema =
|
|
689
|
+
var batchRunIdSchema = import_zod4.z.string();
|
|
690
|
+
var scenarioRunIdSchema = import_zod4.z.string();
|
|
691
|
+
var scenarioIdSchema = import_zod4.z.string();
|
|
642
692
|
var baseScenarioEventSchema = baseEventSchema.extend({
|
|
643
693
|
batchRunId: batchRunIdSchema,
|
|
644
694
|
scenarioId: scenarioIdSchema,
|
|
645
695
|
scenarioRunId: scenarioRunIdSchema,
|
|
646
|
-
scenarioSetId:
|
|
696
|
+
scenarioSetId: import_zod4.z.string().optional().default("default")
|
|
647
697
|
});
|
|
648
698
|
var scenarioRunStartedSchema = baseScenarioEventSchema.extend({
|
|
649
|
-
type:
|
|
650
|
-
metadata:
|
|
651
|
-
name:
|
|
652
|
-
description:
|
|
699
|
+
type: import_zod4.z.literal("SCENARIO_RUN_STARTED" /* RUN_STARTED */),
|
|
700
|
+
metadata: import_zod4.z.object({
|
|
701
|
+
name: import_zod4.z.string().optional(),
|
|
702
|
+
description: import_zod4.z.string().optional()
|
|
653
703
|
})
|
|
654
704
|
});
|
|
655
|
-
var scenarioResultsSchema =
|
|
656
|
-
verdict:
|
|
657
|
-
reasoning:
|
|
658
|
-
metCriteria:
|
|
659
|
-
unmetCriteria:
|
|
660
|
-
error:
|
|
705
|
+
var scenarioResultsSchema = import_zod4.z.object({
|
|
706
|
+
verdict: import_zod4.z.nativeEnum(Verdict),
|
|
707
|
+
reasoning: import_zod4.z.string().optional(),
|
|
708
|
+
metCriteria: import_zod4.z.array(import_zod4.z.string()),
|
|
709
|
+
unmetCriteria: import_zod4.z.array(import_zod4.z.string()),
|
|
710
|
+
error: import_zod4.z.string().optional()
|
|
661
711
|
});
|
|
662
712
|
var scenarioRunFinishedSchema = baseScenarioEventSchema.extend({
|
|
663
|
-
type:
|
|
664
|
-
status:
|
|
713
|
+
type: import_zod4.z.literal("SCENARIO_RUN_FINISHED" /* RUN_FINISHED */),
|
|
714
|
+
status: import_zod4.z.nativeEnum(ScenarioRunStatus),
|
|
665
715
|
results: scenarioResultsSchema.optional().nullable()
|
|
666
716
|
});
|
|
667
717
|
var scenarioMessageSnapshotSchema = import_core.MessagesSnapshotEventSchema.merge(
|
|
668
718
|
baseScenarioEventSchema.extend({
|
|
669
|
-
type:
|
|
719
|
+
type: import_zod4.z.literal("SCENARIO_MESSAGE_SNAPSHOT" /* MESSAGE_SNAPSHOT */)
|
|
670
720
|
})
|
|
671
721
|
);
|
|
672
|
-
var scenarioEventSchema =
|
|
722
|
+
var scenarioEventSchema = import_zod4.z.discriminatedUnion("type", [
|
|
673
723
|
scenarioRunStartedSchema,
|
|
674
724
|
scenarioRunFinishedSchema,
|
|
675
725
|
scenarioMessageSnapshotSchema
|
|
676
726
|
]);
|
|
677
|
-
var successSchema =
|
|
678
|
-
var errorSchema =
|
|
679
|
-
var stateSchema =
|
|
680
|
-
state:
|
|
681
|
-
messages:
|
|
682
|
-
status:
|
|
727
|
+
var successSchema = import_zod4.z.object({ success: import_zod4.z.boolean() });
|
|
728
|
+
var errorSchema = import_zod4.z.object({ error: import_zod4.z.string() });
|
|
729
|
+
var stateSchema = import_zod4.z.object({
|
|
730
|
+
state: import_zod4.z.object({
|
|
731
|
+
messages: import_zod4.z.array(import_zod4.z.any()),
|
|
732
|
+
status: import_zod4.z.string()
|
|
683
733
|
})
|
|
684
734
|
});
|
|
685
|
-
var runsSchema =
|
|
686
|
-
var eventsSchema =
|
|
735
|
+
var runsSchema = import_zod4.z.object({ runs: import_zod4.z.array(import_zod4.z.string()) });
|
|
736
|
+
var eventsSchema = import_zod4.z.object({ events: import_zod4.z.array(scenarioEventSchema) });
|
|
687
737
|
|
|
688
738
|
// src/execution/scenario-execution.ts
|
|
689
|
-
var
|
|
739
|
+
var batchRunId = getBatchRunId();
|
|
690
740
|
var ScenarioExecution = class {
|
|
691
741
|
state;
|
|
692
742
|
eventSubject = new import_rxjs.Subject();
|
|
@@ -1098,7 +1148,7 @@ var ScenarioExecution = class {
|
|
|
1098
1148
|
type: "placeholder",
|
|
1099
1149
|
// This will be replaced by the specific event type
|
|
1100
1150
|
timestamp: Date.now(),
|
|
1101
|
-
batchRunId
|
|
1151
|
+
batchRunId,
|
|
1102
1152
|
scenarioId: this.config.id,
|
|
1103
1153
|
scenarioRunId,
|
|
1104
1154
|
scenarioSetId: this.config.setId
|
|
@@ -1187,45 +1237,111 @@ __export(runner_exports, {
|
|
|
1187
1237
|
// src/events/event-bus.ts
|
|
1188
1238
|
var import_rxjs2 = require("rxjs");
|
|
1189
1239
|
|
|
1240
|
+
// src/events/event-alert-message-logger.ts
|
|
1241
|
+
var EventAlertMessageLogger = class _EventAlertMessageLogger {
|
|
1242
|
+
static shownBatchIds = /* @__PURE__ */ new Set();
|
|
1243
|
+
/**
|
|
1244
|
+
* Shows a fancy greeting message about simulation reporting status.
|
|
1245
|
+
* Only shows once per batch run to avoid spam.
|
|
1246
|
+
*/
|
|
1247
|
+
handleGreeting() {
|
|
1248
|
+
if (this.isGreetingDisabled()) {
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
const batchRunId2 = getBatchRunId();
|
|
1252
|
+
if (_EventAlertMessageLogger.shownBatchIds.has(batchRunId2)) {
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1255
|
+
_EventAlertMessageLogger.shownBatchIds.add(batchRunId2);
|
|
1256
|
+
this.displayGreeting(batchRunId2);
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Shows a fancy message about how to watch the simulation.
|
|
1260
|
+
* Called when a run started event is received with a session ID.
|
|
1261
|
+
*/
|
|
1262
|
+
handleWatchMessage(params) {
|
|
1263
|
+
if (this.isGreetingDisabled()) {
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
this.displayWatchMessage(params);
|
|
1267
|
+
}
|
|
1268
|
+
isGreetingDisabled() {
|
|
1269
|
+
return env.SCENARIO_DISABLE_SIMULATION_REPORT_INFO === true;
|
|
1270
|
+
}
|
|
1271
|
+
displayGreeting(batchRunId2) {
|
|
1272
|
+
const separator = "\u2500".repeat(60);
|
|
1273
|
+
if (!env.LANGWATCH_API_KEY) {
|
|
1274
|
+
console.log(`
|
|
1275
|
+
${separator}`);
|
|
1276
|
+
console.log("\u{1F680} LangWatch Simulation Reporting");
|
|
1277
|
+
console.log(`${separator}`);
|
|
1278
|
+
console.log("\u27A1\uFE0F API key not configured");
|
|
1279
|
+
console.log(" Simulations will only output final results");
|
|
1280
|
+
console.log("");
|
|
1281
|
+
console.log("\u{1F4A1} To visualize conversations in real time:");
|
|
1282
|
+
console.log(" \u2022 Set LANGWATCH_API_KEY environment variable");
|
|
1283
|
+
console.log(" \u2022 Or configure apiKey in scenario.config.js");
|
|
1284
|
+
console.log("");
|
|
1285
|
+
console.log(`\u{1F4E6} Batch Run ID: ${batchRunId2}`);
|
|
1286
|
+
console.log(`${separator}
|
|
1287
|
+
`);
|
|
1288
|
+
} else {
|
|
1289
|
+
console.log(`
|
|
1290
|
+
${separator}`);
|
|
1291
|
+
console.log("\u{1F680} LangWatch Simulation Reporting");
|
|
1292
|
+
console.log(`${separator}`);
|
|
1293
|
+
console.log("\u2705 Simulation reporting enabled");
|
|
1294
|
+
console.log(` Endpoint: ${env.LANGWATCH_ENDPOINT}`);
|
|
1295
|
+
console.log(
|
|
1296
|
+
` API Key: ${env.LANGWATCH_API_KEY.length > 0 ? "Configured" : "Not configured"}`
|
|
1297
|
+
);
|
|
1298
|
+
console.log("");
|
|
1299
|
+
console.log(`\u{1F4E6} Batch Run ID: ${batchRunId2}`);
|
|
1300
|
+
console.log(`${separator}
|
|
1301
|
+
`);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
displayWatchMessage(params) {
|
|
1305
|
+
const separator = "\u2500".repeat(60);
|
|
1306
|
+
const setUrl = params.setUrl;
|
|
1307
|
+
const batchUrl = `${setUrl}/${getBatchRunId()}`;
|
|
1308
|
+
console.log(`
|
|
1309
|
+
${separator}`);
|
|
1310
|
+
console.log("\u{1F440} Watch Your Simulation Live");
|
|
1311
|
+
console.log(`${separator}`);
|
|
1312
|
+
console.log("\u{1F310} Open in your browser:");
|
|
1313
|
+
console.log(` Scenario Set: ${setUrl}`);
|
|
1314
|
+
console.log(` Batch Run: ${batchUrl}`);
|
|
1315
|
+
console.log("");
|
|
1316
|
+
console.log(`${separator}
|
|
1317
|
+
`);
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
|
|
1190
1321
|
// src/events/event-reporter.ts
|
|
1191
1322
|
var EventReporter = class {
|
|
1192
|
-
eventsEndpoint;
|
|
1193
1323
|
apiKey;
|
|
1324
|
+
eventsEndpoint;
|
|
1325
|
+
eventAlertMessageLogger;
|
|
1194
1326
|
logger = new Logger("scenario.events.EventReporter");
|
|
1195
1327
|
constructor(config2) {
|
|
1196
|
-
this.eventsEndpoint = new URL("/api/scenario-events", config2.endpoint);
|
|
1197
1328
|
this.apiKey = config2.apiKey ?? "";
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
"\u27A1\uFE0F LangWatch API key not configured, simulations will only output the final result"
|
|
1202
|
-
);
|
|
1203
|
-
console.log(
|
|
1204
|
-
"To visualize the conversations in real time, configure your LangWatch API key (via LANGWATCH_API_KEY, or scenario.config.js)"
|
|
1205
|
-
);
|
|
1206
|
-
} else {
|
|
1207
|
-
console.log(`simulation reporting is enabled, endpoint:(${this.eventsEndpoint}) api_key_configured:(${this.apiKey.length > 0 ? "true" : "false"})`);
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1329
|
+
this.eventsEndpoint = new URL("/api/scenario-events", config2.endpoint);
|
|
1330
|
+
this.eventAlertMessageLogger = new EventAlertMessageLogger();
|
|
1331
|
+
this.eventAlertMessageLogger.handleGreeting();
|
|
1210
1332
|
}
|
|
1211
1333
|
/**
|
|
1212
1334
|
* Posts an event to the configured endpoint.
|
|
1213
1335
|
* Logs success/failure but doesn't throw - event posting shouldn't break scenario execution.
|
|
1214
1336
|
*/
|
|
1215
1337
|
async postEvent(event) {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
if (!this.eventsEndpoint) {
|
|
1220
|
-
this.logger.warn(
|
|
1221
|
-
"No LANGWATCH_ENDPOINT configured, skipping event posting"
|
|
1222
|
-
);
|
|
1223
|
-
return;
|
|
1224
|
-
}
|
|
1338
|
+
const result = {};
|
|
1339
|
+
this.logger.debug(`[${event.type}] Posting event`, { event });
|
|
1340
|
+
const processedEvent = this.processEventForApi(event);
|
|
1225
1341
|
try {
|
|
1226
1342
|
const response = await fetch(this.eventsEndpoint.href, {
|
|
1227
1343
|
method: "POST",
|
|
1228
|
-
body: JSON.stringify(
|
|
1344
|
+
body: JSON.stringify(processedEvent),
|
|
1229
1345
|
headers: {
|
|
1230
1346
|
"Content-Type": "application/json",
|
|
1231
1347
|
"X-Auth-Token": this.apiKey
|
|
@@ -1237,22 +1353,40 @@ var EventReporter = class {
|
|
|
1237
1353
|
if (response.ok) {
|
|
1238
1354
|
const data = await response.json();
|
|
1239
1355
|
this.logger.debug(`[${event.type}] Event POST response:`, data);
|
|
1356
|
+
result.setUrl = data.url;
|
|
1240
1357
|
} else {
|
|
1241
1358
|
const errorText = await response.text();
|
|
1242
1359
|
this.logger.error(`[${event.type}] Event POST failed:`, {
|
|
1243
1360
|
status: response.status,
|
|
1244
1361
|
statusText: response.statusText,
|
|
1245
1362
|
error: errorText,
|
|
1246
|
-
event
|
|
1363
|
+
event: JSON.stringify(processedEvent)
|
|
1247
1364
|
});
|
|
1248
1365
|
}
|
|
1249
1366
|
} catch (error) {
|
|
1250
1367
|
this.logger.error(`[${event.type}] Event POST error:`, {
|
|
1251
1368
|
error,
|
|
1252
|
-
event,
|
|
1253
|
-
endpoint: this.eventsEndpoint
|
|
1369
|
+
event: JSON.stringify(processedEvent),
|
|
1370
|
+
endpoint: this.eventsEndpoint.href
|
|
1254
1371
|
});
|
|
1255
1372
|
}
|
|
1373
|
+
return result;
|
|
1374
|
+
}
|
|
1375
|
+
/**
|
|
1376
|
+
* Processes event data to ensure API compatibility.
|
|
1377
|
+
* Converts message content objects to strings when needed.
|
|
1378
|
+
*/
|
|
1379
|
+
processEventForApi(event) {
|
|
1380
|
+
if (event.type === "SCENARIO_MESSAGE_SNAPSHOT" /* MESSAGE_SNAPSHOT */) {
|
|
1381
|
+
return {
|
|
1382
|
+
...event,
|
|
1383
|
+
messages: event.messages.map((message2) => ({
|
|
1384
|
+
...message2,
|
|
1385
|
+
content: typeof message2.content !== "string" ? JSON.stringify(message2.content) : message2.content
|
|
1386
|
+
}))
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
return event;
|
|
1256
1390
|
}
|
|
1257
1391
|
};
|
|
1258
1392
|
|
|
@@ -1261,11 +1395,13 @@ var EventBus = class _EventBus {
|
|
|
1261
1395
|
static registry = /* @__PURE__ */ new Set();
|
|
1262
1396
|
events$ = new import_rxjs2.Subject();
|
|
1263
1397
|
eventReporter;
|
|
1398
|
+
eventAlertMessageLogger;
|
|
1264
1399
|
processingPromise = null;
|
|
1265
1400
|
logger = new Logger("scenario.events.EventBus");
|
|
1266
1401
|
static globalListeners = [];
|
|
1267
1402
|
constructor(config2) {
|
|
1268
1403
|
this.eventReporter = new EventReporter(config2);
|
|
1404
|
+
this.eventAlertMessageLogger = new EventAlertMessageLogger();
|
|
1269
1405
|
_EventBus.registry.add(this);
|
|
1270
1406
|
for (const listener of _EventBus.globalListeners) {
|
|
1271
1407
|
listener(this);
|
|
@@ -1297,22 +1433,31 @@ var EventBus = class _EventBus {
|
|
|
1297
1433
|
}
|
|
1298
1434
|
this.processingPromise = new Promise((resolve, reject) => {
|
|
1299
1435
|
this.events$.pipe(
|
|
1436
|
+
// Post events and get results
|
|
1300
1437
|
(0, import_rxjs2.concatMap)(async (event) => {
|
|
1301
|
-
this.logger.debug(`[${event.type}] Processing event`, {
|
|
1302
|
-
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
|
|
1438
|
+
this.logger.debug(`[${event.type}] Processing event`, { event });
|
|
1439
|
+
const result = await this.eventReporter.postEvent(event);
|
|
1440
|
+
return { event, result };
|
|
1441
|
+
}),
|
|
1442
|
+
// Handle watch messages reactively
|
|
1443
|
+
(0, import_rxjs2.tap)(({ event, result }) => {
|
|
1444
|
+
if (event.type === "SCENARIO_RUN_STARTED" /* RUN_STARTED */ && result.setUrl) {
|
|
1445
|
+
this.eventAlertMessageLogger.handleWatchMessage({
|
|
1446
|
+
scenarioSetId: event.scenarioSetId,
|
|
1447
|
+
scenarioRunId: event.scenarioRunId,
|
|
1448
|
+
setUrl: result.setUrl
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1306
1451
|
}),
|
|
1452
|
+
// Extract just the event for downstream processing
|
|
1453
|
+
(0, import_rxjs2.map)(({ event }) => event),
|
|
1307
1454
|
(0, import_rxjs2.catchError)((error) => {
|
|
1308
1455
|
this.logger.error("Error in event stream:", error);
|
|
1309
1456
|
return import_rxjs2.EMPTY;
|
|
1310
1457
|
})
|
|
1311
1458
|
).subscribe({
|
|
1312
1459
|
next: (event) => {
|
|
1313
|
-
this.logger.debug(`[${event.type}] Event processed`, {
|
|
1314
|
-
event
|
|
1315
|
-
});
|
|
1460
|
+
this.logger.debug(`[${event.type}] Event processed`, { event });
|
|
1316
1461
|
if (event.type === "SCENARIO_RUN_FINISHED" /* RUN_FINISHED */) {
|
|
1317
1462
|
resolve();
|
|
1318
1463
|
}
|