@langwatch/scenario 0.2.6 → 0.2.11
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 +53 -18
- package/dist/{chunk-MOOKAYIE.mjs → chunk-7HLDX5EL.mjs} +82 -173
- package/dist/chunk-OL4RFXV4.mjs +133 -0
- package/dist/index.d.mts +568 -75
- package/dist/index.d.ts +568 -75
- package/dist/index.js +838 -269
- package/dist/index.mjs +722 -190
- package/dist/integrations/vitest/config.d.mts +42 -0
- package/dist/integrations/vitest/config.d.ts +42 -0
- package/dist/integrations/vitest/config.js +51 -0
- package/dist/integrations/vitest/config.mjs +28 -0
- package/dist/integrations/vitest/reporter.js +183 -8
- package/dist/integrations/vitest/reporter.mjs +55 -8
- package/dist/integrations/vitest/setup-global.d.mts +3 -0
- package/dist/integrations/vitest/setup-global.d.ts +3 -0
- package/dist/integrations/vitest/setup-global.js +30 -0
- package/dist/integrations/vitest/setup-global.mjs +11 -0
- package/dist/integrations/vitest/setup.js +115 -73
- package/dist/integrations/vitest/setup.mjs +7 -3
- package/package.json +11 -2
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ViteUserConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enhances a Vitest configuration with Scenario testing framework setup.
|
|
5
|
+
*
|
|
6
|
+
* This function wraps the provided Vitest configuration and automatically adds
|
|
7
|
+
* the necessary setup files for Scenario testing. It ensures that both local
|
|
8
|
+
* and global setup files are properly configured while preserving any existing
|
|
9
|
+
* setup configuration.
|
|
10
|
+
*
|
|
11
|
+
* The function normalizes setup file configurations to handle different input formats:
|
|
12
|
+
* - `undefined` → empty array
|
|
13
|
+
* - string → array with single item
|
|
14
|
+
* - array → array as-is
|
|
15
|
+
*
|
|
16
|
+
* @param config - The base Vitest configuration to enhance
|
|
17
|
+
* @returns Enhanced Vitest configuration with Scenario setup files prepended
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { defineConfig } from 'vitest/config';
|
|
22
|
+
* import { withScenario } from '@langwatch/scenario/integrations/vitest/config';
|
|
23
|
+
*
|
|
24
|
+
* export default withScenario(defineConfig({
|
|
25
|
+
* test: {
|
|
26
|
+
* setupFiles: ['./my-setup.ts'],
|
|
27
|
+
* globalSetup: ['./my-global-setup.ts']
|
|
28
|
+
* }
|
|
29
|
+
* }));
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Minimal configuration - only Scenario setup files
|
|
35
|
+
* export default withScenario(defineConfig({}));
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @since 1.0.0
|
|
39
|
+
*/
|
|
40
|
+
declare function withScenario(config: ViteUserConfig): ViteUserConfig;
|
|
41
|
+
|
|
42
|
+
export { withScenario };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ViteUserConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enhances a Vitest configuration with Scenario testing framework setup.
|
|
5
|
+
*
|
|
6
|
+
* This function wraps the provided Vitest configuration and automatically adds
|
|
7
|
+
* the necessary setup files for Scenario testing. It ensures that both local
|
|
8
|
+
* and global setup files are properly configured while preserving any existing
|
|
9
|
+
* setup configuration.
|
|
10
|
+
*
|
|
11
|
+
* The function normalizes setup file configurations to handle different input formats:
|
|
12
|
+
* - `undefined` → empty array
|
|
13
|
+
* - string → array with single item
|
|
14
|
+
* - array → array as-is
|
|
15
|
+
*
|
|
16
|
+
* @param config - The base Vitest configuration to enhance
|
|
17
|
+
* @returns Enhanced Vitest configuration with Scenario setup files prepended
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { defineConfig } from 'vitest/config';
|
|
22
|
+
* import { withScenario } from '@langwatch/scenario/integrations/vitest/config';
|
|
23
|
+
*
|
|
24
|
+
* export default withScenario(defineConfig({
|
|
25
|
+
* test: {
|
|
26
|
+
* setupFiles: ['./my-setup.ts'],
|
|
27
|
+
* globalSetup: ['./my-global-setup.ts']
|
|
28
|
+
* }
|
|
29
|
+
* }));
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Minimal configuration - only Scenario setup files
|
|
35
|
+
* export default withScenario(defineConfig({}));
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @since 1.0.0
|
|
39
|
+
*/
|
|
40
|
+
declare function withScenario(config: ViteUserConfig): ViteUserConfig;
|
|
41
|
+
|
|
42
|
+
export { withScenario };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/integrations/vitest/config.ts
|
|
21
|
+
var config_exports = {};
|
|
22
|
+
__export(config_exports, {
|
|
23
|
+
withScenario: () => withScenario
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(config_exports);
|
|
26
|
+
var import_config = require("vitest/config");
|
|
27
|
+
function withScenario(config) {
|
|
28
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
29
|
+
const normalizedSetupFiles = ((_a = config.test) == null ? void 0 : _a.setupFiles) === void 0 ? [] : Array.isArray((_b = config.test) == null ? void 0 : _b.setupFiles) ? (_c = config.test) == null ? void 0 : _c.setupFiles : [(_d = config.test) == null ? void 0 : _d.setupFiles];
|
|
30
|
+
const normalizedGlobalSetup = ((_e = config.test) == null ? void 0 : _e.globalSetup) === void 0 ? [] : Array.isArray((_f = config.test) == null ? void 0 : _f.globalSetup) ? (_g = config.test) == null ? void 0 : _g.globalSetup : [(_h = config.test) == null ? void 0 : _h.globalSetup];
|
|
31
|
+
return (0, import_config.defineConfig)({
|
|
32
|
+
...config,
|
|
33
|
+
test: {
|
|
34
|
+
...config.test,
|
|
35
|
+
// Prepend Scenario setup files to ensure they run before user-defined setup
|
|
36
|
+
setupFiles: [
|
|
37
|
+
"@langwatch/scenario/integrations/vitest/setup",
|
|
38
|
+
...normalizedSetupFiles
|
|
39
|
+
],
|
|
40
|
+
// Prepend Scenario global setup files to ensure they run before user-defined global setup
|
|
41
|
+
globalSetup: [
|
|
42
|
+
"@langwatch/scenario/integrations/vitest/setup-global",
|
|
43
|
+
...normalizedGlobalSetup
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
49
|
+
0 && (module.exports = {
|
|
50
|
+
withScenario
|
|
51
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import "../../chunk-7P6ASYW6.mjs";
|
|
2
|
+
|
|
3
|
+
// src/integrations/vitest/config.ts
|
|
4
|
+
import { defineConfig } from "vitest/config";
|
|
5
|
+
function withScenario(config) {
|
|
6
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7
|
+
const normalizedSetupFiles = ((_a = config.test) == null ? void 0 : _a.setupFiles) === void 0 ? [] : Array.isArray((_b = config.test) == null ? void 0 : _b.setupFiles) ? (_c = config.test) == null ? void 0 : _c.setupFiles : [(_d = config.test) == null ? void 0 : _d.setupFiles];
|
|
8
|
+
const normalizedGlobalSetup = ((_e = config.test) == null ? void 0 : _e.globalSetup) === void 0 ? [] : Array.isArray((_f = config.test) == null ? void 0 : _f.globalSetup) ? (_g = config.test) == null ? void 0 : _g.globalSetup : [(_h = config.test) == null ? void 0 : _h.globalSetup];
|
|
9
|
+
return defineConfig({
|
|
10
|
+
...config,
|
|
11
|
+
test: {
|
|
12
|
+
...config.test,
|
|
13
|
+
// Prepend Scenario setup files to ensure they run before user-defined setup
|
|
14
|
+
setupFiles: [
|
|
15
|
+
"@langwatch/scenario/integrations/vitest/setup",
|
|
16
|
+
...normalizedSetupFiles
|
|
17
|
+
],
|
|
18
|
+
// Prepend Scenario global setup files to ensure they run before user-defined global setup
|
|
19
|
+
globalSetup: [
|
|
20
|
+
"@langwatch/scenario/integrations/vitest/setup-global",
|
|
21
|
+
...normalizedGlobalSetup
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
withScenario
|
|
28
|
+
};
|
|
@@ -30,12 +30,144 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/integrations/vitest/reporter.ts
|
|
31
31
|
var reporter_exports = {};
|
|
32
32
|
__export(reporter_exports, {
|
|
33
|
-
default: () =>
|
|
33
|
+
default: () => reporter_default
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(reporter_exports);
|
|
36
36
|
var import_fs = __toESM(require("fs"));
|
|
37
37
|
var import_path = __toESM(require("path"));
|
|
38
38
|
var import_chalk = __toESM(require("chalk"));
|
|
39
|
+
|
|
40
|
+
// src/config/env.ts
|
|
41
|
+
var import_zod = require("zod");
|
|
42
|
+
|
|
43
|
+
// src/config/log-levels.ts
|
|
44
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
45
|
+
LogLevel2["ERROR"] = "ERROR";
|
|
46
|
+
LogLevel2["WARN"] = "WARN";
|
|
47
|
+
LogLevel2["INFO"] = "INFO";
|
|
48
|
+
LogLevel2["DEBUG"] = "DEBUG";
|
|
49
|
+
return LogLevel2;
|
|
50
|
+
})(LogLevel || {});
|
|
51
|
+
var LOG_LEVELS = Object.values(LogLevel);
|
|
52
|
+
|
|
53
|
+
// src/config/env.ts
|
|
54
|
+
var envSchema = import_zod.z.object({
|
|
55
|
+
/**
|
|
56
|
+
* LangWatch API key for event reporting.
|
|
57
|
+
* If not provided, events will not be sent to LangWatch.
|
|
58
|
+
*/
|
|
59
|
+
LANGWATCH_API_KEY: import_zod.z.string().optional(),
|
|
60
|
+
/**
|
|
61
|
+
* LangWatch endpoint URL for event reporting.
|
|
62
|
+
* Defaults to the production LangWatch endpoint.
|
|
63
|
+
*/
|
|
64
|
+
LANGWATCH_ENDPOINT: import_zod.z.string().url().optional().default("https://app.langwatch.ai"),
|
|
65
|
+
/**
|
|
66
|
+
* Disables simulation report info messages when set to any truthy value.
|
|
67
|
+
* Useful for CI/CD environments or when you want cleaner output.
|
|
68
|
+
*/
|
|
69
|
+
SCENARIO_DISABLE_SIMULATION_REPORT_INFO: import_zod.z.string().optional().transform((val) => Boolean(val)),
|
|
70
|
+
/**
|
|
71
|
+
* Node environment - affects logging and behavior.
|
|
72
|
+
* Defaults to 'development' if not specified.
|
|
73
|
+
*/
|
|
74
|
+
NODE_ENV: import_zod.z.enum(["development", "production", "test"]).default("development"),
|
|
75
|
+
/**
|
|
76
|
+
* Case-insensitive log level for the scenario package.
|
|
77
|
+
* Defaults to 'info' if not specified.
|
|
78
|
+
*/
|
|
79
|
+
LOG_LEVEL: import_zod.z.string().toUpperCase().pipe(import_zod.z.nativeEnum(LogLevel)).optional().default("INFO" /* INFO */),
|
|
80
|
+
/**
|
|
81
|
+
* Scenario batch run ID.
|
|
82
|
+
* If not provided, a random ID will be generated.
|
|
83
|
+
*/
|
|
84
|
+
SCENARIO_BATCH_RUN_ID: import_zod.z.string().optional()
|
|
85
|
+
});
|
|
86
|
+
function getEnv() {
|
|
87
|
+
return envSchema.parse(process.env);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/utils/logger.ts
|
|
91
|
+
var Logger = class _Logger {
|
|
92
|
+
constructor(context) {
|
|
93
|
+
this.context = context;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Creates a logger with context (e.g., class name)
|
|
97
|
+
*/
|
|
98
|
+
static create(context) {
|
|
99
|
+
return new _Logger(context);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns the current log level from environment.
|
|
103
|
+
* Uses a getter for clarity and idiomatic usage.
|
|
104
|
+
*/
|
|
105
|
+
get LOG_LEVEL() {
|
|
106
|
+
return getEnv().LOG_LEVEL;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Returns the index of the given log level in the LOG_LEVELS array.
|
|
110
|
+
* @param level - The log level to get the index for.
|
|
111
|
+
* @returns The index of the log level in the LOG_LEVELS array.
|
|
112
|
+
*/
|
|
113
|
+
getLogLevelIndexFor(level) {
|
|
114
|
+
return LOG_LEVELS.indexOf(level);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Checks if logging should occur based on LOG_LEVEL env var
|
|
118
|
+
*/
|
|
119
|
+
shouldLog(level) {
|
|
120
|
+
const currentLevelIndex = this.getLogLevelIndexFor(this.LOG_LEVEL);
|
|
121
|
+
const requestedLevelIndex = this.getLogLevelIndexFor(level);
|
|
122
|
+
return currentLevelIndex >= 0 && requestedLevelIndex <= currentLevelIndex;
|
|
123
|
+
}
|
|
124
|
+
formatMessage(message) {
|
|
125
|
+
return this.context ? `[${this.context}] ${message}` : message;
|
|
126
|
+
}
|
|
127
|
+
error(message, data) {
|
|
128
|
+
if (this.shouldLog("ERROR" /* ERROR */)) {
|
|
129
|
+
const formattedMessage = this.formatMessage(message);
|
|
130
|
+
if (data) {
|
|
131
|
+
console.error(formattedMessage, data);
|
|
132
|
+
} else {
|
|
133
|
+
console.error(formattedMessage);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
warn(message, data) {
|
|
138
|
+
if (this.shouldLog("WARN" /* WARN */)) {
|
|
139
|
+
const formattedMessage = this.formatMessage(message);
|
|
140
|
+
if (data) {
|
|
141
|
+
console.warn(formattedMessage, data);
|
|
142
|
+
} else {
|
|
143
|
+
console.warn(formattedMessage);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
info(message, data) {
|
|
148
|
+
if (this.shouldLog("INFO" /* INFO */)) {
|
|
149
|
+
const formattedMessage = this.formatMessage(message);
|
|
150
|
+
if (data) {
|
|
151
|
+
console.info(formattedMessage, data);
|
|
152
|
+
} else {
|
|
153
|
+
console.info(formattedMessage);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
debug(message, data) {
|
|
158
|
+
if (this.shouldLog("DEBUG" /* DEBUG */)) {
|
|
159
|
+
const formattedMessage = this.formatMessage(message);
|
|
160
|
+
if (data) {
|
|
161
|
+
console.log(formattedMessage, data);
|
|
162
|
+
} else {
|
|
163
|
+
console.log(formattedMessage);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/integrations/vitest/reporter.ts
|
|
170
|
+
var logger = Logger.create("integrations:vitest:reporter");
|
|
39
171
|
function getProjectRoot() {
|
|
40
172
|
return process.cwd();
|
|
41
173
|
}
|
|
@@ -54,14 +186,20 @@ function getFullTestName(task) {
|
|
|
54
186
|
}
|
|
55
187
|
return name;
|
|
56
188
|
}
|
|
189
|
+
function indent(str, n = 2) {
|
|
190
|
+
return str.replace(/^/gm, " ".repeat(n));
|
|
191
|
+
}
|
|
57
192
|
var VitestReporter = class {
|
|
58
193
|
results = [];
|
|
59
194
|
async onTestCaseResult(test) {
|
|
60
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
195
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
61
196
|
const fullName = getFullTestName(test);
|
|
62
197
|
const filePath = getLogFilePath(test.id);
|
|
63
198
|
if (!import_fs.default.existsSync(filePath)) {
|
|
64
|
-
|
|
199
|
+
logger.warn(
|
|
200
|
+
`No log file found ${filePath} for test ${fullName}`,
|
|
201
|
+
test.id
|
|
202
|
+
);
|
|
65
203
|
return;
|
|
66
204
|
}
|
|
67
205
|
const lines = import_fs.default.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
@@ -97,19 +235,55 @@ var VitestReporter = class {
|
|
|
97
235
|
console.log(`Description: ${((_g = started.metadata) == null ? void 0 : _g.description) ?? ""}`);
|
|
98
236
|
}
|
|
99
237
|
if (messages.length) {
|
|
100
|
-
console.log("Chat log
|
|
238
|
+
console.log("Chat log:\n");
|
|
101
239
|
let lastMessageCount = 0;
|
|
102
240
|
for (const msg of messages) {
|
|
103
241
|
const allMessages = msg.messages ?? [];
|
|
104
242
|
for (const m of allMessages.slice(lastMessageCount)) {
|
|
105
243
|
const role = m.role;
|
|
244
|
+
if (role.toLowerCase() === "assistant" && "toolCalls" in m && Array.isArray(m.toolCalls) && m.toolCalls.length > 0) {
|
|
245
|
+
for (const toolCall of m.toolCalls) {
|
|
246
|
+
const functionName = toolCall.function.name;
|
|
247
|
+
let parsedJson = "";
|
|
248
|
+
try {
|
|
249
|
+
parsedJson = JSON.stringify(
|
|
250
|
+
JSON.parse(toolCall.function.arguments),
|
|
251
|
+
null,
|
|
252
|
+
2
|
|
253
|
+
);
|
|
254
|
+
} catch {
|
|
255
|
+
parsedJson = toolCall.function.arguments;
|
|
256
|
+
}
|
|
257
|
+
const role2 = import_chalk.default.magenta(`ToolCall(${functionName}):`);
|
|
258
|
+
console.log(`${role2}:
|
|
259
|
+
|
|
260
|
+
${indent(parsedJson)}
|
|
261
|
+
`);
|
|
262
|
+
}
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
106
265
|
let roleLabel = role;
|
|
107
266
|
if (role.toLowerCase() === "user") roleLabel = import_chalk.default.green("User");
|
|
108
267
|
else if (role.toLowerCase() === "agent")
|
|
109
268
|
roleLabel = import_chalk.default.cyan("Agent");
|
|
110
269
|
else if (role.toLowerCase() === "assistant")
|
|
111
|
-
|
|
112
|
-
|
|
270
|
+
if (Array.isArray(m.content) && typeof m.content.at(0) === "object" && ((_h = m.content.at(0)) == null ? void 0 : _h.type) === "tool-call")
|
|
271
|
+
roleLabel = import_chalk.default.cyan("ToolCall");
|
|
272
|
+
else roleLabel = import_chalk.default.cyan("Assistant");
|
|
273
|
+
else if (role.toLowerCase() === "tool") {
|
|
274
|
+
roleLabel = import_chalk.default.magenta("ToolResult");
|
|
275
|
+
let parsedJson = "";
|
|
276
|
+
try {
|
|
277
|
+
parsedJson = JSON.stringify(JSON.parse(m.content), null, 2);
|
|
278
|
+
} catch {
|
|
279
|
+
parsedJson = m.content;
|
|
280
|
+
}
|
|
281
|
+
console.log(`${roleLabel}:
|
|
282
|
+
|
|
283
|
+
${indent(parsedJson)}
|
|
284
|
+
`);
|
|
285
|
+
continue;
|
|
286
|
+
} else roleLabel = import_chalk.default.yellow(role);
|
|
113
287
|
console.log(`${roleLabel}: ${m.content}`);
|
|
114
288
|
}
|
|
115
289
|
lastMessageCount = allMessages.length;
|
|
@@ -122,11 +296,11 @@ var VitestReporter = class {
|
|
|
122
296
|
console.log(`Verdict: ${finished.results.verdict}`);
|
|
123
297
|
if (finished.results.reasoning)
|
|
124
298
|
console.log(`Reasoning: ${finished.results.reasoning}`);
|
|
125
|
-
if ((
|
|
299
|
+
if ((_i = finished.results.metCriteria) == null ? void 0 : _i.length)
|
|
126
300
|
console.log(
|
|
127
301
|
`Met criteria: ${finished.results.metCriteria.join(", ")}`
|
|
128
302
|
);
|
|
129
|
-
if ((
|
|
303
|
+
if ((_j = finished.results.unmetCriteria) == null ? void 0 : _j.length)
|
|
130
304
|
console.log(
|
|
131
305
|
`Unmet criteria: ${finished.results.unmetCriteria.join(", ")}`
|
|
132
306
|
);
|
|
@@ -166,3 +340,4 @@ var VitestReporter = class {
|
|
|
166
340
|
console.log();
|
|
167
341
|
}
|
|
168
342
|
};
|
|
343
|
+
var reporter_default = VitestReporter;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Logger
|
|
3
|
+
} from "../../chunk-OL4RFXV4.mjs";
|
|
1
4
|
import "../../chunk-7P6ASYW6.mjs";
|
|
2
5
|
|
|
3
6
|
// src/integrations/vitest/reporter.ts
|
|
4
7
|
import fs from "fs";
|
|
5
8
|
import path from "path";
|
|
6
9
|
import chalk from "chalk";
|
|
10
|
+
var logger = Logger.create("integrations:vitest:reporter");
|
|
7
11
|
function getProjectRoot() {
|
|
8
12
|
return process.cwd();
|
|
9
13
|
}
|
|
@@ -22,14 +26,20 @@ function getFullTestName(task) {
|
|
|
22
26
|
}
|
|
23
27
|
return name;
|
|
24
28
|
}
|
|
29
|
+
function indent(str, n = 2) {
|
|
30
|
+
return str.replace(/^/gm, " ".repeat(n));
|
|
31
|
+
}
|
|
25
32
|
var VitestReporter = class {
|
|
26
33
|
results = [];
|
|
27
34
|
async onTestCaseResult(test) {
|
|
28
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
35
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
29
36
|
const fullName = getFullTestName(test);
|
|
30
37
|
const filePath = getLogFilePath(test.id);
|
|
31
38
|
if (!fs.existsSync(filePath)) {
|
|
32
|
-
|
|
39
|
+
logger.warn(
|
|
40
|
+
`No log file found ${filePath} for test ${fullName}`,
|
|
41
|
+
test.id
|
|
42
|
+
);
|
|
33
43
|
return;
|
|
34
44
|
}
|
|
35
45
|
const lines = fs.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
@@ -65,19 +75,55 @@ var VitestReporter = class {
|
|
|
65
75
|
console.log(`Description: ${((_g = started.metadata) == null ? void 0 : _g.description) ?? ""}`);
|
|
66
76
|
}
|
|
67
77
|
if (messages.length) {
|
|
68
|
-
console.log("Chat log
|
|
78
|
+
console.log("Chat log:\n");
|
|
69
79
|
let lastMessageCount = 0;
|
|
70
80
|
for (const msg of messages) {
|
|
71
81
|
const allMessages = msg.messages ?? [];
|
|
72
82
|
for (const m of allMessages.slice(lastMessageCount)) {
|
|
73
83
|
const role = m.role;
|
|
84
|
+
if (role.toLowerCase() === "assistant" && "toolCalls" in m && Array.isArray(m.toolCalls) && m.toolCalls.length > 0) {
|
|
85
|
+
for (const toolCall of m.toolCalls) {
|
|
86
|
+
const functionName = toolCall.function.name;
|
|
87
|
+
let parsedJson = "";
|
|
88
|
+
try {
|
|
89
|
+
parsedJson = JSON.stringify(
|
|
90
|
+
JSON.parse(toolCall.function.arguments),
|
|
91
|
+
null,
|
|
92
|
+
2
|
|
93
|
+
);
|
|
94
|
+
} catch {
|
|
95
|
+
parsedJson = toolCall.function.arguments;
|
|
96
|
+
}
|
|
97
|
+
const role2 = chalk.magenta(`ToolCall(${functionName}):`);
|
|
98
|
+
console.log(`${role2}:
|
|
99
|
+
|
|
100
|
+
${indent(parsedJson)}
|
|
101
|
+
`);
|
|
102
|
+
}
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
74
105
|
let roleLabel = role;
|
|
75
106
|
if (role.toLowerCase() === "user") roleLabel = chalk.green("User");
|
|
76
107
|
else if (role.toLowerCase() === "agent")
|
|
77
108
|
roleLabel = chalk.cyan("Agent");
|
|
78
109
|
else if (role.toLowerCase() === "assistant")
|
|
79
|
-
|
|
80
|
-
|
|
110
|
+
if (Array.isArray(m.content) && typeof m.content.at(0) === "object" && ((_h = m.content.at(0)) == null ? void 0 : _h.type) === "tool-call")
|
|
111
|
+
roleLabel = chalk.cyan("ToolCall");
|
|
112
|
+
else roleLabel = chalk.cyan("Assistant");
|
|
113
|
+
else if (role.toLowerCase() === "tool") {
|
|
114
|
+
roleLabel = chalk.magenta("ToolResult");
|
|
115
|
+
let parsedJson = "";
|
|
116
|
+
try {
|
|
117
|
+
parsedJson = JSON.stringify(JSON.parse(m.content), null, 2);
|
|
118
|
+
} catch {
|
|
119
|
+
parsedJson = m.content;
|
|
120
|
+
}
|
|
121
|
+
console.log(`${roleLabel}:
|
|
122
|
+
|
|
123
|
+
${indent(parsedJson)}
|
|
124
|
+
`);
|
|
125
|
+
continue;
|
|
126
|
+
} else roleLabel = chalk.yellow(role);
|
|
81
127
|
console.log(`${roleLabel}: ${m.content}`);
|
|
82
128
|
}
|
|
83
129
|
lastMessageCount = allMessages.length;
|
|
@@ -90,11 +136,11 @@ var VitestReporter = class {
|
|
|
90
136
|
console.log(`Verdict: ${finished.results.verdict}`);
|
|
91
137
|
if (finished.results.reasoning)
|
|
92
138
|
console.log(`Reasoning: ${finished.results.reasoning}`);
|
|
93
|
-
if ((
|
|
139
|
+
if ((_i = finished.results.metCriteria) == null ? void 0 : _i.length)
|
|
94
140
|
console.log(
|
|
95
141
|
`Met criteria: ${finished.results.metCriteria.join(", ")}`
|
|
96
142
|
);
|
|
97
|
-
if ((
|
|
143
|
+
if ((_j = finished.results.unmetCriteria) == null ? void 0 : _j.length)
|
|
98
144
|
console.log(
|
|
99
145
|
`Unmet criteria: ${finished.results.unmetCriteria.join(", ")}`
|
|
100
146
|
);
|
|
@@ -134,6 +180,7 @@ var VitestReporter = class {
|
|
|
134
180
|
console.log();
|
|
135
181
|
}
|
|
136
182
|
};
|
|
183
|
+
var reporter_default = VitestReporter;
|
|
137
184
|
export {
|
|
138
|
-
|
|
185
|
+
reporter_default as default
|
|
139
186
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/integrations/vitest/setup-global.ts
|
|
21
|
+
var setup_global_exports = {};
|
|
22
|
+
__export(setup_global_exports, {
|
|
23
|
+
default: () => setup
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(setup_global_exports);
|
|
26
|
+
var import_xksuid = require("xksuid");
|
|
27
|
+
function setup() {
|
|
28
|
+
const scenarioBatchRunId = `scenariobatchrun_${(0, import_xksuid.generate)()}`;
|
|
29
|
+
process.env.SCENARIO_BATCH_RUN_ID = scenarioBatchRunId;
|
|
30
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "../../chunk-7P6ASYW6.mjs";
|
|
2
|
+
|
|
3
|
+
// src/integrations/vitest/setup-global.ts
|
|
4
|
+
import { generate } from "xksuid";
|
|
5
|
+
function setup() {
|
|
6
|
+
const scenarioBatchRunId = `scenariobatchrun_${generate()}`;
|
|
7
|
+
process.env.SCENARIO_BATCH_RUN_ID = scenarioBatchRunId;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
setup as default
|
|
11
|
+
};
|