langsmith 0.3.20 → 0.3.21
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/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/jest/index.d.ts +73 -0
- package/dist/utils/jestlike/globals.d.ts +1 -0
- package/dist/utils/jestlike/index.cjs +47 -7
- package/dist/utils/jestlike/index.d.ts +73 -0
- package/dist/utils/jestlike/index.js +47 -7
- package/dist/vitest/index.d.ts +73 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8,4 +8,4 @@ Object.defineProperty(exports, "RunTree", { enumerable: true, get: function () {
|
|
|
8
8
|
var fetch_js_1 = require("./singletons/fetch.cjs");
|
|
9
9
|
Object.defineProperty(exports, "overrideFetchImplementation", { enumerable: true, get: function () { return fetch_js_1.overrideFetchImplementation; } });
|
|
10
10
|
// Update using yarn bump-version
|
|
11
|
-
exports.__version__ = "0.3.
|
|
11
|
+
exports.__version__ = "0.3.21";
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { Client, type ClientConfig, type LangSmithTracingClientInterface, } from
|
|
|
2
2
|
export type { Dataset, Example, TracerSession, Run, Feedback, RetrieverOutput, } from "./schemas.js";
|
|
3
3
|
export { RunTree, type RunTreeConfig } from "./run_trees.js";
|
|
4
4
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
5
|
-
export declare const __version__ = "0.3.
|
|
5
|
+
export declare const __version__ = "0.3.21";
|
package/dist/index.js
CHANGED
package/dist/jest/index.d.ts
CHANGED
|
@@ -85,6 +85,42 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
|
|
|
85
85
|
referenceOutputs?: O;
|
|
86
86
|
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
87
87
|
};
|
|
88
|
+
concurrent: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
89
|
+
inputs: I;
|
|
90
|
+
referenceOutputs?: O;
|
|
91
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
92
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
93
|
+
inputs: I;
|
|
94
|
+
referenceOutputs?: O;
|
|
95
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
96
|
+
inputs: I;
|
|
97
|
+
referenceOutputs?: O;
|
|
98
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
99
|
+
only: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
100
|
+
inputs: I;
|
|
101
|
+
referenceOutputs?: O;
|
|
102
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
103
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
104
|
+
inputs: I;
|
|
105
|
+
referenceOutputs?: O;
|
|
106
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
107
|
+
inputs: I;
|
|
108
|
+
referenceOutputs?: O;
|
|
109
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
110
|
+
};
|
|
111
|
+
skip: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
112
|
+
inputs: I;
|
|
113
|
+
referenceOutputs?: O;
|
|
114
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
115
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
116
|
+
inputs: I;
|
|
117
|
+
referenceOutputs?: O;
|
|
118
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
119
|
+
inputs: I;
|
|
120
|
+
referenceOutputs?: O;
|
|
121
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
88
124
|
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
89
125
|
inputs: I;
|
|
90
126
|
referenceOutputs?: O;
|
|
@@ -120,6 +156,42 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
|
|
|
120
156
|
referenceOutputs?: O;
|
|
121
157
|
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
122
158
|
};
|
|
159
|
+
concurrent: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
160
|
+
inputs: I;
|
|
161
|
+
referenceOutputs?: O;
|
|
162
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
163
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
164
|
+
inputs: I;
|
|
165
|
+
referenceOutputs?: O;
|
|
166
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
167
|
+
inputs: I;
|
|
168
|
+
referenceOutputs?: O;
|
|
169
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
170
|
+
only: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
171
|
+
inputs: I;
|
|
172
|
+
referenceOutputs?: O;
|
|
173
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
174
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
175
|
+
inputs: I;
|
|
176
|
+
referenceOutputs?: O;
|
|
177
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
178
|
+
inputs: I;
|
|
179
|
+
referenceOutputs?: O;
|
|
180
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
181
|
+
};
|
|
182
|
+
skip: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
183
|
+
inputs: I;
|
|
184
|
+
referenceOutputs?: O;
|
|
185
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
186
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
187
|
+
inputs: I;
|
|
188
|
+
referenceOutputs?: O;
|
|
189
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
190
|
+
inputs: I;
|
|
191
|
+
referenceOutputs?: O;
|
|
192
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
193
|
+
};
|
|
194
|
+
};
|
|
123
195
|
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
124
196
|
inputs: I;
|
|
125
197
|
referenceOutputs?: O;
|
|
@@ -130,6 +202,7 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
|
|
|
130
202
|
}, describe: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper & {
|
|
131
203
|
only: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
|
|
132
204
|
skip: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
|
|
205
|
+
concurrent: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
|
|
133
206
|
}, expect: jest.Expect;
|
|
134
207
|
export {
|
|
135
208
|
/**
|
|
@@ -19,6 +19,7 @@ export type TestWrapperAsyncLocalStorageData = {
|
|
|
19
19
|
suiteUuid: string;
|
|
20
20
|
suiteName: string;
|
|
21
21
|
testRootRunTree?: RunTree;
|
|
22
|
+
setupPromise?: Promise<void>;
|
|
22
23
|
};
|
|
23
24
|
export declare const testWrapperAsyncLocalStorageInstance: AsyncLocalStorage<TestWrapperAsyncLocalStorageData>;
|
|
24
25
|
export declare function trackingEnabled(context: TestWrapperAsyncLocalStorageData): boolean;
|
|
@@ -229,13 +229,27 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
229
229
|
}
|
|
230
230
|
return storageValue;
|
|
231
231
|
}
|
|
232
|
-
function wrapDescribeMethod(method) {
|
|
232
|
+
function wrapDescribeMethod(method, methodName) {
|
|
233
233
|
if ((0, env_js_1.isJsDom)()) {
|
|
234
234
|
console.error(`[LANGSMITH]: You seem to be using a jsdom environment. This is not supported and you may experience unexpected behavior. Please set the "environment" or "testEnvironment" field in your test config file to "node".`);
|
|
235
235
|
}
|
|
236
236
|
return function (testSuiteName, fn, experimentConfig) {
|
|
237
|
+
if (typeof method !== "function") {
|
|
238
|
+
throw new Error(`"${methodName}" is not supported by your test runner.`);
|
|
239
|
+
}
|
|
240
|
+
if (globals_js_1.testWrapperAsyncLocalStorageInstance.getStore() !== undefined) {
|
|
241
|
+
throw new Error([
|
|
242
|
+
`You seem to be nesting an ls.describe block named "${testSuiteName}" inside another ls.describe block.`,
|
|
243
|
+
"This is not supported because each ls.describe block corresponds to a LangSmith dataset.",
|
|
244
|
+
"To logically group tests, nest the native Jest or Vitest describe methods instead.",
|
|
245
|
+
].join("\n"));
|
|
246
|
+
}
|
|
237
247
|
const client = experimentConfig?.client ?? globals_js_1.DEFAULT_TEST_CLIENT;
|
|
238
248
|
const suiteName = experimentConfig?.testSuiteName ?? testSuiteName;
|
|
249
|
+
let setupPromiseResolver;
|
|
250
|
+
const setupPromise = new Promise((resolve) => {
|
|
251
|
+
setupPromiseResolver = resolve;
|
|
252
|
+
});
|
|
239
253
|
return method(suiteName, () => {
|
|
240
254
|
const startTime = new Date();
|
|
241
255
|
const suiteUuid = (0, uuid_1.v4)();
|
|
@@ -269,10 +283,12 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
269
283
|
metadata: suiteMetadata,
|
|
270
284
|
},
|
|
271
285
|
enableTestTracking: experimentConfig?.enableTestTracking,
|
|
286
|
+
setupPromise,
|
|
272
287
|
};
|
|
273
288
|
beforeAll(async () => {
|
|
274
289
|
const storageValue = await runDatasetSetup(context);
|
|
275
290
|
datasetSetupInfo.set(suiteUuid, storageValue);
|
|
291
|
+
setupPromiseResolver();
|
|
276
292
|
});
|
|
277
293
|
afterAll(async () => {
|
|
278
294
|
await Promise.all([
|
|
@@ -353,9 +369,10 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
353
369
|
});
|
|
354
370
|
};
|
|
355
371
|
}
|
|
356
|
-
const lsDescribe = Object.assign(wrapDescribeMethod(describe), {
|
|
357
|
-
only: wrapDescribeMethod(describe.only),
|
|
358
|
-
skip: wrapDescribeMethod(describe.skip),
|
|
372
|
+
const lsDescribe = Object.assign(wrapDescribeMethod(describe, "describe"), {
|
|
373
|
+
only: wrapDescribeMethod(describe.only, "describe.only"),
|
|
374
|
+
skip: wrapDescribeMethod(describe.skip, "describe.skip"),
|
|
375
|
+
concurrent: wrapDescribeMethod(describe.concurrent, "describe.concurrent"),
|
|
359
376
|
});
|
|
360
377
|
function wrapTestMethod(method) {
|
|
361
378
|
return function (name, lsParams, testFn, timeout) {
|
|
@@ -374,7 +391,12 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
374
391
|
// Jest will not group tests under the same "describe" group if you await the test and
|
|
375
392
|
// total runs is greater than 1.
|
|
376
393
|
const resultsPath = path.join(os.tmpdir(), "langsmith_test_results", `${testUuid}.json`);
|
|
377
|
-
void method(`${name}${totalRuns > 1 ? `, run ${i}` : ""}${constants_js_1.TEST_ID_DELIMITER}${testUuid}`, async () => {
|
|
394
|
+
void method(`${name}${totalRuns > 1 ? `, run ${i}` : ""}${constants_js_1.TEST_ID_DELIMITER}${testUuid}`, async (...args) => {
|
|
395
|
+
// Jest will magically introspect args and pass a "done" callback if
|
|
396
|
+
// we use a non-spread parameter. To obtain and pass Vitest test context
|
|
397
|
+
// through into the test function, we must therefore refer to Vitest
|
|
398
|
+
// args using this signature
|
|
399
|
+
const jestlikeArgs = args[0];
|
|
378
400
|
if (context === undefined) {
|
|
379
401
|
throw new Error([
|
|
380
402
|
`Could not retrieve test context.`,
|
|
@@ -382,6 +404,11 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
382
404
|
`See this page for more information: https://docs.smith.langchain.com/evaluation/how_to_guides/vitest_jest`,
|
|
383
405
|
].join("\n"));
|
|
384
406
|
}
|
|
407
|
+
// Jest .concurrent is super buggy and doesn't wait for beforeAll to complete
|
|
408
|
+
// before running test functions, so we need to wait for the setup promise
|
|
409
|
+
// to resolve before we can continue.
|
|
410
|
+
// Seee https://github.com/jestjs/jest/issues/4281
|
|
411
|
+
await context.setupPromise;
|
|
385
412
|
if (!datasetSetupInfo.get(context.suiteUuid)) {
|
|
386
413
|
throw new Error("Dataset failed to initialize. Please check your LangSmith environment variables.");
|
|
387
414
|
}
|
|
@@ -414,11 +441,13 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
414
441
|
throw new Error("Could not identify test context after setting test root run tree. Please contact us for help.");
|
|
415
442
|
}
|
|
416
443
|
try {
|
|
417
|
-
const res = await testFn(
|
|
444
|
+
const res = await testFn(Object.assign(typeof jestlikeArgs === "object" && jestlikeArgs != null
|
|
445
|
+
? jestlikeArgs
|
|
446
|
+
: {}, {
|
|
418
447
|
...rest,
|
|
419
448
|
inputs: testInput,
|
|
420
449
|
referenceOutputs: testOutput,
|
|
421
|
-
});
|
|
450
|
+
}));
|
|
422
451
|
(0, globals_js_1._logTestFeedback)({
|
|
423
452
|
exampleId,
|
|
424
453
|
feedback: { key: "pass", score: true },
|
|
@@ -582,6 +611,16 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
582
611
|
}
|
|
583
612
|
return eachMethod;
|
|
584
613
|
}
|
|
614
|
+
// Roughly mirrors: https://jestjs.io/docs/api#methods
|
|
615
|
+
const concurrentMethod = Object.assign(wrapTestMethod(test.concurrent), {
|
|
616
|
+
each: createEachMethod(test.concurrent),
|
|
617
|
+
only: Object.assign(wrapTestMethod(test.concurrent.only), {
|
|
618
|
+
each: createEachMethod(test.concurrent.only),
|
|
619
|
+
}),
|
|
620
|
+
skip: Object.assign(wrapTestMethod(test.concurrent.skip), {
|
|
621
|
+
each: createEachMethod(test.concurrent.skip),
|
|
622
|
+
}),
|
|
623
|
+
});
|
|
585
624
|
const lsTest = Object.assign(wrapTestMethod(test), {
|
|
586
625
|
only: Object.assign(wrapTestMethod(test.only), {
|
|
587
626
|
each: createEachMethod(test.only),
|
|
@@ -589,6 +628,7 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
589
628
|
skip: Object.assign(wrapTestMethod(test.skip), {
|
|
590
629
|
each: createEachMethod(test.skip),
|
|
591
630
|
}),
|
|
631
|
+
concurrent: concurrentMethod,
|
|
592
632
|
each: createEachMethod(test),
|
|
593
633
|
});
|
|
594
634
|
const wrappedExpect = (0, chain_js_1.wrapExpect)(expect);
|
|
@@ -36,6 +36,42 @@ export declare function generateWrapperFromJestlikeMethods(methods: Record<strin
|
|
|
36
36
|
referenceOutputs?: O;
|
|
37
37
|
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
38
38
|
};
|
|
39
|
+
concurrent: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
40
|
+
inputs: I;
|
|
41
|
+
referenceOutputs?: O;
|
|
42
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
43
|
+
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
44
|
+
inputs: I;
|
|
45
|
+
referenceOutputs?: O;
|
|
46
|
+
} & Record<string, any>)[], config?: LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
47
|
+
inputs: I;
|
|
48
|
+
referenceOutputs?: O;
|
|
49
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
50
|
+
only: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
51
|
+
inputs: I;
|
|
52
|
+
referenceOutputs?: O;
|
|
53
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
54
|
+
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
55
|
+
inputs: I;
|
|
56
|
+
referenceOutputs?: O;
|
|
57
|
+
} & Record<string, any>)[], config?: LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
58
|
+
inputs: I;
|
|
59
|
+
referenceOutputs?: O;
|
|
60
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
61
|
+
};
|
|
62
|
+
skip: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
63
|
+
inputs: I;
|
|
64
|
+
referenceOutputs?: O;
|
|
65
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
66
|
+
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
67
|
+
inputs: I;
|
|
68
|
+
referenceOutputs?: O;
|
|
69
|
+
} & Record<string, any>)[], config?: LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
70
|
+
inputs: I;
|
|
71
|
+
referenceOutputs?: O;
|
|
72
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
39
75
|
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
40
76
|
inputs: I;
|
|
41
77
|
referenceOutputs?: O;
|
|
@@ -72,6 +108,42 @@ export declare function generateWrapperFromJestlikeMethods(methods: Record<strin
|
|
|
72
108
|
referenceOutputs?: O;
|
|
73
109
|
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
74
110
|
};
|
|
111
|
+
concurrent: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
112
|
+
inputs: I;
|
|
113
|
+
referenceOutputs?: O;
|
|
114
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
115
|
+
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
116
|
+
inputs: I;
|
|
117
|
+
referenceOutputs?: O;
|
|
118
|
+
} & Record<string, any>)[], config?: LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
119
|
+
inputs: I;
|
|
120
|
+
referenceOutputs?: O;
|
|
121
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
122
|
+
only: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
123
|
+
inputs: I;
|
|
124
|
+
referenceOutputs?: O;
|
|
125
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
126
|
+
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
127
|
+
inputs: I;
|
|
128
|
+
referenceOutputs?: O;
|
|
129
|
+
} & Record<string, any>)[], config?: LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
130
|
+
inputs: I;
|
|
131
|
+
referenceOutputs?: O;
|
|
132
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
133
|
+
};
|
|
134
|
+
skip: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
135
|
+
inputs: I;
|
|
136
|
+
referenceOutputs?: O;
|
|
137
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
138
|
+
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
139
|
+
inputs: I;
|
|
140
|
+
referenceOutputs?: O;
|
|
141
|
+
} & Record<string, any>)[], config?: LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
142
|
+
inputs: I;
|
|
143
|
+
referenceOutputs?: O;
|
|
144
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
75
147
|
each: <I extends KVMap, O extends KVMap>(table: ({
|
|
76
148
|
inputs: I;
|
|
77
149
|
referenceOutputs?: O;
|
|
@@ -83,6 +155,7 @@ export declare function generateWrapperFromJestlikeMethods(methods: Record<strin
|
|
|
83
155
|
describe: LangSmithJestlikeDescribeWrapper & {
|
|
84
156
|
only: LangSmithJestlikeDescribeWrapper;
|
|
85
157
|
skip: LangSmithJestlikeDescribeWrapper;
|
|
158
|
+
concurrent: LangSmithJestlikeDescribeWrapper;
|
|
86
159
|
};
|
|
87
160
|
expect: jest.Expect;
|
|
88
161
|
toBeRelativeCloseTo: typeof toBeRelativeCloseTo;
|
|
@@ -182,13 +182,27 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
182
182
|
}
|
|
183
183
|
return storageValue;
|
|
184
184
|
}
|
|
185
|
-
function wrapDescribeMethod(method) {
|
|
185
|
+
function wrapDescribeMethod(method, methodName) {
|
|
186
186
|
if (isJsDom()) {
|
|
187
187
|
console.error(`[LANGSMITH]: You seem to be using a jsdom environment. This is not supported and you may experience unexpected behavior. Please set the "environment" or "testEnvironment" field in your test config file to "node".`);
|
|
188
188
|
}
|
|
189
189
|
return function (testSuiteName, fn, experimentConfig) {
|
|
190
|
+
if (typeof method !== "function") {
|
|
191
|
+
throw new Error(`"${methodName}" is not supported by your test runner.`);
|
|
192
|
+
}
|
|
193
|
+
if (testWrapperAsyncLocalStorageInstance.getStore() !== undefined) {
|
|
194
|
+
throw new Error([
|
|
195
|
+
`You seem to be nesting an ls.describe block named "${testSuiteName}" inside another ls.describe block.`,
|
|
196
|
+
"This is not supported because each ls.describe block corresponds to a LangSmith dataset.",
|
|
197
|
+
"To logically group tests, nest the native Jest or Vitest describe methods instead.",
|
|
198
|
+
].join("\n"));
|
|
199
|
+
}
|
|
190
200
|
const client = experimentConfig?.client ?? DEFAULT_TEST_CLIENT;
|
|
191
201
|
const suiteName = experimentConfig?.testSuiteName ?? testSuiteName;
|
|
202
|
+
let setupPromiseResolver;
|
|
203
|
+
const setupPromise = new Promise((resolve) => {
|
|
204
|
+
setupPromiseResolver = resolve;
|
|
205
|
+
});
|
|
192
206
|
return method(suiteName, () => {
|
|
193
207
|
const startTime = new Date();
|
|
194
208
|
const suiteUuid = v4();
|
|
@@ -222,10 +236,12 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
222
236
|
metadata: suiteMetadata,
|
|
223
237
|
},
|
|
224
238
|
enableTestTracking: experimentConfig?.enableTestTracking,
|
|
239
|
+
setupPromise,
|
|
225
240
|
};
|
|
226
241
|
beforeAll(async () => {
|
|
227
242
|
const storageValue = await runDatasetSetup(context);
|
|
228
243
|
datasetSetupInfo.set(suiteUuid, storageValue);
|
|
244
|
+
setupPromiseResolver();
|
|
229
245
|
});
|
|
230
246
|
afterAll(async () => {
|
|
231
247
|
await Promise.all([
|
|
@@ -306,9 +322,10 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
306
322
|
});
|
|
307
323
|
};
|
|
308
324
|
}
|
|
309
|
-
const lsDescribe = Object.assign(wrapDescribeMethod(describe), {
|
|
310
|
-
only: wrapDescribeMethod(describe.only),
|
|
311
|
-
skip: wrapDescribeMethod(describe.skip),
|
|
325
|
+
const lsDescribe = Object.assign(wrapDescribeMethod(describe, "describe"), {
|
|
326
|
+
only: wrapDescribeMethod(describe.only, "describe.only"),
|
|
327
|
+
skip: wrapDescribeMethod(describe.skip, "describe.skip"),
|
|
328
|
+
concurrent: wrapDescribeMethod(describe.concurrent, "describe.concurrent"),
|
|
312
329
|
});
|
|
313
330
|
function wrapTestMethod(method) {
|
|
314
331
|
return function (name, lsParams, testFn, timeout) {
|
|
@@ -327,7 +344,12 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
327
344
|
// Jest will not group tests under the same "describe" group if you await the test and
|
|
328
345
|
// total runs is greater than 1.
|
|
329
346
|
const resultsPath = path.join(os.tmpdir(), "langsmith_test_results", `${testUuid}.json`);
|
|
330
|
-
void method(`${name}${totalRuns > 1 ? `, run ${i}` : ""}${TEST_ID_DELIMITER}${testUuid}`, async () => {
|
|
347
|
+
void method(`${name}${totalRuns > 1 ? `, run ${i}` : ""}${TEST_ID_DELIMITER}${testUuid}`, async (...args) => {
|
|
348
|
+
// Jest will magically introspect args and pass a "done" callback if
|
|
349
|
+
// we use a non-spread parameter. To obtain and pass Vitest test context
|
|
350
|
+
// through into the test function, we must therefore refer to Vitest
|
|
351
|
+
// args using this signature
|
|
352
|
+
const jestlikeArgs = args[0];
|
|
331
353
|
if (context === undefined) {
|
|
332
354
|
throw new Error([
|
|
333
355
|
`Could not retrieve test context.`,
|
|
@@ -335,6 +357,11 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
335
357
|
`See this page for more information: https://docs.smith.langchain.com/evaluation/how_to_guides/vitest_jest`,
|
|
336
358
|
].join("\n"));
|
|
337
359
|
}
|
|
360
|
+
// Jest .concurrent is super buggy and doesn't wait for beforeAll to complete
|
|
361
|
+
// before running test functions, so we need to wait for the setup promise
|
|
362
|
+
// to resolve before we can continue.
|
|
363
|
+
// Seee https://github.com/jestjs/jest/issues/4281
|
|
364
|
+
await context.setupPromise;
|
|
338
365
|
if (!datasetSetupInfo.get(context.suiteUuid)) {
|
|
339
366
|
throw new Error("Dataset failed to initialize. Please check your LangSmith environment variables.");
|
|
340
367
|
}
|
|
@@ -367,11 +394,13 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
367
394
|
throw new Error("Could not identify test context after setting test root run tree. Please contact us for help.");
|
|
368
395
|
}
|
|
369
396
|
try {
|
|
370
|
-
const res = await testFn(
|
|
397
|
+
const res = await testFn(Object.assign(typeof jestlikeArgs === "object" && jestlikeArgs != null
|
|
398
|
+
? jestlikeArgs
|
|
399
|
+
: {}, {
|
|
371
400
|
...rest,
|
|
372
401
|
inputs: testInput,
|
|
373
402
|
referenceOutputs: testOutput,
|
|
374
|
-
});
|
|
403
|
+
}));
|
|
375
404
|
_logTestFeedback({
|
|
376
405
|
exampleId,
|
|
377
406
|
feedback: { key: "pass", score: true },
|
|
@@ -535,6 +564,16 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
535
564
|
}
|
|
536
565
|
return eachMethod;
|
|
537
566
|
}
|
|
567
|
+
// Roughly mirrors: https://jestjs.io/docs/api#methods
|
|
568
|
+
const concurrentMethod = Object.assign(wrapTestMethod(test.concurrent), {
|
|
569
|
+
each: createEachMethod(test.concurrent),
|
|
570
|
+
only: Object.assign(wrapTestMethod(test.concurrent.only), {
|
|
571
|
+
each: createEachMethod(test.concurrent.only),
|
|
572
|
+
}),
|
|
573
|
+
skip: Object.assign(wrapTestMethod(test.concurrent.skip), {
|
|
574
|
+
each: createEachMethod(test.concurrent.skip),
|
|
575
|
+
}),
|
|
576
|
+
});
|
|
538
577
|
const lsTest = Object.assign(wrapTestMethod(test), {
|
|
539
578
|
only: Object.assign(wrapTestMethod(test.only), {
|
|
540
579
|
each: createEachMethod(test.only),
|
|
@@ -542,6 +581,7 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
542
581
|
skip: Object.assign(wrapTestMethod(test.skip), {
|
|
543
582
|
each: createEachMethod(test.skip),
|
|
544
583
|
}),
|
|
584
|
+
concurrent: concurrentMethod,
|
|
545
585
|
each: createEachMethod(test),
|
|
546
586
|
});
|
|
547
587
|
const wrappedExpect = wrapExpect(expect);
|
package/dist/vitest/index.d.ts
CHANGED
|
@@ -83,6 +83,42 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
|
|
|
83
83
|
referenceOutputs?: O;
|
|
84
84
|
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
85
85
|
};
|
|
86
|
+
concurrent: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
87
|
+
inputs: I;
|
|
88
|
+
referenceOutputs?: O;
|
|
89
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
90
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
91
|
+
inputs: I;
|
|
92
|
+
referenceOutputs?: O;
|
|
93
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
94
|
+
inputs: I;
|
|
95
|
+
referenceOutputs?: O;
|
|
96
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
97
|
+
only: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
98
|
+
inputs: I;
|
|
99
|
+
referenceOutputs?: O;
|
|
100
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
101
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
102
|
+
inputs: I;
|
|
103
|
+
referenceOutputs?: O;
|
|
104
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
105
|
+
inputs: I;
|
|
106
|
+
referenceOutputs?: O;
|
|
107
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
108
|
+
};
|
|
109
|
+
skip: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
110
|
+
inputs: I;
|
|
111
|
+
referenceOutputs?: O;
|
|
112
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
113
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
114
|
+
inputs: I;
|
|
115
|
+
referenceOutputs?: O;
|
|
116
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
117
|
+
inputs: I;
|
|
118
|
+
referenceOutputs?: O;
|
|
119
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
86
122
|
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
87
123
|
inputs: I;
|
|
88
124
|
referenceOutputs?: O;
|
|
@@ -118,6 +154,42 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
|
|
|
118
154
|
referenceOutputs?: O;
|
|
119
155
|
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
120
156
|
};
|
|
157
|
+
concurrent: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
158
|
+
inputs: I;
|
|
159
|
+
referenceOutputs?: O;
|
|
160
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
161
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
162
|
+
inputs: I;
|
|
163
|
+
referenceOutputs?: O;
|
|
164
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
165
|
+
inputs: I;
|
|
166
|
+
referenceOutputs?: O;
|
|
167
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
168
|
+
only: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
169
|
+
inputs: I;
|
|
170
|
+
referenceOutputs?: O;
|
|
171
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
172
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
173
|
+
inputs: I;
|
|
174
|
+
referenceOutputs?: O;
|
|
175
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
176
|
+
inputs: I;
|
|
177
|
+
referenceOutputs?: O;
|
|
178
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
179
|
+
};
|
|
180
|
+
skip: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(name: string, lsParams: LangSmithJestlikeWrapperParams<I, O>, testFn: (data: {
|
|
181
|
+
inputs: I;
|
|
182
|
+
referenceOutputs?: O;
|
|
183
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void) & {
|
|
184
|
+
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
185
|
+
inputs: I;
|
|
186
|
+
referenceOutputs?: O;
|
|
187
|
+
} & Record<string, any>)[], config?: import("../utils/jestlike/types.js").LangSmithJestlikeWrapperConfig) => (name: string, fn: (params: {
|
|
188
|
+
inputs: I;
|
|
189
|
+
referenceOutputs?: O;
|
|
190
|
+
} & Record<string, any>) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
191
|
+
};
|
|
192
|
+
};
|
|
121
193
|
each: <I extends import("../schemas.js").KVMap, O extends import("../schemas.js").KVMap>(table: ({
|
|
122
194
|
inputs: I;
|
|
123
195
|
referenceOutputs?: O;
|
|
@@ -128,6 +200,7 @@ declare const test: (<I extends Record<string, any> = Record<string, any>, O ext
|
|
|
128
200
|
}, describe: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper & {
|
|
129
201
|
only: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
|
|
130
202
|
skip: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
|
|
203
|
+
concurrent: import("../utils/jestlike/types.js").LangSmithJestlikeDescribeWrapper;
|
|
131
204
|
}, expect: jest.Expect;
|
|
132
205
|
export {
|
|
133
206
|
/**
|