langsmith 0.2.14-rc.0 → 0.2.14-rc.2
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/globals.d.ts +4 -1
- package/dist/jest/index.cjs +106 -58
- package/dist/jest/index.d.ts +6 -6
- package/dist/jest/index.js +107 -59
- package/dist/jest/vendor/chain.cjs +0 -4
- package/dist/jest/vendor/chain.js +0 -4
- 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.2.14-rc.
|
|
11
|
+
exports.__version__ = "0.2.14-rc.2";
|
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.2.14-rc.
|
|
5
|
+
export declare const __version__ = "0.2.14-rc.2";
|
package/dist/index.js
CHANGED
|
@@ -2,4 +2,4 @@ export { Client, } from "./client.js";
|
|
|
2
2
|
export { RunTree } from "./run_trees.js";
|
|
3
3
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
4
4
|
// Update using yarn bump-version
|
|
5
|
-
export const __version__ = "0.2.14-rc.
|
|
5
|
+
export const __version__ = "0.2.14-rc.2";
|
package/dist/jest/globals.d.ts
CHANGED
|
@@ -6,10 +6,13 @@ export declare const jestAsyncLocalStorageInstance: AsyncLocalStorage<{
|
|
|
6
6
|
dataset?: Dataset | undefined;
|
|
7
7
|
examples?: (Example & {
|
|
8
8
|
inputHash: string;
|
|
9
|
+
outputHash: string;
|
|
9
10
|
})[] | undefined;
|
|
10
11
|
createdAt: string;
|
|
11
12
|
project?: TracerSession | undefined;
|
|
12
13
|
currentExample?: Partial<Example> | undefined;
|
|
13
|
-
client
|
|
14
|
+
client: Client;
|
|
15
|
+
suiteUuid: string;
|
|
16
|
+
suiteName: string;
|
|
14
17
|
}>;
|
|
15
18
|
export declare function trackingEnabled(): boolean;
|
package/dist/jest/index.cjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-namespace */
|
|
2
4
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
5
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
6
|
};
|
|
@@ -44,55 +46,75 @@ async function _createProject(client, datasetId) {
|
|
|
44
46
|
throw new Error("Could not generate a unique experiment name within 10 attempts." +
|
|
45
47
|
" Please try again.");
|
|
46
48
|
}
|
|
49
|
+
const setupPromises = new Map();
|
|
50
|
+
async function runDatasetSetup(testClient, datasetName) {
|
|
51
|
+
let storageValue;
|
|
52
|
+
if (!(0, globals_js_1.trackingEnabled)()) {
|
|
53
|
+
storageValue = {
|
|
54
|
+
createdAt: new Date().toISOString(),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
let dataset;
|
|
59
|
+
try {
|
|
60
|
+
dataset = await testClient.readDataset({
|
|
61
|
+
datasetName,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
if (e.message.includes("not found")) {
|
|
66
|
+
dataset = await testClient.createDataset(datasetName, {
|
|
67
|
+
description: `Dataset for unit tests created on ${new Date().toISOString()}`,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const examplesList = testClient.listExamples({
|
|
75
|
+
datasetName,
|
|
76
|
+
});
|
|
77
|
+
const examples = [];
|
|
78
|
+
for await (const example of examplesList) {
|
|
79
|
+
const inputHash = crypto_1.default
|
|
80
|
+
.createHash("sha256")
|
|
81
|
+
.update(JSON.stringify(example.inputs))
|
|
82
|
+
.digest("hex");
|
|
83
|
+
const outputHash = crypto_1.default
|
|
84
|
+
.createHash("sha256")
|
|
85
|
+
.update(JSON.stringify(example.inputs))
|
|
86
|
+
.digest("hex");
|
|
87
|
+
examples.push({ ...example, inputHash, outputHash });
|
|
88
|
+
}
|
|
89
|
+
const project = await _createProject(testClient, dataset.id);
|
|
90
|
+
storageValue = {
|
|
91
|
+
dataset,
|
|
92
|
+
examples,
|
|
93
|
+
project,
|
|
94
|
+
client: testClient,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return storageValue;
|
|
98
|
+
}
|
|
47
99
|
function wrapDescribeMethod(method) {
|
|
48
100
|
return function (datasetName, fn, config) {
|
|
49
|
-
const testClient = config?.client ?? run_trees_js_1.RunTree.getSharedClient();
|
|
50
101
|
return method(datasetName, () => {
|
|
51
|
-
(0,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
description: `Dataset for unit tests created on ${new Date().toISOString()}`,
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
throw e;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
const examplesList = testClient.listExamples({
|
|
75
|
-
datasetName,
|
|
76
|
-
});
|
|
77
|
-
const examples = [];
|
|
78
|
-
for await (const example of examplesList) {
|
|
79
|
-
const inputHash = crypto_1.default
|
|
80
|
-
.createHash("sha256")
|
|
81
|
-
.update(JSON.stringify(example.inputs))
|
|
82
|
-
.digest("hex");
|
|
83
|
-
examples.push({ ...example, inputHash });
|
|
84
|
-
}
|
|
85
|
-
const project = await _createProject(testClient, dataset.id);
|
|
86
|
-
globals_js_1.jestAsyncLocalStorageInstance.enterWith({
|
|
87
|
-
dataset,
|
|
88
|
-
examples,
|
|
89
|
-
createdAt: new Date().toISOString(),
|
|
90
|
-
project,
|
|
91
|
-
client: testClient,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
fn();
|
|
102
|
+
const suiteUuid = (0, uuid_1.v4)();
|
|
103
|
+
/**
|
|
104
|
+
* We cannot rely on setting AsyncLocalStorage in beforeAll or beforeEach,
|
|
105
|
+
* due to https://github.com/jestjs/jest/issues/13653 and needing to use
|
|
106
|
+
* the janky .enterWith.
|
|
107
|
+
*
|
|
108
|
+
* We also cannot do async setup in describe due to Jest restrictions.
|
|
109
|
+
* However, .run works and since the below function does not contain synchronously,
|
|
110
|
+
* it works.
|
|
111
|
+
*/
|
|
112
|
+
void globals_js_1.jestAsyncLocalStorageInstance.run({
|
|
113
|
+
suiteUuid,
|
|
114
|
+
suiteName: datasetName,
|
|
115
|
+
client: config?.client ?? run_trees_js_1.RunTree.getSharedClient(),
|
|
116
|
+
createdAt: new Date().toISOString(),
|
|
117
|
+
}, fn);
|
|
96
118
|
});
|
|
97
119
|
};
|
|
98
120
|
}
|
|
@@ -102,37 +124,62 @@ const lsDescribe = Object.assign(wrapDescribeMethod(globals_1.describe), {
|
|
|
102
124
|
});
|
|
103
125
|
function wrapTestMethod(method) {
|
|
104
126
|
return function (params, config) {
|
|
127
|
+
const context = globals_js_1.jestAsyncLocalStorageInstance.getStore();
|
|
128
|
+
// This typing is wrong, but necessary to avoid lint errors
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
105
130
|
return async function (...args) {
|
|
106
131
|
return method(args[0], async () => {
|
|
132
|
+
if (context === undefined) {
|
|
133
|
+
throw new Error(`Could not retrieve test context.\nPlease make sure you have tracing enabled and you are wrapping all of your test cases in an "ls.describe()" function.`);
|
|
134
|
+
}
|
|
135
|
+
// Because of https://github.com/jestjs/jest/issues/13653, we have to do asynchronous setup
|
|
136
|
+
// within the test itself
|
|
137
|
+
if (!setupPromises.get(context.suiteUuid)) {
|
|
138
|
+
setupPromises.set(context.suiteUuid, runDatasetSetup(context.client, context.suiteName));
|
|
139
|
+
}
|
|
140
|
+
const { examples, dataset, createdAt, project, client } = await setupPromises.get(context.suiteUuid);
|
|
107
141
|
const testInput = typeof params === "string" ? {} : params.inputs;
|
|
108
142
|
const testOutput = typeof params === "string" ? {} : params.outputs;
|
|
109
143
|
const inputHash = crypto_1.default
|
|
110
144
|
.createHash("sha256")
|
|
111
145
|
.update(JSON.stringify(testInput))
|
|
112
146
|
.digest("hex");
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const { examples, dataset, createdAt, project, client } = context;
|
|
147
|
+
const outputHash = crypto_1.default
|
|
148
|
+
.createHash("sha256")
|
|
149
|
+
.update(JSON.stringify(testOutput))
|
|
150
|
+
.digest("hex");
|
|
118
151
|
if ((0, globals_js_1.trackingEnabled)()) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
152
|
+
const missingFields = [];
|
|
153
|
+
if (examples === undefined) {
|
|
154
|
+
missingFields.push("examples");
|
|
155
|
+
}
|
|
156
|
+
if (dataset === undefined) {
|
|
157
|
+
missingFields.push("dataset");
|
|
158
|
+
}
|
|
159
|
+
if (project === undefined) {
|
|
160
|
+
missingFields.push("project");
|
|
161
|
+
}
|
|
162
|
+
if (client === undefined) {
|
|
163
|
+
missingFields.push("client");
|
|
164
|
+
}
|
|
165
|
+
if (missingFields.length > 0) {
|
|
166
|
+
throw new Error(`Failed to initialize test tracking: Could not identify ${missingFields
|
|
167
|
+
.map((field) => `"${field}"`)
|
|
168
|
+
.join(", ")} while syncing to LangSmith. Please contact us for help.`);
|
|
124
169
|
}
|
|
125
170
|
const testClient = config?.client ?? client;
|
|
126
171
|
let example = (examples ?? []).find((example) => {
|
|
127
|
-
return example.inputHash === inputHash
|
|
172
|
+
return (example.inputHash === inputHash &&
|
|
173
|
+
example.outputHash === outputHash);
|
|
128
174
|
});
|
|
129
175
|
if (example === undefined) {
|
|
130
176
|
const newExample = await testClient.createExample(testInput, testOutput, {
|
|
131
177
|
datasetId: dataset?.id,
|
|
132
178
|
createdAt: new Date(createdAt ?? new Date()),
|
|
133
179
|
});
|
|
134
|
-
example = { ...newExample, inputHash };
|
|
180
|
+
example = { ...newExample, inputHash, outputHash };
|
|
135
181
|
}
|
|
182
|
+
// .enterWith is OK here
|
|
136
183
|
globals_js_1.jestAsyncLocalStorageInstance.enterWith({
|
|
137
184
|
...context,
|
|
138
185
|
currentExample: example,
|
|
@@ -163,6 +210,7 @@ function wrapTestMethod(method) {
|
|
|
163
210
|
await testClient.awaitPendingTraceBatches();
|
|
164
211
|
}
|
|
165
212
|
else {
|
|
213
|
+
// .enterWith is OK here
|
|
166
214
|
globals_js_1.jestAsyncLocalStorageInstance.enterWith({
|
|
167
215
|
...context,
|
|
168
216
|
currentExample: { inputs: testInput, outputs: testOutput },
|
package/dist/jest/index.d.ts
CHANGED
|
@@ -4,14 +4,14 @@ import type { SimpleEvaluator } from "./vendor/gradedBy.js";
|
|
|
4
4
|
declare global {
|
|
5
5
|
namespace jest {
|
|
6
6
|
interface AsymmetricMatchers {
|
|
7
|
-
toBeRelativeCloseTo(expected: string, options
|
|
8
|
-
toBeAbsoluteCloseTo(expected: string, options
|
|
9
|
-
toBeSemanticCloseTo(expected: string, options
|
|
7
|
+
toBeRelativeCloseTo(expected: string, options?: any): void;
|
|
8
|
+
toBeAbsoluteCloseTo(expected: string, options?: any): void;
|
|
9
|
+
toBeSemanticCloseTo(expected: string, options?: any): Promise<void>;
|
|
10
10
|
}
|
|
11
11
|
interface Matchers<R> {
|
|
12
|
-
toBeRelativeCloseTo(expected: string, options
|
|
13
|
-
toBeAbsoluteCloseTo(expected: string, options
|
|
14
|
-
toBeSemanticCloseTo(expected: string, options
|
|
12
|
+
toBeRelativeCloseTo(expected: string, options?: any): R;
|
|
13
|
+
toBeAbsoluteCloseTo(expected: string, options?: any): R;
|
|
14
|
+
toBeSemanticCloseTo(expected: string, options?: any): Promise<R>;
|
|
15
15
|
gradedBy(evaluator: SimpleEvaluator): jest.Matchers<Promise<R>> & {
|
|
16
16
|
not: jest.Matchers<Promise<R>>;
|
|
17
17
|
resolves: jest.Matchers<Promise<R>>;
|
package/dist/jest/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-namespace */
|
|
3
|
+
import { expect, test, describe } from "@jest/globals";
|
|
2
4
|
import crypto from "crypto";
|
|
3
5
|
import { v4 } from "uuid";
|
|
4
6
|
import { traceable } from "../traceable.js";
|
|
@@ -39,55 +41,75 @@ async function _createProject(client, datasetId) {
|
|
|
39
41
|
throw new Error("Could not generate a unique experiment name within 10 attempts." +
|
|
40
42
|
" Please try again.");
|
|
41
43
|
}
|
|
44
|
+
const setupPromises = new Map();
|
|
45
|
+
async function runDatasetSetup(testClient, datasetName) {
|
|
46
|
+
let storageValue;
|
|
47
|
+
if (!trackingEnabled()) {
|
|
48
|
+
storageValue = {
|
|
49
|
+
createdAt: new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
let dataset;
|
|
54
|
+
try {
|
|
55
|
+
dataset = await testClient.readDataset({
|
|
56
|
+
datasetName,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
if (e.message.includes("not found")) {
|
|
61
|
+
dataset = await testClient.createDataset(datasetName, {
|
|
62
|
+
description: `Dataset for unit tests created on ${new Date().toISOString()}`,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
throw e;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const examplesList = testClient.listExamples({
|
|
70
|
+
datasetName,
|
|
71
|
+
});
|
|
72
|
+
const examples = [];
|
|
73
|
+
for await (const example of examplesList) {
|
|
74
|
+
const inputHash = crypto
|
|
75
|
+
.createHash("sha256")
|
|
76
|
+
.update(JSON.stringify(example.inputs))
|
|
77
|
+
.digest("hex");
|
|
78
|
+
const outputHash = crypto
|
|
79
|
+
.createHash("sha256")
|
|
80
|
+
.update(JSON.stringify(example.inputs))
|
|
81
|
+
.digest("hex");
|
|
82
|
+
examples.push({ ...example, inputHash, outputHash });
|
|
83
|
+
}
|
|
84
|
+
const project = await _createProject(testClient, dataset.id);
|
|
85
|
+
storageValue = {
|
|
86
|
+
dataset,
|
|
87
|
+
examples,
|
|
88
|
+
project,
|
|
89
|
+
client: testClient,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return storageValue;
|
|
93
|
+
}
|
|
42
94
|
function wrapDescribeMethod(method) {
|
|
43
95
|
return function (datasetName, fn, config) {
|
|
44
|
-
const testClient = config?.client ?? RunTree.getSharedClient();
|
|
45
96
|
return method(datasetName, () => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
description: `Dataset for unit tests created on ${new Date().toISOString()}`,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
throw e;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const examplesList = testClient.listExamples({
|
|
70
|
-
datasetName,
|
|
71
|
-
});
|
|
72
|
-
const examples = [];
|
|
73
|
-
for await (const example of examplesList) {
|
|
74
|
-
const inputHash = crypto
|
|
75
|
-
.createHash("sha256")
|
|
76
|
-
.update(JSON.stringify(example.inputs))
|
|
77
|
-
.digest("hex");
|
|
78
|
-
examples.push({ ...example, inputHash });
|
|
79
|
-
}
|
|
80
|
-
const project = await _createProject(testClient, dataset.id);
|
|
81
|
-
jestAsyncLocalStorageInstance.enterWith({
|
|
82
|
-
dataset,
|
|
83
|
-
examples,
|
|
84
|
-
createdAt: new Date().toISOString(),
|
|
85
|
-
project,
|
|
86
|
-
client: testClient,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
fn();
|
|
97
|
+
const suiteUuid = v4();
|
|
98
|
+
/**
|
|
99
|
+
* We cannot rely on setting AsyncLocalStorage in beforeAll or beforeEach,
|
|
100
|
+
* due to https://github.com/jestjs/jest/issues/13653 and needing to use
|
|
101
|
+
* the janky .enterWith.
|
|
102
|
+
*
|
|
103
|
+
* We also cannot do async setup in describe due to Jest restrictions.
|
|
104
|
+
* However, .run works and since the below function does not contain synchronously,
|
|
105
|
+
* it works.
|
|
106
|
+
*/
|
|
107
|
+
void jestAsyncLocalStorageInstance.run({
|
|
108
|
+
suiteUuid,
|
|
109
|
+
suiteName: datasetName,
|
|
110
|
+
client: config?.client ?? RunTree.getSharedClient(),
|
|
111
|
+
createdAt: new Date().toISOString(),
|
|
112
|
+
}, fn);
|
|
91
113
|
});
|
|
92
114
|
};
|
|
93
115
|
}
|
|
@@ -97,37 +119,62 @@ const lsDescribe = Object.assign(wrapDescribeMethod(describe), {
|
|
|
97
119
|
});
|
|
98
120
|
function wrapTestMethod(method) {
|
|
99
121
|
return function (params, config) {
|
|
122
|
+
const context = jestAsyncLocalStorageInstance.getStore();
|
|
123
|
+
// This typing is wrong, but necessary to avoid lint errors
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
100
125
|
return async function (...args) {
|
|
101
126
|
return method(args[0], async () => {
|
|
127
|
+
if (context === undefined) {
|
|
128
|
+
throw new Error(`Could not retrieve test context.\nPlease make sure you have tracing enabled and you are wrapping all of your test cases in an "ls.describe()" function.`);
|
|
129
|
+
}
|
|
130
|
+
// Because of https://github.com/jestjs/jest/issues/13653, we have to do asynchronous setup
|
|
131
|
+
// within the test itself
|
|
132
|
+
if (!setupPromises.get(context.suiteUuid)) {
|
|
133
|
+
setupPromises.set(context.suiteUuid, runDatasetSetup(context.client, context.suiteName));
|
|
134
|
+
}
|
|
135
|
+
const { examples, dataset, createdAt, project, client } = await setupPromises.get(context.suiteUuid);
|
|
102
136
|
const testInput = typeof params === "string" ? {} : params.inputs;
|
|
103
137
|
const testOutput = typeof params === "string" ? {} : params.outputs;
|
|
104
138
|
const inputHash = crypto
|
|
105
139
|
.createHash("sha256")
|
|
106
140
|
.update(JSON.stringify(testInput))
|
|
107
141
|
.digest("hex");
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const { examples, dataset, createdAt, project, client } = context;
|
|
142
|
+
const outputHash = crypto
|
|
143
|
+
.createHash("sha256")
|
|
144
|
+
.update(JSON.stringify(testOutput))
|
|
145
|
+
.digest("hex");
|
|
113
146
|
if (trackingEnabled()) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
147
|
+
const missingFields = [];
|
|
148
|
+
if (examples === undefined) {
|
|
149
|
+
missingFields.push("examples");
|
|
150
|
+
}
|
|
151
|
+
if (dataset === undefined) {
|
|
152
|
+
missingFields.push("dataset");
|
|
153
|
+
}
|
|
154
|
+
if (project === undefined) {
|
|
155
|
+
missingFields.push("project");
|
|
156
|
+
}
|
|
157
|
+
if (client === undefined) {
|
|
158
|
+
missingFields.push("client");
|
|
159
|
+
}
|
|
160
|
+
if (missingFields.length > 0) {
|
|
161
|
+
throw new Error(`Failed to initialize test tracking: Could not identify ${missingFields
|
|
162
|
+
.map((field) => `"${field}"`)
|
|
163
|
+
.join(", ")} while syncing to LangSmith. Please contact us for help.`);
|
|
119
164
|
}
|
|
120
165
|
const testClient = config?.client ?? client;
|
|
121
166
|
let example = (examples ?? []).find((example) => {
|
|
122
|
-
return example.inputHash === inputHash
|
|
167
|
+
return (example.inputHash === inputHash &&
|
|
168
|
+
example.outputHash === outputHash);
|
|
123
169
|
});
|
|
124
170
|
if (example === undefined) {
|
|
125
171
|
const newExample = await testClient.createExample(testInput, testOutput, {
|
|
126
172
|
datasetId: dataset?.id,
|
|
127
173
|
createdAt: new Date(createdAt ?? new Date()),
|
|
128
174
|
});
|
|
129
|
-
example = { ...newExample, inputHash };
|
|
175
|
+
example = { ...newExample, inputHash, outputHash };
|
|
130
176
|
}
|
|
177
|
+
// .enterWith is OK here
|
|
131
178
|
jestAsyncLocalStorageInstance.enterWith({
|
|
132
179
|
...context,
|
|
133
180
|
currentExample: example,
|
|
@@ -158,6 +205,7 @@ function wrapTestMethod(method) {
|
|
|
158
205
|
await testClient.awaitPendingTraceBatches();
|
|
159
206
|
}
|
|
160
207
|
else {
|
|
208
|
+
// .enterWith is OK here
|
|
161
209
|
jestAsyncLocalStorageInstance.enterWith({
|
|
162
210
|
...context,
|
|
163
211
|
currentExample: { inputs: testInput, outputs: testOutput },
|
|
@@ -71,10 +71,6 @@ function expectWithGradedBy(expect) {
|
|
|
71
71
|
const expectProxy = Object.assign((...args) => addGradedBy(expect(...args), args), // partially apply expect to get all matchers and chain them
|
|
72
72
|
expect // clone additional properties on expect
|
|
73
73
|
);
|
|
74
|
-
// expectProxy.extend = (o: any) => {
|
|
75
|
-
// expect.extend(o); // add new matchers to expect
|
|
76
|
-
// expectProxy = Object.assign(expectProxy, expect); // clone new asymmetric matchers
|
|
77
|
-
// };
|
|
78
74
|
return expectProxy;
|
|
79
75
|
}
|
|
80
76
|
exports.default = expectWithGradedBy;
|
|
@@ -69,10 +69,6 @@ export default function expectWithGradedBy(expect) {
|
|
|
69
69
|
const expectProxy = Object.assign((...args) => addGradedBy(expect(...args), args), // partially apply expect to get all matchers and chain them
|
|
70
70
|
expect // clone additional properties on expect
|
|
71
71
|
);
|
|
72
|
-
// expectProxy.extend = (o: any) => {
|
|
73
|
-
// expect.extend(o); // add new matchers to expect
|
|
74
|
-
// expectProxy = Object.assign(expectProxy, expect); // clone new asymmetric matchers
|
|
75
|
-
// };
|
|
76
72
|
return expectProxy;
|
|
77
73
|
}
|
|
78
74
|
globalThis.expect = expectWithGradedBy(globalThis.expect);
|