braintrust 3.18.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +0 -10
  2. package/dev/dist/index.js +3626 -1989
  3. package/dev/dist/index.mjs +4576 -2939
  4. package/dist/apply-auto-instrumentation.js +342 -175
  5. package/dist/apply-auto-instrumentation.mjs +170 -3
  6. package/dist/auto-instrumentations/bundler/esbuild.cjs +209 -3
  7. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  8. package/dist/auto-instrumentations/bundler/next.cjs +209 -3
  9. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  10. package/dist/auto-instrumentations/bundler/rollup.cjs +209 -3
  11. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  12. package/dist/auto-instrumentations/bundler/vite.cjs +209 -3
  13. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  14. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +209 -3
  15. package/dist/auto-instrumentations/bundler/webpack.cjs +209 -3
  16. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  17. package/dist/auto-instrumentations/{chunk-MYCHHXOE.mjs → chunk-K74TZGGM.mjs} +1 -1
  18. package/dist/auto-instrumentations/{chunk-GNUEZ2PE.mjs → chunk-S4374IP6.mjs} +84 -4
  19. package/dist/auto-instrumentations/{chunk-ZYKZEMRT.mjs → chunk-W4E36GIW.mjs} +128 -0
  20. package/dist/auto-instrumentations/hook.mjs +209 -3
  21. package/dist/auto-instrumentations/index.cjs +129 -0
  22. package/dist/auto-instrumentations/index.d.mts +3 -1
  23. package/dist/auto-instrumentations/index.d.ts +3 -1
  24. package/dist/auto-instrumentations/index.mjs +3 -1
  25. package/dist/browser.d.mts +79 -8
  26. package/dist/browser.d.ts +79 -8
  27. package/dist/browser.js +2054 -161
  28. package/dist/browser.mjs +4847 -2954
  29. package/dist/chunk-37RLJF2U.js +29262 -0
  30. package/dist/{chunk-73IYIIOL.js → chunk-LPC4W2WX.js} +54 -4
  31. package/dist/chunk-VEQ2PCMC.mjs +29262 -0
  32. package/dist/{chunk-BYFADLEZ.mjs → chunk-Y7W7WP6H.mjs} +53 -3
  33. package/dist/cli.js +3492 -1849
  34. package/dist/edge-light.d.mts +1 -1
  35. package/dist/edge-light.d.ts +1 -1
  36. package/dist/edge-light.js +2054 -161
  37. package/dist/edge-light.mjs +4847 -2954
  38. package/dist/index.d.mts +79 -8
  39. package/dist/index.d.ts +79 -8
  40. package/dist/index.js +835 -27963
  41. package/dist/index.mjs +578 -27706
  42. package/dist/instrumentation/index.d.mts +66 -6
  43. package/dist/instrumentation/index.d.ts +66 -6
  44. package/dist/instrumentation/index.js +4573 -2937
  45. package/dist/instrumentation/index.mjs +4573 -2937
  46. package/dist/vitest-evals-reporter.d.mts +22 -0
  47. package/dist/vitest-evals-reporter.d.ts +22 -0
  48. package/dist/vitest-evals-reporter.js +401 -0
  49. package/dist/vitest-evals-reporter.mjs +401 -0
  50. package/dist/workerd.d.mts +1 -1
  51. package/dist/workerd.d.ts +1 -1
  52. package/dist/workerd.js +2054 -161
  53. package/dist/workerd.mjs +4847 -2954
  54. package/package.json +7 -1
@@ -0,0 +1,22 @@
1
+ import { Reporter, Vitest, TestModule } from 'vitest/node';
2
+
3
+ interface BraintrustVitestEvalsReporterOptions {
4
+ projectName?: string;
5
+ projectId?: string;
6
+ experimentName?: string;
7
+ displaySummary?: boolean;
8
+ metadata?: Record<string, unknown>;
9
+ tags?: string[];
10
+ baseExperiment?: string;
11
+ baseExperimentId?: string;
12
+ }
13
+ declare class BraintrustVitestEvalsReporter implements Reporter {
14
+ private readonly options;
15
+ private experiment?;
16
+ constructor(options?: BraintrustVitestEvalsReporterOptions);
17
+ onInit(_vitest: Vitest): void;
18
+ onTestRunEnd(testModules: ReadonlyArray<TestModule>): Promise<void>;
19
+ private getOrCreateExperiment;
20
+ }
21
+
22
+ export { BraintrustVitestEvalsReporter as default };
@@ -0,0 +1,22 @@
1
+ import { Reporter, Vitest, TestModule } from 'vitest/node';
2
+
3
+ interface BraintrustVitestEvalsReporterOptions {
4
+ projectName?: string;
5
+ projectId?: string;
6
+ experimentName?: string;
7
+ displaySummary?: boolean;
8
+ metadata?: Record<string, unknown>;
9
+ tags?: string[];
10
+ baseExperiment?: string;
11
+ baseExperimentId?: string;
12
+ }
13
+ declare class BraintrustVitestEvalsReporter implements Reporter {
14
+ private readonly options;
15
+ private experiment?;
16
+ constructor(options?: BraintrustVitestEvalsReporterOptions);
17
+ onInit(_vitest: Vitest): void;
18
+ onTestRunEnd(testModules: ReadonlyArray<TestModule>): Promise<void>;
19
+ private getOrCreateExperiment;
20
+ }
21
+
22
+ export { BraintrustVitestEvalsReporter as default };
@@ -0,0 +1,401 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+
6
+
7
+ var _chunk37RLJF2Ujs = require('./chunk-37RLJF2U.js');
8
+ require('./chunk-LPC4W2WX.js');
9
+
10
+ // src/wrappers/vitest-evals/reporter.ts
11
+ _chunk37RLJF2Ujs.configureNode.call(void 0, );
12
+ var RESERVED_NORMALIZED_SPAN_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
13
+ "name",
14
+ "type",
15
+ "vitest_evals_kind",
16
+ "trace_id",
17
+ "external_span_id",
18
+ "external_parent_id",
19
+ "status"
20
+ ]);
21
+ var BraintrustVitestEvalsReporter = class {
22
+ constructor(options = {}) {
23
+ this.options = options;
24
+ }
25
+
26
+ onInit(_vitest) {
27
+ }
28
+ async onTestRunEnd(testModules) {
29
+ const evalTests = [];
30
+ for (const testModule of testModules) {
31
+ for (const test of testModule.children.allTests()) {
32
+ const candidate = { test, meta: readEvalTaskMeta(test.meta()) };
33
+ if (isRunnableEvalTest(candidate)) {
34
+ evalTests.push(candidate);
35
+ }
36
+ }
37
+ }
38
+ if (evalTests.length === 0) {
39
+ return;
40
+ }
41
+ const experiment = this.getOrCreateExperiment();
42
+ for (const { test, meta } of evalTests) {
43
+ logEvalTest(experiment, test, meta);
44
+ }
45
+ await _chunk37RLJF2Ujs.summarizeAndFlush.call(void 0, experiment, {
46
+ displaySummary: this.options.displaySummary
47
+ });
48
+ this.experiment = void 0;
49
+ }
50
+ getOrCreateExperiment() {
51
+ if (this.experiment) {
52
+ return this.experiment;
53
+ }
54
+ const { projectId, projectName } = this.options;
55
+ if (!projectId && !projectName) {
56
+ throw new Error(
57
+ "Braintrust vitest-evals reporter requires projectName or projectId when eval cases are reported."
58
+ );
59
+ }
60
+ const experimentName = _nullishCoalesce(this.options.experimentName, () => ( `vitest-evals-${(/* @__PURE__ */ new Date()).toISOString()}`));
61
+ this.experiment = _chunk37RLJF2Ujs.initExperiment.call(void 0, {
62
+ ...projectId ? { projectId } : { project: projectName },
63
+ experiment: experimentName,
64
+ metadata: this.options.metadata,
65
+ tags: this.options.tags,
66
+ baseExperiment: this.options.baseExperiment,
67
+ baseExperimentId: this.options.baseExperimentId
68
+ });
69
+ return this.experiment;
70
+ }
71
+ };
72
+ function isRunnableEvalTest(candidate) {
73
+ if (!candidate.meta) return false;
74
+ const state = candidate.test.result().state;
75
+ return state !== "skipped" && state !== "pending";
76
+ }
77
+ function logEvalTest(experiment, test, meta) {
78
+ const result = test.result();
79
+ const diagnostic = test.diagnostic();
80
+ const run = _optionalChain([meta, 'access', _ => _.harness, 'optionalAccess', _2 => _2.run]);
81
+ const output = _nullishCoalesce(_optionalChain([meta, 'access', _3 => _3.eval, 'optionalAccess', _4 => _4.output]), () => ( _optionalChain([run, 'optionalAccess', _5 => _5.output])));
82
+ const scores = buildScores(result.state, meta.eval);
83
+ const metrics = buildMetrics(_optionalChain([diagnostic, 'optionalAccess', _6 => _6.duration]), run);
84
+ const metadata = buildMetadata(test, meta, run);
85
+ const rootSpan = experiment.startSpan({
86
+ name: test.fullName || test.name,
87
+ spanAttributes: {
88
+ type: "eval" /* EVAL */,
89
+ framework: "vitest",
90
+ reporter: "vitest-evals"
91
+ },
92
+ startTime: startTimeSeconds(diagnostic),
93
+ event: {
94
+ input: {
95
+ test: test.fullName || test.name,
96
+ input: firstUserMessageContent(run)
97
+ },
98
+ ...output !== void 0 ? { output } : {},
99
+ scores,
100
+ metrics,
101
+ metadata,
102
+ ...test.tags.length > 0 ? { tags: test.tags } : {}
103
+ }
104
+ });
105
+ if (result.state === "failed") {
106
+ for (const error of _nullishCoalesce(result.errors, () => ( []))) {
107
+ logReporterError(rootSpan, error);
108
+ }
109
+ }
110
+ if (_optionalChain([run, 'optionalAccess', _7 => _7.traces, 'optionalAccess', _8 => _8.length])) {
111
+ logNormalizedTraces(rootSpan, run.traces);
112
+ } else {
113
+ logToolCallSpans(rootSpan, toolCallsFromMeta(meta.eval, run));
114
+ }
115
+ rootSpan.end({
116
+ endTime: startTimeSeconds(diagnostic) !== void 0 && _optionalChain([diagnostic, 'optionalAccess', _9 => _9.duration]) !== void 0 ? startTimeSeconds(diagnostic) + diagnostic.duration / 1e3 : void 0
117
+ });
118
+ }
119
+ function buildScores(state, evalMeta) {
120
+ const scores = {
121
+ pass: state === "passed" ? 1 : 0
122
+ };
123
+ if (typeof _optionalChain([evalMeta, 'optionalAccess', _10 => _10.avgScore]) === "number" || _optionalChain([evalMeta, 'optionalAccess', _11 => _11.avgScore]) === null) {
124
+ scores.avg_score = evalMeta.avgScore;
125
+ }
126
+ for (const score of _nullishCoalesce(_optionalChain([evalMeta, 'optionalAccess', _12 => _12.scores]), () => ( []))) {
127
+ if (!score.name) continue;
128
+ if (typeof score.score === "number" || score.score === null) {
129
+ scores[score.name] = score.score;
130
+ }
131
+ }
132
+ return scores;
133
+ }
134
+ function buildMetrics(durationMs, run) {
135
+ const usage = _optionalChain([run, 'optionalAccess', _13 => _13.usage]);
136
+ const metrics = {};
137
+ if (durationMs !== void 0) {
138
+ metrics.duration_ms = durationMs;
139
+ }
140
+ if (typeof _optionalChain([usage, 'optionalAccess', _14 => _14.inputTokens]) === "number") {
141
+ metrics.input_tokens = usage.inputTokens;
142
+ }
143
+ if (typeof _optionalChain([usage, 'optionalAccess', _15 => _15.outputTokens]) === "number") {
144
+ metrics.output_tokens = usage.outputTokens;
145
+ }
146
+ if (typeof _optionalChain([usage, 'optionalAccess', _16 => _16.reasoningTokens]) === "number") {
147
+ metrics.reasoning_tokens = usage.reasoningTokens;
148
+ }
149
+ if (typeof _optionalChain([usage, 'optionalAccess', _17 => _17.totalTokens]) === "number") {
150
+ metrics.total_tokens = usage.totalTokens;
151
+ }
152
+ if (typeof _optionalChain([usage, 'optionalAccess', _18 => _18.toolCalls]) === "number") {
153
+ metrics.tool_calls = usage.toolCalls;
154
+ }
155
+ if (typeof _optionalChain([usage, 'optionalAccess', _19 => _19.retries]) === "number") {
156
+ metrics.retries = usage.retries;
157
+ }
158
+ return metrics;
159
+ }
160
+ function buildMetadata(test, meta, run) {
161
+ const result = test.result();
162
+ const metadata = {
163
+ file: _optionalChain([test, 'access', _20 => _20.module, 'optionalAccess', _21 => _21.moduleId]),
164
+ relativeFile: _optionalChain([test, 'access', _22 => _22.module, 'optionalAccess', _23 => _23.relativeModuleId]),
165
+ fullName: test.fullName,
166
+ testId: test.id,
167
+ location: test.location,
168
+ status: result.state,
169
+ failureMessages: (_nullishCoalesce(result.errors, () => ( []))).map(formatErrorMessage),
170
+ harnessName: _optionalChain([meta, 'access', _24 => _24.harness, 'optionalAccess', _25 => _25.name]),
171
+ thresholdFailed: _optionalChain([meta, 'access', _26 => _26.eval, 'optionalAccess', _27 => _27.thresholdFailed]),
172
+ session: _optionalChain([run, 'optionalAccess', _28 => _28.session]),
173
+ artifacts: _optionalChain([run, 'optionalAccess', _29 => _29.artifacts]),
174
+ timings: _optionalChain([run, 'optionalAccess', _30 => _30.timings]),
175
+ errors: _optionalChain([run, 'optionalAccess', _31 => _31.errors]),
176
+ scoreMetadata: Object.fromEntries(
177
+ (_nullishCoalesce(_optionalChain([meta, 'access', _32 => _32.eval, 'optionalAccess', _33 => _33.scores]), () => ( []))).filter((score) => score.name && score.metadata).map((score) => [score.name, score.metadata])
178
+ )
179
+ };
180
+ return Object.fromEntries(
181
+ Object.entries(metadata).filter(([, value]) => value !== void 0)
182
+ );
183
+ }
184
+ function logNormalizedTraces(rootSpan, traces) {
185
+ for (const trace of traces) {
186
+ const spans = _nullishCoalesce(trace.spans, () => ( []));
187
+ const spanMap = /* @__PURE__ */ new Map();
188
+ const pending = [...spans];
189
+ while (pending.length > 0) {
190
+ const before = pending.length;
191
+ for (let index = pending.length - 1; index >= 0; index--) {
192
+ const normalized = pending[index];
193
+ const parent = normalized.parentId === void 0 ? rootSpan : spanMap.get(normalized.parentId);
194
+ if (!parent) continue;
195
+ const span = logNormalizedSpan(parent, normalized, trace);
196
+ if (normalized.id) {
197
+ spanMap.set(normalized.id, span);
198
+ }
199
+ pending.splice(index, 1);
200
+ }
201
+ if (pending.length === before) {
202
+ for (const normalized of pending.splice(0)) {
203
+ const span = logNormalizedSpan(rootSpan, normalized, trace);
204
+ if (normalized.id) {
205
+ spanMap.set(normalized.id, span);
206
+ }
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+ function logNormalizedSpan(parent, normalized, trace) {
213
+ const durationMs = typeof normalized.durationMs === "number" && Number.isFinite(normalized.durationMs) ? normalized.durationMs : void 0;
214
+ const startTime = epochSeconds(normalized.startedAt);
215
+ const endTime = _nullishCoalesce(epochSeconds(normalized.finishedAt), () => ( (startTime !== void 0 && durationMs !== void 0 ? startTime + durationMs / 1e3 : void 0)));
216
+ const span = parent.startSpan({
217
+ name: _nullishCoalesce(_nullishCoalesce(normalized.name, () => ( normalized.kind)), () => ( "harness span")),
218
+ spanAttributes: {
219
+ ...filteredNormalizedSpanAttributes(normalized.attributes),
220
+ type: spanTypeForNormalizedKind(normalized.kind),
221
+ vitest_evals_kind: normalized.kind,
222
+ trace_id: _nullishCoalesce(normalized.traceId, () => ( trace.id)),
223
+ external_span_id: normalized.id,
224
+ external_parent_id: normalized.parentId,
225
+ status: normalized.status
226
+ },
227
+ startTime,
228
+ ...durationMs !== void 0 ? { event: { metrics: { duration_ms: durationMs } } } : {}
229
+ });
230
+ const metadata = {
231
+ traceName: trace.name,
232
+ traceMetadata: trace.metadata,
233
+ events: normalized.events
234
+ };
235
+ if (Object.values(metadata).some((value) => value !== void 0)) {
236
+ span.log({
237
+ metadata: Object.fromEntries(
238
+ Object.entries(metadata).filter(([, value]) => value !== void 0)
239
+ )
240
+ });
241
+ }
242
+ if (normalized.error !== void 0) {
243
+ logReporterError(span, normalized.error);
244
+ }
245
+ span.end({ endTime });
246
+ return span;
247
+ }
248
+ function logToolCallSpans(rootSpan, calls) {
249
+ for (const call of calls) {
250
+ if (!call.name) continue;
251
+ const durationMs = typeof call.durationMs === "number" && Number.isFinite(call.durationMs) ? call.durationMs : void 0;
252
+ const startTime = epochSeconds(call.startedAt);
253
+ const endTime = _nullishCoalesce(epochSeconds(call.finishedAt), () => ( (startTime !== void 0 && durationMs !== void 0 ? startTime + durationMs / 1e3 : void 0)));
254
+ const span = rootSpan.startSpan({
255
+ name: call.name,
256
+ spanAttributes: {
257
+ type: "tool" /* TOOL */,
258
+ tool_call_id: call.id
259
+ },
260
+ startTime,
261
+ event: {
262
+ input: call.arguments,
263
+ ...call.result !== void 0 ? { output: call.result } : {},
264
+ metadata: call.metadata,
265
+ metrics: durationMs !== void 0 ? { duration_ms: durationMs } : void 0
266
+ }
267
+ });
268
+ if (call.error !== void 0) {
269
+ logReporterError(span, call.error);
270
+ }
271
+ span.end({ endTime });
272
+ }
273
+ }
274
+ function readEvalTaskMeta(input) {
275
+ if (!_chunk37RLJF2Ujs.isObject.call(void 0, input)) return void 0;
276
+ const evalMeta = readEvalMeta(input.eval);
277
+ const harnessMeta = readHarnessMeta(input.harness);
278
+ if (!evalMeta && !harnessMeta) return void 0;
279
+ return {
280
+ ...evalMeta ? { eval: evalMeta } : {},
281
+ ...harnessMeta ? { harness: harnessMeta } : {}
282
+ };
283
+ }
284
+ function readEvalMeta(input) {
285
+ if (!_chunk37RLJF2Ujs.isObject.call(void 0, input)) return void 0;
286
+ const avgScore = readFiniteOrNull(input.avgScore);
287
+ const scores = Array.isArray(input.scores) ? input.scores.map(readEvalScore).filter(isDefined) : void 0;
288
+ const toolCalls = Array.isArray(input.toolCalls) ? input.toolCalls.map(readToolCall).filter(isDefined) : void 0;
289
+ return {
290
+ ...scores ? { scores } : {},
291
+ ...avgScore !== void 0 ? { avgScore } : {},
292
+ ...input.output !== void 0 ? { output: input.output } : {},
293
+ ...typeof input.thresholdFailed === "boolean" ? { thresholdFailed: input.thresholdFailed } : {},
294
+ ...toolCalls ? { toolCalls } : {}
295
+ };
296
+ }
297
+ function readEvalScore(input) {
298
+ if (!_chunk37RLJF2Ujs.isObject.call(void 0, input)) return void 0;
299
+ const score = readFiniteOrNull(input.score);
300
+ return {
301
+ ...typeof input.name === "string" ? { name: input.name } : {},
302
+ ...score !== void 0 ? { score } : {},
303
+ ..._chunk37RLJF2Ujs.isObject.call(void 0, input.metadata) ? { metadata: input.metadata } : {}
304
+ };
305
+ }
306
+ function readHarnessMeta(input) {
307
+ if (!_chunk37RLJF2Ujs.isObject.call(void 0, input)) return void 0;
308
+ return {
309
+ ...typeof input.name === "string" ? { name: input.name } : {},
310
+ ..._chunk37RLJF2Ujs.isObject.call(void 0, input.run) ? { run: input.run } : {}
311
+ };
312
+ }
313
+ function readToolCall(input) {
314
+ if (!_chunk37RLJF2Ujs.isObject.call(void 0, input)) return void 0;
315
+ return input;
316
+ }
317
+ function filteredNormalizedSpanAttributes(attributes) {
318
+ if (!attributes) return {};
319
+ return Object.fromEntries(
320
+ Object.entries(attributes).filter(
321
+ ([key]) => !RESERVED_NORMALIZED_SPAN_ATTRIBUTE_KEYS.has(key)
322
+ )
323
+ );
324
+ }
325
+ function readFiniteOrNull(value) {
326
+ if (value === null) return null;
327
+ if (typeof value === "number" && Number.isFinite(value)) {
328
+ return value;
329
+ }
330
+ return void 0;
331
+ }
332
+ function isDefined(value) {
333
+ return value !== void 0;
334
+ }
335
+ function firstUserMessageContent(run) {
336
+ return _optionalChain([run, 'optionalAccess', _34 => _34.session, 'optionalAccess', _35 => _35.messages, 'optionalAccess', _36 => _36.find, 'call', _37 => _37((message) => message.role === "user"), 'optionalAccess', _38 => _38.content]);
337
+ }
338
+ function toolCallsFromRun(run) {
339
+ const calls = [];
340
+ for (const message of _nullishCoalesce(_optionalChain([run, 'optionalAccess', _39 => _39.session, 'optionalAccess', _40 => _40.messages]), () => ( []))) {
341
+ if (Array.isArray(message.toolCalls)) {
342
+ calls.push(...message.toolCalls);
343
+ }
344
+ }
345
+ return calls;
346
+ }
347
+ function toolCallsFromMeta(evalMeta, run) {
348
+ const runCalls = toolCallsFromRun(run);
349
+ return runCalls.length > 0 ? runCalls : _nullishCoalesce(_optionalChain([evalMeta, 'optionalAccess', _41 => _41.toolCalls]), () => ( []));
350
+ }
351
+ function spanTypeForNormalizedKind(kind) {
352
+ switch (kind) {
353
+ case "model":
354
+ return "llm" /* LLM */;
355
+ case "tool":
356
+ return "tool" /* TOOL */;
357
+ case "agent":
358
+ case "run":
359
+ return "task" /* TASK */;
360
+ default:
361
+ return "function" /* FUNCTION */;
362
+ }
363
+ }
364
+ function startTimeSeconds(diagnostic) {
365
+ return _optionalChain([diagnostic, 'optionalAccess', _42 => _42.startTime]) === void 0 ? void 0 : diagnostic.startTime / 1e3;
366
+ }
367
+ function epochSeconds(value) {
368
+ if (value === void 0) return void 0;
369
+ const ms = Date.parse(value);
370
+ return Number.isFinite(ms) ? ms / 1e3 : void 0;
371
+ }
372
+ function logReporterError(span, error) {
373
+ if (error instanceof Error) {
374
+ _chunk37RLJF2Ujs.logError.call(void 0, span, error);
375
+ return;
376
+ }
377
+ if (_chunk37RLJF2Ujs.isObject.call(void 0, error)) {
378
+ const message = typeof error.message === "string" ? error.message : void 0;
379
+ const stack = typeof error.stack === "string" ? error.stack : void 0;
380
+ if (message !== void 0 || stack !== void 0) {
381
+ span.log({
382
+ error: stack ? `${_nullishCoalesce(message, () => ( "<error>"))}
383
+
384
+ ${stack}` : message
385
+ });
386
+ return;
387
+ }
388
+ }
389
+ _chunk37RLJF2Ujs.logError.call(void 0, span, error);
390
+ }
391
+ function formatErrorMessage(error) {
392
+ if (_chunk37RLJF2Ujs.isObject.call(void 0, error)) {
393
+ if (typeof error.message === "string") return error.message;
394
+ if (typeof error.stack === "string") return error.stack;
395
+ }
396
+ if (error instanceof Error) return error.message;
397
+ return String(error);
398
+ }
399
+
400
+
401
+ exports.default = BraintrustVitestEvalsReporter;