langsmith 0.2.14-rc.2 → 0.2.14-rc.3
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.cjs +34 -16
- package/dist/jest/index.d.ts +10 -0
- package/dist/jest/index.js +34 -16
- package/dist/jest/matchers.cjs +0 -48
- package/dist/jest/matchers.js +0 -48
- 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.3";
|
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.3";
|
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.3";
|
package/dist/jest/index.cjs
CHANGED
|
@@ -19,6 +19,24 @@ globals_1.expect.extend({
|
|
|
19
19
|
toBeAbsoluteCloseTo: matchers_js_1.toBeAbsoluteCloseTo,
|
|
20
20
|
toBeSemanticCloseTo: matchers_js_1.toBeSemanticCloseTo,
|
|
21
21
|
});
|
|
22
|
+
const objectHash = (obj, depth = 0) => {
|
|
23
|
+
// Prevent infinite recursion
|
|
24
|
+
if (depth > 50) {
|
|
25
|
+
return "[Max Depth Exceeded]";
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(obj)) {
|
|
28
|
+
return obj.map((item) => objectHash(item, depth + 1));
|
|
29
|
+
}
|
|
30
|
+
if (obj && typeof obj === "object") {
|
|
31
|
+
return Object.keys(obj)
|
|
32
|
+
.sort()
|
|
33
|
+
.reduce((result, key) => {
|
|
34
|
+
result[key] = objectHash(obj[key], depth + 1);
|
|
35
|
+
return result;
|
|
36
|
+
}, {});
|
|
37
|
+
}
|
|
38
|
+
return crypto_1.default.createHash("sha256").update(JSON.stringify(obj)).digest("hex");
|
|
39
|
+
};
|
|
22
40
|
async function _createProject(client, datasetId) {
|
|
23
41
|
// Create the project, updating the experimentName until we find a unique one.
|
|
24
42
|
let project;
|
|
@@ -76,14 +94,8 @@ async function runDatasetSetup(testClient, datasetName) {
|
|
|
76
94
|
});
|
|
77
95
|
const examples = [];
|
|
78
96
|
for await (const example of examplesList) {
|
|
79
|
-
const inputHash =
|
|
80
|
-
|
|
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");
|
|
97
|
+
const inputHash = objectHash(example.inputs);
|
|
98
|
+
const outputHash = objectHash(example.outputs ?? {});
|
|
87
99
|
examples.push({ ...example, inputHash, outputHash });
|
|
88
100
|
}
|
|
89
101
|
const project = await _createProject(testClient, dataset.id);
|
|
@@ -124,6 +136,9 @@ const lsDescribe = Object.assign(wrapDescribeMethod(globals_1.describe), {
|
|
|
124
136
|
});
|
|
125
137
|
function wrapTestMethod(method) {
|
|
126
138
|
return function (params, config) {
|
|
139
|
+
// Due to https://github.com/jestjs/jest/issues/13653,
|
|
140
|
+
// we must access the local store value here before
|
|
141
|
+
// entering an async context
|
|
127
142
|
const context = globals_js_1.jestAsyncLocalStorageInstance.getStore();
|
|
128
143
|
// This typing is wrong, but necessary to avoid lint errors
|
|
129
144
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
@@ -140,14 +155,8 @@ function wrapTestMethod(method) {
|
|
|
140
155
|
const { examples, dataset, createdAt, project, client } = await setupPromises.get(context.suiteUuid);
|
|
141
156
|
const testInput = typeof params === "string" ? {} : params.inputs;
|
|
142
157
|
const testOutput = typeof params === "string" ? {} : params.outputs;
|
|
143
|
-
const inputHash =
|
|
144
|
-
|
|
145
|
-
.update(JSON.stringify(testInput))
|
|
146
|
-
.digest("hex");
|
|
147
|
-
const outputHash = crypto_1.default
|
|
148
|
-
.createHash("sha256")
|
|
149
|
-
.update(JSON.stringify(testOutput))
|
|
150
|
-
.digest("hex");
|
|
158
|
+
const inputHash = objectHash(testInput);
|
|
159
|
+
const outputHash = objectHash(testOutput ?? {});
|
|
151
160
|
if ((0, globals_js_1.trackingEnabled)()) {
|
|
152
161
|
const missingFields = [];
|
|
153
162
|
if (examples === undefined) {
|
|
@@ -224,9 +233,18 @@ function wrapTestMethod(method) {
|
|
|
224
233
|
};
|
|
225
234
|
};
|
|
226
235
|
}
|
|
236
|
+
function eachMethod(table) {
|
|
237
|
+
return function (name, fn, timeout) {
|
|
238
|
+
for (let i = 0; i < table.length; i += 1) {
|
|
239
|
+
const example = table[i];
|
|
240
|
+
wrapTestMethod(globals_1.test)(example)(`${name} ${i}`, fn, timeout);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
227
244
|
const lsTest = Object.assign(wrapTestMethod(globals_1.test), {
|
|
228
245
|
only: wrapTestMethod(globals_1.test.only),
|
|
229
246
|
skip: wrapTestMethod(globals_1.test.skip),
|
|
247
|
+
each: eachMethod,
|
|
230
248
|
});
|
|
231
249
|
exports.default = {
|
|
232
250
|
test: lsTest,
|
package/dist/jest/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RunTreeConfig } from "../run_trees.js";
|
|
2
|
+
import { KVMap } from "../schemas.js";
|
|
2
3
|
import expectWithGradedBy from "./vendor/chain.js";
|
|
3
4
|
import type { SimpleEvaluator } from "./vendor/gradedBy.js";
|
|
4
5
|
declare global {
|
|
@@ -25,6 +26,13 @@ export type LangSmithJestTestWrapper<I, O> = (name: string, fn: (params: {
|
|
|
25
26
|
inputs: I;
|
|
26
27
|
outputs: O;
|
|
27
28
|
}) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
29
|
+
declare function eachMethod<I extends KVMap, O extends KVMap>(table: {
|
|
30
|
+
inputs: I;
|
|
31
|
+
outputs: O;
|
|
32
|
+
}[]): (name: string, fn: (params: {
|
|
33
|
+
inputs: I;
|
|
34
|
+
outputs: O;
|
|
35
|
+
}) => unknown | Promise<unknown>, timeout?: number) => void;
|
|
28
36
|
declare const _default: {
|
|
29
37
|
test: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(params: string | {
|
|
30
38
|
inputs: I;
|
|
@@ -38,6 +46,7 @@ declare const _default: {
|
|
|
38
46
|
inputs: I;
|
|
39
47
|
outputs: O;
|
|
40
48
|
}, config?: Partial<RunTreeConfig> | undefined) => LangSmithJestTestWrapper<I, O>;
|
|
49
|
+
each: typeof eachMethod;
|
|
41
50
|
};
|
|
42
51
|
it: (<I extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>>(params: string | {
|
|
43
52
|
inputs: I;
|
|
@@ -51,6 +60,7 @@ declare const _default: {
|
|
|
51
60
|
inputs: I;
|
|
52
61
|
outputs: O;
|
|
53
62
|
}, config?: Partial<RunTreeConfig> | undefined) => LangSmithJestTestWrapper<I, O>;
|
|
63
|
+
each: typeof eachMethod;
|
|
54
64
|
};
|
|
55
65
|
describe: LangSmithJestDescribeWrapper & {
|
|
56
66
|
only: LangSmithJestDescribeWrapper;
|
package/dist/jest/index.js
CHANGED
|
@@ -14,6 +14,24 @@ expect.extend({
|
|
|
14
14
|
toBeAbsoluteCloseTo,
|
|
15
15
|
toBeSemanticCloseTo,
|
|
16
16
|
});
|
|
17
|
+
const objectHash = (obj, depth = 0) => {
|
|
18
|
+
// Prevent infinite recursion
|
|
19
|
+
if (depth > 50) {
|
|
20
|
+
return "[Max Depth Exceeded]";
|
|
21
|
+
}
|
|
22
|
+
if (Array.isArray(obj)) {
|
|
23
|
+
return obj.map((item) => objectHash(item, depth + 1));
|
|
24
|
+
}
|
|
25
|
+
if (obj && typeof obj === "object") {
|
|
26
|
+
return Object.keys(obj)
|
|
27
|
+
.sort()
|
|
28
|
+
.reduce((result, key) => {
|
|
29
|
+
result[key] = objectHash(obj[key], depth + 1);
|
|
30
|
+
return result;
|
|
31
|
+
}, {});
|
|
32
|
+
}
|
|
33
|
+
return crypto.createHash("sha256").update(JSON.stringify(obj)).digest("hex");
|
|
34
|
+
};
|
|
17
35
|
async function _createProject(client, datasetId) {
|
|
18
36
|
// Create the project, updating the experimentName until we find a unique one.
|
|
19
37
|
let project;
|
|
@@ -71,14 +89,8 @@ async function runDatasetSetup(testClient, datasetName) {
|
|
|
71
89
|
});
|
|
72
90
|
const examples = [];
|
|
73
91
|
for await (const example of examplesList) {
|
|
74
|
-
const inputHash =
|
|
75
|
-
|
|
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");
|
|
92
|
+
const inputHash = objectHash(example.inputs);
|
|
93
|
+
const outputHash = objectHash(example.outputs ?? {});
|
|
82
94
|
examples.push({ ...example, inputHash, outputHash });
|
|
83
95
|
}
|
|
84
96
|
const project = await _createProject(testClient, dataset.id);
|
|
@@ -119,6 +131,9 @@ const lsDescribe = Object.assign(wrapDescribeMethod(describe), {
|
|
|
119
131
|
});
|
|
120
132
|
function wrapTestMethod(method) {
|
|
121
133
|
return function (params, config) {
|
|
134
|
+
// Due to https://github.com/jestjs/jest/issues/13653,
|
|
135
|
+
// we must access the local store value here before
|
|
136
|
+
// entering an async context
|
|
122
137
|
const context = jestAsyncLocalStorageInstance.getStore();
|
|
123
138
|
// This typing is wrong, but necessary to avoid lint errors
|
|
124
139
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
@@ -135,14 +150,8 @@ function wrapTestMethod(method) {
|
|
|
135
150
|
const { examples, dataset, createdAt, project, client } = await setupPromises.get(context.suiteUuid);
|
|
136
151
|
const testInput = typeof params === "string" ? {} : params.inputs;
|
|
137
152
|
const testOutput = typeof params === "string" ? {} : params.outputs;
|
|
138
|
-
const inputHash =
|
|
139
|
-
|
|
140
|
-
.update(JSON.stringify(testInput))
|
|
141
|
-
.digest("hex");
|
|
142
|
-
const outputHash = crypto
|
|
143
|
-
.createHash("sha256")
|
|
144
|
-
.update(JSON.stringify(testOutput))
|
|
145
|
-
.digest("hex");
|
|
153
|
+
const inputHash = objectHash(testInput);
|
|
154
|
+
const outputHash = objectHash(testOutput ?? {});
|
|
146
155
|
if (trackingEnabled()) {
|
|
147
156
|
const missingFields = [];
|
|
148
157
|
if (examples === undefined) {
|
|
@@ -219,9 +228,18 @@ function wrapTestMethod(method) {
|
|
|
219
228
|
};
|
|
220
229
|
};
|
|
221
230
|
}
|
|
231
|
+
function eachMethod(table) {
|
|
232
|
+
return function (name, fn, timeout) {
|
|
233
|
+
for (let i = 0; i < table.length; i += 1) {
|
|
234
|
+
const example = table[i];
|
|
235
|
+
wrapTestMethod(test)(example)(`${name} ${i}`, fn, timeout);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
222
239
|
const lsTest = Object.assign(wrapTestMethod(test), {
|
|
223
240
|
only: wrapTestMethod(test.only),
|
|
224
241
|
skip: wrapTestMethod(test.skip),
|
|
242
|
+
each: eachMethod,
|
|
225
243
|
});
|
|
226
244
|
export default {
|
|
227
245
|
test: lsTest,
|
package/dist/jest/matchers.cjs
CHANGED
|
@@ -99,51 +99,3 @@ async function toBeSemanticCloseTo(received, expected, options) {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
exports.toBeSemanticCloseTo = toBeSemanticCloseTo;
|
|
102
|
-
// export async function toPassEvaluator(
|
|
103
|
-
// this: MatcherContext,
|
|
104
|
-
// actual: KVMap,
|
|
105
|
-
// evaluator: SimpleEvaluator,
|
|
106
|
-
// _expected?: KVMap
|
|
107
|
-
// ) {
|
|
108
|
-
// const runTree = getCurrentRunTree();
|
|
109
|
-
// const context = localStorage.getStore();
|
|
110
|
-
// if (context === undefined || context.currentExample === undefined) {
|
|
111
|
-
// throw new Error(
|
|
112
|
-
// `Could not identify example context from current context.\nPlease ensure you are calling this matcher within "ls.test()"`
|
|
113
|
-
// );
|
|
114
|
-
// }
|
|
115
|
-
// const wrappedEvaluator = traceable(evaluator, {
|
|
116
|
-
// reference_example_id: context.currentExample.id,
|
|
117
|
-
// metadata: {
|
|
118
|
-
// example_version: context.currentExample.modified_at
|
|
119
|
-
// ? new Date(context.currentExample.modified_at).toISOString()
|
|
120
|
-
// : new Date(context.currentExample.created_at).toISOString(),
|
|
121
|
-
// },
|
|
122
|
-
// client: context.client,
|
|
123
|
-
// tracingEnabled: true,
|
|
124
|
-
// });
|
|
125
|
-
// const evalResult = await wrappedEvaluator({
|
|
126
|
-
// input: runTree.inputs,
|
|
127
|
-
// expected: context.currentExample.outputs ?? {},
|
|
128
|
-
// actual,
|
|
129
|
-
// });
|
|
130
|
-
// await context.client.logEvaluationFeedback(evalResult, runTree);
|
|
131
|
-
// if (!("results" in evalResult) && !evalResult.score) {
|
|
132
|
-
// return {
|
|
133
|
-
// pass: false,
|
|
134
|
-
// message: () =>
|
|
135
|
-
// `expected ${this.utils.printReceived(
|
|
136
|
-
// actual
|
|
137
|
-
// )} to pass evaluator. Failed with ${JSON.stringify(
|
|
138
|
-
// evalResult,
|
|
139
|
-
// null,
|
|
140
|
-
// 2
|
|
141
|
-
// )}`,
|
|
142
|
-
// };
|
|
143
|
-
// }
|
|
144
|
-
// return {
|
|
145
|
-
// pass: true,
|
|
146
|
-
// message: () =>
|
|
147
|
-
// `evaluator passed with score ${JSON.stringify(evalResult, null, 2)}`,
|
|
148
|
-
// };
|
|
149
|
-
// }
|
package/dist/jest/matchers.js
CHANGED
|
@@ -93,51 +93,3 @@ export async function toBeSemanticCloseTo(received, expected, options) {
|
|
|
93
93
|
: `Expected "${received}" to be semantically close to "${expected}" (threshold: ${threshold}, similarity: ${similarity})`,
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
|
-
// export async function toPassEvaluator(
|
|
97
|
-
// this: MatcherContext,
|
|
98
|
-
// actual: KVMap,
|
|
99
|
-
// evaluator: SimpleEvaluator,
|
|
100
|
-
// _expected?: KVMap
|
|
101
|
-
// ) {
|
|
102
|
-
// const runTree = getCurrentRunTree();
|
|
103
|
-
// const context = localStorage.getStore();
|
|
104
|
-
// if (context === undefined || context.currentExample === undefined) {
|
|
105
|
-
// throw new Error(
|
|
106
|
-
// `Could not identify example context from current context.\nPlease ensure you are calling this matcher within "ls.test()"`
|
|
107
|
-
// );
|
|
108
|
-
// }
|
|
109
|
-
// const wrappedEvaluator = traceable(evaluator, {
|
|
110
|
-
// reference_example_id: context.currentExample.id,
|
|
111
|
-
// metadata: {
|
|
112
|
-
// example_version: context.currentExample.modified_at
|
|
113
|
-
// ? new Date(context.currentExample.modified_at).toISOString()
|
|
114
|
-
// : new Date(context.currentExample.created_at).toISOString(),
|
|
115
|
-
// },
|
|
116
|
-
// client: context.client,
|
|
117
|
-
// tracingEnabled: true,
|
|
118
|
-
// });
|
|
119
|
-
// const evalResult = await wrappedEvaluator({
|
|
120
|
-
// input: runTree.inputs,
|
|
121
|
-
// expected: context.currentExample.outputs ?? {},
|
|
122
|
-
// actual,
|
|
123
|
-
// });
|
|
124
|
-
// await context.client.logEvaluationFeedback(evalResult, runTree);
|
|
125
|
-
// if (!("results" in evalResult) && !evalResult.score) {
|
|
126
|
-
// return {
|
|
127
|
-
// pass: false,
|
|
128
|
-
// message: () =>
|
|
129
|
-
// `expected ${this.utils.printReceived(
|
|
130
|
-
// actual
|
|
131
|
-
// )} to pass evaluator. Failed with ${JSON.stringify(
|
|
132
|
-
// evalResult,
|
|
133
|
-
// null,
|
|
134
|
-
// 2
|
|
135
|
-
// )}`,
|
|
136
|
-
// };
|
|
137
|
-
// }
|
|
138
|
-
// return {
|
|
139
|
-
// pass: true,
|
|
140
|
-
// message: () =>
|
|
141
|
-
// `evaluator passed with score ${JSON.stringify(evalResult, null, 2)}`,
|
|
142
|
-
// };
|
|
143
|
-
// }
|