langsmith 0.1.20 → 0.1.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/client.cjs CHANGED
@@ -148,7 +148,7 @@ class Queue {
148
148
  }
149
149
  exports.Queue = Queue;
150
150
  // 20 MB
151
- exports.DEFAULT_BATCH_SIZE_LIMIT_BYTES = 20971520;
151
+ exports.DEFAULT_BATCH_SIZE_LIMIT_BYTES = 20_971_520;
152
152
  class Client {
153
153
  constructor(config = {}) {
154
154
  Object.defineProperty(this, "apiKey", {
@@ -276,7 +276,7 @@ class Client {
276
276
  this.apiUrl = trimQuotes(config.apiUrl ?? defaultConfig.apiUrl) ?? "";
277
277
  this.apiKey = trimQuotes(config.apiKey ?? defaultConfig.apiKey);
278
278
  this.webUrl = trimQuotes(config.webUrl ?? defaultConfig.webUrl);
279
- this.timeout_ms = config.timeout_ms ?? 12000;
279
+ this.timeout_ms = config.timeout_ms ?? 12_000;
280
280
  this.caller = new async_caller_js_1.AsyncCaller(config.callerOptions ?? {});
281
281
  this.batchIngestCaller = new async_caller_js_1.AsyncCaller({
282
282
  ...(config.callerOptions ?? {}),
package/dist/client.js CHANGED
@@ -121,7 +121,7 @@ export class Queue {
121
121
  }
122
122
  }
123
123
  // 20 MB
124
- export const DEFAULT_BATCH_SIZE_LIMIT_BYTES = 20971520;
124
+ export const DEFAULT_BATCH_SIZE_LIMIT_BYTES = 20_971_520;
125
125
  export class Client {
126
126
  constructor(config = {}) {
127
127
  Object.defineProperty(this, "apiKey", {
@@ -249,7 +249,7 @@ export class Client {
249
249
  this.apiUrl = trimQuotes(config.apiUrl ?? defaultConfig.apiUrl) ?? "";
250
250
  this.apiKey = trimQuotes(config.apiKey ?? defaultConfig.apiKey);
251
251
  this.webUrl = trimQuotes(config.webUrl ?? defaultConfig.webUrl);
252
- this.timeout_ms = config.timeout_ms ?? 12000;
252
+ this.timeout_ms = config.timeout_ms ?? 12_000;
253
253
  this.caller = new AsyncCaller(config.callerOptions ?? {});
254
254
  this.batchIngestCaller = new AsyncCaller({
255
255
  ...(config.callerOptions ?? {}),
package/dist/index.cjs CHANGED
@@ -6,4 +6,4 @@ Object.defineProperty(exports, "Client", { enumerable: true, get: function () {
6
6
  var run_trees_js_1 = require("./run_trees.cjs");
7
7
  Object.defineProperty(exports, "RunTree", { enumerable: true, get: function () { return run_trees_js_1.RunTree; } });
8
8
  // Update using yarn bump-version
9
- exports.__version__ = "0.1.20";
9
+ exports.__version__ = "0.1.21";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Client } from "./client.js";
2
2
  export type { Dataset, Example, TracerSession, Run, Feedback, } from "./schemas.js";
3
3
  export { RunTree, type RunTreeConfig } from "./run_trees.js";
4
- export declare const __version__ = "0.1.20";
4
+ export declare const __version__ = "0.1.21";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Client } from "./client.js";
2
2
  export { RunTree } from "./run_trees.js";
3
3
  // Update using yarn bump-version
4
- export const __version__ = "0.1.20";
4
+ export const __version__ = "0.1.21";
@@ -232,7 +232,7 @@ class RunTree {
232
232
  extra: {},
233
233
  };
234
234
  }
235
- async createChild(config) {
235
+ createChild(config) {
236
236
  const child = new RunTree({
237
237
  ...config,
238
238
  parent_run: this,
@@ -243,9 +243,9 @@ class RunTree {
243
243
  return child;
244
244
  }
245
245
  async end(outputs, error, endTime = Date.now()) {
246
- this.outputs = outputs;
247
- this.error = error;
248
- this.end_time = endTime;
246
+ this.outputs = this.outputs ?? outputs;
247
+ this.error = this.error ?? error;
248
+ this.end_time = this.end_time ?? endTime;
249
249
  }
250
250
  async _convertToCreate(run, excludeChildRuns = true) {
251
251
  const runExtra = run.extra ?? {};
@@ -65,7 +65,7 @@ export declare class RunTree implements BaseRun {
65
65
  metadata?: KVMap;
66
66
  }): RunTree;
67
67
  private static getDefaultConfig;
68
- createChild(config: RunTreeConfig): Promise<RunTree>;
68
+ createChild(config: RunTreeConfig): RunTree;
69
69
  end(outputs?: KVMap, error?: string, endTime?: number): Promise<void>;
70
70
  private _convertToCreate;
71
71
  postRun(excludeChildRuns?: boolean): Promise<void>;
package/dist/run_trees.js CHANGED
@@ -205,7 +205,7 @@ export class RunTree {
205
205
  extra: {},
206
206
  };
207
207
  }
208
- async createChild(config) {
208
+ createChild(config) {
209
209
  const child = new RunTree({
210
210
  ...config,
211
211
  parent_run: this,
@@ -216,9 +216,9 @@ export class RunTree {
216
216
  return child;
217
217
  }
218
218
  async end(outputs, error, endTime = Date.now()) {
219
- this.outputs = outputs;
220
- this.error = error;
221
- this.end_time = endTime;
219
+ this.outputs = this.outputs ?? outputs;
220
+ this.error = this.error ?? error;
221
+ this.end_time = this.end_time ?? endTime;
222
222
  }
223
223
  async _convertToCreate(run, excludeChildRuns = true) {
224
224
  const runExtra = run.extra ?? {};
@@ -4,6 +4,12 @@ exports.isTraceableFunction = exports.getCurrentRunTree = exports.traceable = vo
4
4
  const async_hooks_1 = require("async_hooks");
5
5
  const run_trees_js_1 = require("./run_trees.cjs");
6
6
  const env_js_1 = require("./utils/env.cjs");
7
+ function isPromiseMethod(x) {
8
+ if (x === "then" || x === "catch" || x === "finally") {
9
+ return true;
10
+ }
11
+ return false;
12
+ }
7
13
  const asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
8
14
  const isAsyncIterable = (x) => x != null &&
9
15
  typeof x === "object" &&
@@ -33,14 +39,55 @@ const getTracingRunTree = (runTree) => {
33
39
  */
34
40
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
41
  function traceable(wrappedFunc, config) {
36
- const { aggregator, ...runTreeConfig } = config ?? {};
37
- const traceableFunc = async (...args) => {
42
+ const { aggregator, argsConfigPath, ...runTreeConfig } = config ?? {};
43
+ const traceableFunc = (...args) => {
38
44
  let currentRunTree;
39
45
  let rawInputs;
40
- const ensuredConfig = {
41
- name: wrappedFunc.name || "<lambda>",
42
- ...runTreeConfig,
43
- };
46
+ let ensuredConfig;
47
+ try {
48
+ let runtimeConfig;
49
+ if (argsConfigPath) {
50
+ const [index, path] = argsConfigPath;
51
+ if (index === args.length - 1 && !path) {
52
+ runtimeConfig = args.pop();
53
+ }
54
+ else if (index <= args.length &&
55
+ typeof args[index] === "object" &&
56
+ args[index] !== null) {
57
+ if (path) {
58
+ const { [path]: extracted, ...rest } = args[index];
59
+ runtimeConfig = extracted;
60
+ args[index] = rest;
61
+ }
62
+ else {
63
+ runtimeConfig = args[index];
64
+ args.splice(index, 1);
65
+ }
66
+ }
67
+ }
68
+ ensuredConfig = {
69
+ name: wrappedFunc.name || "<lambda>",
70
+ ...runTreeConfig,
71
+ ...runtimeConfig,
72
+ tags: [
73
+ ...new Set([
74
+ ...(runTreeConfig?.tags ?? []),
75
+ ...(runtimeConfig?.tags ?? []),
76
+ ]),
77
+ ],
78
+ metadata: {
79
+ ...runTreeConfig?.metadata,
80
+ ...runtimeConfig?.metadata,
81
+ },
82
+ };
83
+ }
84
+ catch (err) {
85
+ console.warn(`Failed to extract runtime config from args for ${runTreeConfig?.name ?? wrappedFunc.name}`, err);
86
+ ensuredConfig = {
87
+ name: wrappedFunc.name || "<lambda>",
88
+ ...runTreeConfig,
89
+ };
90
+ }
44
91
  const previousRunTree = asyncLocalStorage.getStore();
45
92
  if ((0, run_trees_js_1.isRunTree)(args[0])) {
46
93
  currentRunTree = args[0];
@@ -51,7 +98,7 @@ function traceable(wrappedFunc, config) {
51
98
  rawInputs = args.slice(1);
52
99
  }
53
100
  else if (previousRunTree !== undefined) {
54
- currentRunTree = await previousRunTree.createChild(ensuredConfig);
101
+ currentRunTree = previousRunTree.createChild(ensuredConfig);
55
102
  rawInputs = args;
56
103
  }
57
104
  else {
@@ -76,74 +123,145 @@ function traceable(wrappedFunc, config) {
76
123
  if (currentRunTree) {
77
124
  currentRunTree.inputs = inputs;
78
125
  }
79
- const initialOutputs = currentRunTree?.outputs;
80
- const initialError = currentRunTree?.error;
81
- await currentRunTree?.postRun();
82
- return new Promise((resolve, reject) => {
83
- void asyncLocalStorage.run(currentRunTree, async () => {
84
- try {
85
- const rawOutput = await wrappedFunc(...rawInputs);
126
+ return asyncLocalStorage.run(currentRunTree, () => {
127
+ const postRunPromise = currentRunTree?.postRun();
128
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
+ let returnValue;
130
+ try {
131
+ returnValue = wrappedFunc(...rawInputs);
132
+ }
133
+ catch (err) {
134
+ returnValue = Promise.reject(err);
135
+ }
136
+ if (isAsyncIterable(returnValue)) {
137
+ // eslint-disable-next-line no-inner-declarations
138
+ async function* wrapOutputForTracing() {
139
+ let finished = false;
140
+ const chunks = [];
141
+ try {
142
+ for await (const chunk of returnValue) {
143
+ chunks.push(chunk);
144
+ yield chunk;
145
+ }
146
+ finished = true;
147
+ }
148
+ catch (e) {
149
+ await currentRunTree?.end(undefined, String(e));
150
+ throw e;
151
+ }
152
+ finally {
153
+ if (!finished) {
154
+ await currentRunTree?.end(undefined, "Cancelled");
155
+ }
156
+ let finalOutputs;
157
+ if (aggregator !== undefined) {
158
+ try {
159
+ finalOutputs = await aggregator(chunks);
160
+ }
161
+ catch (e) {
162
+ console.error(`[ERROR]: LangSmith aggregation failed: `, e);
163
+ finalOutputs = chunks;
164
+ }
165
+ }
166
+ else {
167
+ finalOutputs = chunks;
168
+ }
169
+ if (typeof finalOutputs === "object" &&
170
+ !Array.isArray(finalOutputs)) {
171
+ await currentRunTree?.end(finalOutputs);
172
+ }
173
+ else {
174
+ await currentRunTree?.end({ outputs: finalOutputs });
175
+ }
176
+ await postRunPromise;
177
+ await currentRunTree?.patchRun();
178
+ }
179
+ }
180
+ return wrapOutputForTracing();
181
+ }
182
+ const tracedPromise = new Promise((resolve, reject) => {
183
+ Promise.resolve(returnValue)
184
+ .then(
185
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
186
+ async (rawOutput) => {
86
187
  if (isAsyncIterable(rawOutput)) {
87
188
  // eslint-disable-next-line no-inner-declarations
88
189
  async function* wrapOutputForTracing() {
190
+ let finished = false;
89
191
  const chunks = [];
90
- // TypeScript thinks this is unsafe
91
- for await (const chunk of rawOutput) {
92
- chunks.push(chunk);
93
- yield chunk;
192
+ try {
193
+ // TypeScript thinks this is unsafe
194
+ for await (const chunk of rawOutput) {
195
+ chunks.push(chunk);
196
+ yield chunk;
197
+ }
198
+ finished = true;
199
+ }
200
+ catch (e) {
201
+ await currentRunTree?.end(undefined, String(e));
202
+ throw e;
94
203
  }
95
- let finalOutputs;
96
- if (aggregator !== undefined) {
97
- try {
98
- finalOutputs = await aggregator(chunks);
204
+ finally {
205
+ if (!finished) {
206
+ await currentRunTree?.end(undefined, "Cancelled");
99
207
  }
100
- catch (e) {
101
- console.error(`[ERROR]: LangSmith aggregation failed: `, e);
208
+ let finalOutputs;
209
+ if (aggregator !== undefined) {
210
+ try {
211
+ finalOutputs = await aggregator(chunks);
212
+ }
213
+ catch (e) {
214
+ console.error(`[ERROR]: LangSmith aggregation failed: `, e);
215
+ finalOutputs = chunks;
216
+ }
217
+ }
218
+ else {
102
219
  finalOutputs = chunks;
103
220
  }
221
+ if (typeof finalOutputs === "object" &&
222
+ !Array.isArray(finalOutputs)) {
223
+ await currentRunTree?.end(finalOutputs);
224
+ }
225
+ else {
226
+ await currentRunTree?.end({ outputs: finalOutputs });
227
+ }
228
+ await postRunPromise;
229
+ await currentRunTree?.patchRun();
104
230
  }
105
- else {
106
- finalOutputs = chunks;
107
- }
108
- if (typeof finalOutputs === "object" &&
109
- !Array.isArray(finalOutputs)) {
110
- await currentRunTree?.end(finalOutputs);
111
- }
112
- else {
113
- await currentRunTree?.end({ outputs: finalOutputs });
114
- }
115
- await currentRunTree?.patchRun();
116
231
  }
117
232
  return resolve(wrapOutputForTracing());
118
233
  }
119
234
  else {
120
- const outputs = isKVMap(rawOutput)
121
- ? rawOutput
122
- : { outputs: rawOutput };
123
- if (initialOutputs === currentRunTree?.outputs) {
124
- await currentRunTree?.end(outputs);
125
- }
126
- else {
127
- if (currentRunTree !== undefined) {
128
- currentRunTree.end_time = Date.now();
129
- }
235
+ try {
236
+ await currentRunTree?.end(isKVMap(rawOutput) ? rawOutput : { outputs: rawOutput });
237
+ await postRunPromise;
238
+ await currentRunTree?.patchRun();
130
239
  }
131
- await currentRunTree?.patchRun();
132
- return resolve(rawOutput);
133
- }
134
- }
135
- catch (error) {
136
- if (initialError === currentRunTree?.error) {
137
- await currentRunTree?.end(initialOutputs, String(error));
138
- }
139
- else {
140
- if (currentRunTree !== undefined) {
141
- currentRunTree.end_time = Date.now();
240
+ finally {
241
+ // eslint-disable-next-line no-unsafe-finally
242
+ return rawOutput;
142
243
  }
143
244
  }
245
+ },
246
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
247
+ async (error) => {
248
+ await currentRunTree?.end(undefined, String(error));
249
+ await postRunPromise;
144
250
  await currentRunTree?.patchRun();
145
- reject(error);
146
- }
251
+ throw error;
252
+ })
253
+ .then(resolve, reject);
254
+ });
255
+ if (typeof returnValue !== "object" || returnValue === null) {
256
+ return tracedPromise;
257
+ }
258
+ return new Proxy(returnValue, {
259
+ get(target, prop, receiver) {
260
+ if (isPromiseMethod(prop)) {
261
+ return tracedPromise[prop].bind(tracedPromise);
262
+ }
263
+ return Reflect.get(target, prop, receiver);
264
+ },
147
265
  });
148
266
  });
149
267
  };
@@ -1,12 +1,13 @@
1
1
  import { RunTree, RunTreeConfig, RunnableConfigLike } from "./run_trees.js";
2
2
  export type RunTreeLike = RunTree;
3
+ type SmartPromise<T> = T extends AsyncGenerator ? T : T extends Promise<unknown> ? T : Promise<T>;
3
4
  type WrapArgReturnPair<Pair> = Pair extends [
4
5
  infer Args extends any[],
5
6
  infer Return
6
7
  ] ? {
7
- (...args: Args): Promise<Return>;
8
- (...args: [runTree: RunTreeLike, ...rest: Args]): Promise<Return>;
9
- (...args: [config: RunnableConfigLike, ...rest: Args]): Promise<Return>;
8
+ (...args: Args): SmartPromise<Return>;
9
+ (...args: [runTree: RunTreeLike, ...rest: Args]): SmartPromise<Return>;
10
+ (...args: [config: RunnableConfigLike, ...rest: Args]): SmartPromise<Return>;
10
11
  } : never;
11
12
  type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
12
13
  export type TraceableFunction<Func extends (...args: any[]) => any> = Func extends {
@@ -46,6 +47,7 @@ export type TraceableFunction<Func extends (...args: any[]) => any> = Func exten
46
47
  */
47
48
  export declare function traceable<Func extends (...args: any[]) => any>(wrappedFunc: Func, config?: Partial<RunTreeConfig> & {
48
49
  aggregator?: (args: any[]) => any;
50
+ argsConfigPath?: [number] | [number, string];
49
51
  }): TraceableFunction<Func>;
50
52
  /**
51
53
  * Return the current run tree from within a traceable-wrapped function.
package/dist/traceable.js CHANGED
@@ -1,6 +1,12 @@
1
1
  import { AsyncLocalStorage } from "async_hooks";
2
2
  import { RunTree, isRunTree, isRunnableConfigLike, } from "./run_trees.js";
3
3
  import { getEnvironmentVariable } from "./utils/env.js";
4
+ function isPromiseMethod(x) {
5
+ if (x === "then" || x === "catch" || x === "finally") {
6
+ return true;
7
+ }
8
+ return false;
9
+ }
4
10
  const asyncLocalStorage = new AsyncLocalStorage();
5
11
  const isAsyncIterable = (x) => x != null &&
6
12
  typeof x === "object" &&
@@ -30,14 +36,55 @@ const getTracingRunTree = (runTree) => {
30
36
  */
31
37
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
38
  export function traceable(wrappedFunc, config) {
33
- const { aggregator, ...runTreeConfig } = config ?? {};
34
- const traceableFunc = async (...args) => {
39
+ const { aggregator, argsConfigPath, ...runTreeConfig } = config ?? {};
40
+ const traceableFunc = (...args) => {
35
41
  let currentRunTree;
36
42
  let rawInputs;
37
- const ensuredConfig = {
38
- name: wrappedFunc.name || "<lambda>",
39
- ...runTreeConfig,
40
- };
43
+ let ensuredConfig;
44
+ try {
45
+ let runtimeConfig;
46
+ if (argsConfigPath) {
47
+ const [index, path] = argsConfigPath;
48
+ if (index === args.length - 1 && !path) {
49
+ runtimeConfig = args.pop();
50
+ }
51
+ else if (index <= args.length &&
52
+ typeof args[index] === "object" &&
53
+ args[index] !== null) {
54
+ if (path) {
55
+ const { [path]: extracted, ...rest } = args[index];
56
+ runtimeConfig = extracted;
57
+ args[index] = rest;
58
+ }
59
+ else {
60
+ runtimeConfig = args[index];
61
+ args.splice(index, 1);
62
+ }
63
+ }
64
+ }
65
+ ensuredConfig = {
66
+ name: wrappedFunc.name || "<lambda>",
67
+ ...runTreeConfig,
68
+ ...runtimeConfig,
69
+ tags: [
70
+ ...new Set([
71
+ ...(runTreeConfig?.tags ?? []),
72
+ ...(runtimeConfig?.tags ?? []),
73
+ ]),
74
+ ],
75
+ metadata: {
76
+ ...runTreeConfig?.metadata,
77
+ ...runtimeConfig?.metadata,
78
+ },
79
+ };
80
+ }
81
+ catch (err) {
82
+ console.warn(`Failed to extract runtime config from args for ${runTreeConfig?.name ?? wrappedFunc.name}`, err);
83
+ ensuredConfig = {
84
+ name: wrappedFunc.name || "<lambda>",
85
+ ...runTreeConfig,
86
+ };
87
+ }
41
88
  const previousRunTree = asyncLocalStorage.getStore();
42
89
  if (isRunTree(args[0])) {
43
90
  currentRunTree = args[0];
@@ -48,7 +95,7 @@ export function traceable(wrappedFunc, config) {
48
95
  rawInputs = args.slice(1);
49
96
  }
50
97
  else if (previousRunTree !== undefined) {
51
- currentRunTree = await previousRunTree.createChild(ensuredConfig);
98
+ currentRunTree = previousRunTree.createChild(ensuredConfig);
52
99
  rawInputs = args;
53
100
  }
54
101
  else {
@@ -73,74 +120,145 @@ export function traceable(wrappedFunc, config) {
73
120
  if (currentRunTree) {
74
121
  currentRunTree.inputs = inputs;
75
122
  }
76
- const initialOutputs = currentRunTree?.outputs;
77
- const initialError = currentRunTree?.error;
78
- await currentRunTree?.postRun();
79
- return new Promise((resolve, reject) => {
80
- void asyncLocalStorage.run(currentRunTree, async () => {
81
- try {
82
- const rawOutput = await wrappedFunc(...rawInputs);
123
+ return asyncLocalStorage.run(currentRunTree, () => {
124
+ const postRunPromise = currentRunTree?.postRun();
125
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
+ let returnValue;
127
+ try {
128
+ returnValue = wrappedFunc(...rawInputs);
129
+ }
130
+ catch (err) {
131
+ returnValue = Promise.reject(err);
132
+ }
133
+ if (isAsyncIterable(returnValue)) {
134
+ // eslint-disable-next-line no-inner-declarations
135
+ async function* wrapOutputForTracing() {
136
+ let finished = false;
137
+ const chunks = [];
138
+ try {
139
+ for await (const chunk of returnValue) {
140
+ chunks.push(chunk);
141
+ yield chunk;
142
+ }
143
+ finished = true;
144
+ }
145
+ catch (e) {
146
+ await currentRunTree?.end(undefined, String(e));
147
+ throw e;
148
+ }
149
+ finally {
150
+ if (!finished) {
151
+ await currentRunTree?.end(undefined, "Cancelled");
152
+ }
153
+ let finalOutputs;
154
+ if (aggregator !== undefined) {
155
+ try {
156
+ finalOutputs = await aggregator(chunks);
157
+ }
158
+ catch (e) {
159
+ console.error(`[ERROR]: LangSmith aggregation failed: `, e);
160
+ finalOutputs = chunks;
161
+ }
162
+ }
163
+ else {
164
+ finalOutputs = chunks;
165
+ }
166
+ if (typeof finalOutputs === "object" &&
167
+ !Array.isArray(finalOutputs)) {
168
+ await currentRunTree?.end(finalOutputs);
169
+ }
170
+ else {
171
+ await currentRunTree?.end({ outputs: finalOutputs });
172
+ }
173
+ await postRunPromise;
174
+ await currentRunTree?.patchRun();
175
+ }
176
+ }
177
+ return wrapOutputForTracing();
178
+ }
179
+ const tracedPromise = new Promise((resolve, reject) => {
180
+ Promise.resolve(returnValue)
181
+ .then(
182
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
+ async (rawOutput) => {
83
184
  if (isAsyncIterable(rawOutput)) {
84
185
  // eslint-disable-next-line no-inner-declarations
85
186
  async function* wrapOutputForTracing() {
187
+ let finished = false;
86
188
  const chunks = [];
87
- // TypeScript thinks this is unsafe
88
- for await (const chunk of rawOutput) {
89
- chunks.push(chunk);
90
- yield chunk;
189
+ try {
190
+ // TypeScript thinks this is unsafe
191
+ for await (const chunk of rawOutput) {
192
+ chunks.push(chunk);
193
+ yield chunk;
194
+ }
195
+ finished = true;
196
+ }
197
+ catch (e) {
198
+ await currentRunTree?.end(undefined, String(e));
199
+ throw e;
91
200
  }
92
- let finalOutputs;
93
- if (aggregator !== undefined) {
94
- try {
95
- finalOutputs = await aggregator(chunks);
201
+ finally {
202
+ if (!finished) {
203
+ await currentRunTree?.end(undefined, "Cancelled");
96
204
  }
97
- catch (e) {
98
- console.error(`[ERROR]: LangSmith aggregation failed: `, e);
205
+ let finalOutputs;
206
+ if (aggregator !== undefined) {
207
+ try {
208
+ finalOutputs = await aggregator(chunks);
209
+ }
210
+ catch (e) {
211
+ console.error(`[ERROR]: LangSmith aggregation failed: `, e);
212
+ finalOutputs = chunks;
213
+ }
214
+ }
215
+ else {
99
216
  finalOutputs = chunks;
100
217
  }
218
+ if (typeof finalOutputs === "object" &&
219
+ !Array.isArray(finalOutputs)) {
220
+ await currentRunTree?.end(finalOutputs);
221
+ }
222
+ else {
223
+ await currentRunTree?.end({ outputs: finalOutputs });
224
+ }
225
+ await postRunPromise;
226
+ await currentRunTree?.patchRun();
101
227
  }
102
- else {
103
- finalOutputs = chunks;
104
- }
105
- if (typeof finalOutputs === "object" &&
106
- !Array.isArray(finalOutputs)) {
107
- await currentRunTree?.end(finalOutputs);
108
- }
109
- else {
110
- await currentRunTree?.end({ outputs: finalOutputs });
111
- }
112
- await currentRunTree?.patchRun();
113
228
  }
114
229
  return resolve(wrapOutputForTracing());
115
230
  }
116
231
  else {
117
- const outputs = isKVMap(rawOutput)
118
- ? rawOutput
119
- : { outputs: rawOutput };
120
- if (initialOutputs === currentRunTree?.outputs) {
121
- await currentRunTree?.end(outputs);
122
- }
123
- else {
124
- if (currentRunTree !== undefined) {
125
- currentRunTree.end_time = Date.now();
126
- }
232
+ try {
233
+ await currentRunTree?.end(isKVMap(rawOutput) ? rawOutput : { outputs: rawOutput });
234
+ await postRunPromise;
235
+ await currentRunTree?.patchRun();
127
236
  }
128
- await currentRunTree?.patchRun();
129
- return resolve(rawOutput);
130
- }
131
- }
132
- catch (error) {
133
- if (initialError === currentRunTree?.error) {
134
- await currentRunTree?.end(initialOutputs, String(error));
135
- }
136
- else {
137
- if (currentRunTree !== undefined) {
138
- currentRunTree.end_time = Date.now();
237
+ finally {
238
+ // eslint-disable-next-line no-unsafe-finally
239
+ return rawOutput;
139
240
  }
140
241
  }
242
+ },
243
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
244
+ async (error) => {
245
+ await currentRunTree?.end(undefined, String(error));
246
+ await postRunPromise;
141
247
  await currentRunTree?.patchRun();
142
- reject(error);
143
- }
248
+ throw error;
249
+ })
250
+ .then(resolve, reject);
251
+ });
252
+ if (typeof returnValue !== "object" || returnValue === null) {
253
+ return tracedPromise;
254
+ }
255
+ return new Proxy(returnValue, {
256
+ get(target, prop, receiver) {
257
+ if (isPromiseMethod(prop)) {
258
+ return tracedPromise[prop].bind(tracedPromise);
259
+ }
260
+ return Reflect.get(target, prop, receiver);
261
+ },
144
262
  });
145
263
  });
146
264
  };
@@ -7,13 +7,13 @@ exports.AsyncCaller = void 0;
7
7
  const p_retry_1 = __importDefault(require("p-retry"));
8
8
  const p_queue_1 = __importDefault(require("p-queue"));
9
9
  const STATUS_NO_RETRY = [
10
- 400,
11
- 401,
12
- 403,
13
- 404,
14
- 405,
15
- 406,
16
- 407,
10
+ 400, // Bad Request
11
+ 401, // Unauthorized
12
+ 403, // Forbidden
13
+ 404, // Not Found
14
+ 405, // Method Not Allowed
15
+ 406, // Not Acceptable
16
+ 407, // Proxy Authentication Required
17
17
  408, // Request Timeout
18
18
  ];
19
19
  const STATUS_IGNORE = [
@@ -60,8 +60,16 @@ class AsyncCaller {
60
60
  });
61
61
  this.maxConcurrency = params.maxConcurrency ?? Infinity;
62
62
  this.maxRetries = params.maxRetries ?? 6;
63
- const PQueue = "default" in p_queue_1.default ? p_queue_1.default.default : p_queue_1.default;
64
- this.queue = new PQueue({ concurrency: this.maxConcurrency });
63
+ if ("default" in p_queue_1.default) {
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ this.queue = new p_queue_1.default.default({
66
+ concurrency: this.maxConcurrency,
67
+ });
68
+ }
69
+ else {
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ this.queue = new p_queue_1.default({ concurrency: this.maxConcurrency });
72
+ }
65
73
  this.onFailedResponseHook = params?.onFailedResponseHook;
66
74
  }
67
75
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1,13 +1,13 @@
1
1
  import pRetry from "p-retry";
2
2
  import PQueueMod from "p-queue";
3
3
  const STATUS_NO_RETRY = [
4
- 400,
5
- 401,
6
- 403,
7
- 404,
8
- 405,
9
- 406,
10
- 407,
4
+ 400, // Bad Request
5
+ 401, // Unauthorized
6
+ 403, // Forbidden
7
+ 404, // Not Found
8
+ 405, // Method Not Allowed
9
+ 406, // Not Acceptable
10
+ 407, // Proxy Authentication Required
11
11
  408, // Request Timeout
12
12
  ];
13
13
  const STATUS_IGNORE = [
@@ -54,8 +54,16 @@ export class AsyncCaller {
54
54
  });
55
55
  this.maxConcurrency = params.maxConcurrency ?? Infinity;
56
56
  this.maxRetries = params.maxRetries ?? 6;
57
- const PQueue = "default" in PQueueMod ? PQueueMod.default : PQueueMod;
58
- this.queue = new PQueue({ concurrency: this.maxConcurrency });
57
+ if ("default" in PQueueMod) {
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ this.queue = new PQueueMod.default({
60
+ concurrency: this.maxConcurrency,
61
+ });
62
+ }
63
+ else {
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ this.queue = new PQueueMod({ concurrency: this.maxConcurrency });
66
+ }
59
67
  this.onFailedResponseHook = params?.onFailedResponseHook;
60
68
  }
61
69
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -2,8 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wrapSDK = exports.wrapOpenAI = void 0;
4
4
  const traceable_js_1 = require("../traceable.cjs");
5
- function _combineChatCompletionChoices(choices) {
5
+ function _combineChatCompletionChoices(choices
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ ) {
6
8
  const reversedChoices = choices.slice().reverse();
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
10
  const message = {
8
11
  role: "assistant",
9
12
  content: "",
@@ -73,26 +76,43 @@ function _combineChatCompletionChoices(choices) {
73
76
  message: message,
74
77
  };
75
78
  }
76
- async function extractLangSmithExtraAndCall(openAIMethod, args, defaultRunConfig) {
77
- if (args[1]?.langsmithExtra !== undefined) {
78
- const { langsmithExtra, ...openAIOptions } = args[1];
79
- const wrappedMethod = (0, traceable_js_1.traceable)(openAIMethod, {
80
- ...defaultRunConfig,
81
- ...langsmithExtra,
82
- });
83
- const finalArgs = [args[0]];
84
- if (args.length > 2) {
85
- finalArgs.push(openAIOptions);
86
- finalArgs.push(args.slice(2));
79
+ const chatAggregator = (chunks) => {
80
+ if (!chunks || chunks.length === 0) {
81
+ return { choices: [{ message: { role: "assistant", content: "" } }] };
82
+ }
83
+ const choicesByIndex = {};
84
+ for (const chunk of chunks) {
85
+ for (const choice of chunk.choices) {
86
+ if (choicesByIndex[choice.index] === undefined) {
87
+ choicesByIndex[choice.index] = [];
88
+ }
89
+ choicesByIndex[choice.index].push(choice);
87
90
  }
88
- else if (Object.keys(openAIOptions).length !== 0) {
89
- finalArgs.push(openAIOptions);
91
+ }
92
+ const aggregatedOutput = chunks[chunks.length - 1];
93
+ aggregatedOutput.choices = Object.values(choicesByIndex).map((choices) => _combineChatCompletionChoices(choices));
94
+ return aggregatedOutput;
95
+ };
96
+ const textAggregator = (allChunks
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ ) => {
99
+ if (allChunks.length === 0) {
100
+ return { choices: [{ text: "" }] };
101
+ }
102
+ const allContent = [];
103
+ for (const chunk of allChunks) {
104
+ const content = chunk.choices[0].text;
105
+ if (content != null) {
106
+ allContent.push(content);
90
107
  }
91
- return wrappedMethod(...finalArgs);
92
108
  }
93
- const wrappedMethod = (0, traceable_js_1.traceable)(openAIMethod, defaultRunConfig);
94
- return wrappedMethod(...args);
95
- }
109
+ const content = allContent.join("");
110
+ const aggregatedOutput = allChunks[allChunks.length - 1];
111
+ aggregatedOutput.choices = [
112
+ { ...aggregatedOutput.choices[0], text: content },
113
+ ];
114
+ return aggregatedOutput;
115
+ };
96
116
  /**
97
117
  * Wraps an OpenAI client's completion methods, enabling automatic LangSmith
98
118
  * tracing. Method signatures are unchanged, with the exception that you can pass
@@ -118,61 +138,20 @@ async function extractLangSmithExtraAndCall(openAIMethod, args, defaultRunConfig
118
138
  * ```
119
139
  */
120
140
  const wrapOpenAI = (openai, options) => {
121
- const originalChatCompletionsFn = openai.chat.completions.create.bind(openai.chat.completions);
122
- openai.chat.completions.create = async (...args) => {
123
- const aggregator = (chunks) => {
124
- if (!chunks || chunks.length === 0) {
125
- return { choices: [{ message: { role: "assistant", content: "" } }] };
126
- }
127
- const choicesByIndex = {};
128
- for (const chunk of chunks) {
129
- for (const choice of chunk.choices) {
130
- if (choicesByIndex[choice.index] === undefined) {
131
- choicesByIndex[choice.index] = [];
132
- }
133
- choicesByIndex[choice.index].push(choice);
134
- }
135
- }
136
- const aggregatedOutput = chunks[chunks.length - 1];
137
- aggregatedOutput.choices = Object.values(choicesByIndex).map((choices) => _combineChatCompletionChoices(choices));
138
- return aggregatedOutput;
139
- };
140
- const defaultRunConfig = {
141
- name: "ChatOpenAI",
142
- run_type: "llm",
143
- aggregator,
144
- ...options,
145
- };
146
- return extractLangSmithExtraAndCall(originalChatCompletionsFn, args, defaultRunConfig);
147
- };
148
- const originalCompletionsFn = openai.completions.create.bind(openai.chat.completions);
149
- openai.completions.create = async (...args) => {
150
- const aggregator = (allChunks) => {
151
- if (allChunks.length === 0) {
152
- return { choices: [{ text: "" }] };
153
- }
154
- const allContent = [];
155
- for (const chunk of allChunks) {
156
- const content = chunk.choices[0].text;
157
- if (content != null) {
158
- allContent.push(content);
159
- }
160
- }
161
- const content = allContent.join("");
162
- const aggregatedOutput = allChunks[allChunks.length - 1];
163
- aggregatedOutput.choices = [
164
- { ...aggregatedOutput.choices[0], text: content },
165
- ];
166
- return aggregatedOutput;
167
- };
168
- const defaultRunConfig = {
169
- name: "OpenAI",
170
- run_type: "llm",
171
- aggregator,
172
- ...options,
173
- };
174
- return extractLangSmithExtraAndCall(originalCompletionsFn, args, defaultRunConfig);
175
- };
141
+ openai.chat.completions.create = (0, traceable_js_1.traceable)(openai.chat.completions.create.bind(openai.chat.completions), {
142
+ name: "ChatOpenAI",
143
+ run_type: "llm",
144
+ aggregator: chatAggregator,
145
+ argsConfigPath: [1, "langsmithExtra"],
146
+ ...options,
147
+ });
148
+ openai.completions.create = (0, traceable_js_1.traceable)(openai.completions.create.bind(openai.completions), {
149
+ name: "OpenAI",
150
+ run_type: "llm",
151
+ aggregator: textAggregator,
152
+ argsConfigPath: [1, "langsmithExtra"],
153
+ ...options,
154
+ });
176
155
  return openai;
177
156
  };
178
157
  exports.wrapOpenAI = wrapOpenAI;
@@ -181,7 +160,7 @@ const _wrapClient = (sdk, runName, options) => {
181
160
  get(target, propKey, receiver) {
182
161
  const originalValue = target[propKey];
183
162
  if (typeof originalValue === "function") {
184
- return (0, traceable_js_1.traceable)(originalValue.bind(target), Object.assign({ name: [runName, propKey.toString()].join("."), run_type: "llm" }, options?.client));
163
+ return (0, traceable_js_1.traceable)(originalValue.bind(target), Object.assign({ name: [runName, propKey.toString()].join("."), run_type: "llm" }, options));
185
164
  }
186
165
  else if (originalValue != null &&
187
166
  !Array.isArray(originalValue) &&
@@ -1,4 +1,5 @@
1
- import type { OpenAI } from "openai";
1
+ import { OpenAI } from "openai";
2
+ import type { APIPromise } from "openai/core";
2
3
  import type { Client, RunTreeConfig } from "../index.js";
3
4
  import { type RunnableConfigLike } from "../run_trees.js";
4
5
  import { type RunTreeLike } from "../traceable.js";
@@ -12,31 +13,29 @@ type OpenAIType = {
12
13
  create: (...args: any[]) => any;
13
14
  };
14
15
  };
15
- type PatchedOpenAIClient<T extends OpenAIType> = {
16
- [P in keyof T]: T[P];
17
- } & {
18
- chat: {
19
- completions: {
16
+ type PatchedOpenAIClient<T extends OpenAIType> = T & {
17
+ chat: T["chat"] & {
18
+ completions: T["chat"]["completions"] & {
20
19
  create: {
21
20
  (arg: OpenAI.ChatCompletionCreateParamsStreaming, arg2?: OpenAI.RequestOptions & {
22
21
  langsmithExtra?: RunnableConfigLike | RunTreeLike;
23
- }): Promise<AsyncGenerator<OpenAI.ChatCompletionChunk>>;
22
+ }): APIPromise<AsyncGenerator<OpenAI.ChatCompletionChunk>>;
24
23
  } & {
25
24
  (arg: OpenAI.ChatCompletionCreateParamsNonStreaming, arg2?: OpenAI.RequestOptions & {
26
25
  langsmithExtra?: RunnableConfigLike | RunTreeLike;
27
- }): Promise<OpenAI.ChatCompletionChunk>;
26
+ }): APIPromise<OpenAI.ChatCompletionChunk>;
28
27
  };
29
28
  };
30
29
  };
31
- completions: {
30
+ completions: T["completions"] & {
32
31
  create: {
33
32
  (arg: OpenAI.CompletionCreateParamsStreaming, arg2?: OpenAI.RequestOptions & {
34
33
  langsmithExtra?: RunnableConfigLike | RunTreeLike;
35
- }): Promise<AsyncGenerator<OpenAI.Completion>>;
34
+ }): APIPromise<AsyncGenerator<OpenAI.Completion>>;
36
35
  } & {
37
36
  (arg: OpenAI.CompletionCreateParamsNonStreaming, arg2?: OpenAI.RequestOptions & {
38
37
  langsmithExtra?: RunnableConfigLike | RunTreeLike;
39
- }): Promise<OpenAI.Completion>;
38
+ }): APIPromise<OpenAI.Completion>;
40
39
  };
41
40
  };
42
41
  };
@@ -1,6 +1,9 @@
1
1
  import { traceable } from "../traceable.js";
2
- function _combineChatCompletionChoices(choices) {
2
+ function _combineChatCompletionChoices(choices
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ ) {
3
5
  const reversedChoices = choices.slice().reverse();
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
7
  const message = {
5
8
  role: "assistant",
6
9
  content: "",
@@ -70,26 +73,43 @@ function _combineChatCompletionChoices(choices) {
70
73
  message: message,
71
74
  };
72
75
  }
73
- async function extractLangSmithExtraAndCall(openAIMethod, args, defaultRunConfig) {
74
- if (args[1]?.langsmithExtra !== undefined) {
75
- const { langsmithExtra, ...openAIOptions } = args[1];
76
- const wrappedMethod = traceable(openAIMethod, {
77
- ...defaultRunConfig,
78
- ...langsmithExtra,
79
- });
80
- const finalArgs = [args[0]];
81
- if (args.length > 2) {
82
- finalArgs.push(openAIOptions);
83
- finalArgs.push(args.slice(2));
76
+ const chatAggregator = (chunks) => {
77
+ if (!chunks || chunks.length === 0) {
78
+ return { choices: [{ message: { role: "assistant", content: "" } }] };
79
+ }
80
+ const choicesByIndex = {};
81
+ for (const chunk of chunks) {
82
+ for (const choice of chunk.choices) {
83
+ if (choicesByIndex[choice.index] === undefined) {
84
+ choicesByIndex[choice.index] = [];
85
+ }
86
+ choicesByIndex[choice.index].push(choice);
84
87
  }
85
- else if (Object.keys(openAIOptions).length !== 0) {
86
- finalArgs.push(openAIOptions);
88
+ }
89
+ const aggregatedOutput = chunks[chunks.length - 1];
90
+ aggregatedOutput.choices = Object.values(choicesByIndex).map((choices) => _combineChatCompletionChoices(choices));
91
+ return aggregatedOutput;
92
+ };
93
+ const textAggregator = (allChunks
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
+ ) => {
96
+ if (allChunks.length === 0) {
97
+ return { choices: [{ text: "" }] };
98
+ }
99
+ const allContent = [];
100
+ for (const chunk of allChunks) {
101
+ const content = chunk.choices[0].text;
102
+ if (content != null) {
103
+ allContent.push(content);
87
104
  }
88
- return wrappedMethod(...finalArgs);
89
105
  }
90
- const wrappedMethod = traceable(openAIMethod, defaultRunConfig);
91
- return wrappedMethod(...args);
92
- }
106
+ const content = allContent.join("");
107
+ const aggregatedOutput = allChunks[allChunks.length - 1];
108
+ aggregatedOutput.choices = [
109
+ { ...aggregatedOutput.choices[0], text: content },
110
+ ];
111
+ return aggregatedOutput;
112
+ };
93
113
  /**
94
114
  * Wraps an OpenAI client's completion methods, enabling automatic LangSmith
95
115
  * tracing. Method signatures are unchanged, with the exception that you can pass
@@ -115,61 +135,20 @@ async function extractLangSmithExtraAndCall(openAIMethod, args, defaultRunConfig
115
135
  * ```
116
136
  */
117
137
  export const wrapOpenAI = (openai, options) => {
118
- const originalChatCompletionsFn = openai.chat.completions.create.bind(openai.chat.completions);
119
- openai.chat.completions.create = async (...args) => {
120
- const aggregator = (chunks) => {
121
- if (!chunks || chunks.length === 0) {
122
- return { choices: [{ message: { role: "assistant", content: "" } }] };
123
- }
124
- const choicesByIndex = {};
125
- for (const chunk of chunks) {
126
- for (const choice of chunk.choices) {
127
- if (choicesByIndex[choice.index] === undefined) {
128
- choicesByIndex[choice.index] = [];
129
- }
130
- choicesByIndex[choice.index].push(choice);
131
- }
132
- }
133
- const aggregatedOutput = chunks[chunks.length - 1];
134
- aggregatedOutput.choices = Object.values(choicesByIndex).map((choices) => _combineChatCompletionChoices(choices));
135
- return aggregatedOutput;
136
- };
137
- const defaultRunConfig = {
138
- name: "ChatOpenAI",
139
- run_type: "llm",
140
- aggregator,
141
- ...options,
142
- };
143
- return extractLangSmithExtraAndCall(originalChatCompletionsFn, args, defaultRunConfig);
144
- };
145
- const originalCompletionsFn = openai.completions.create.bind(openai.chat.completions);
146
- openai.completions.create = async (...args) => {
147
- const aggregator = (allChunks) => {
148
- if (allChunks.length === 0) {
149
- return { choices: [{ text: "" }] };
150
- }
151
- const allContent = [];
152
- for (const chunk of allChunks) {
153
- const content = chunk.choices[0].text;
154
- if (content != null) {
155
- allContent.push(content);
156
- }
157
- }
158
- const content = allContent.join("");
159
- const aggregatedOutput = allChunks[allChunks.length - 1];
160
- aggregatedOutput.choices = [
161
- { ...aggregatedOutput.choices[0], text: content },
162
- ];
163
- return aggregatedOutput;
164
- };
165
- const defaultRunConfig = {
166
- name: "OpenAI",
167
- run_type: "llm",
168
- aggregator,
169
- ...options,
170
- };
171
- return extractLangSmithExtraAndCall(originalCompletionsFn, args, defaultRunConfig);
172
- };
138
+ openai.chat.completions.create = traceable(openai.chat.completions.create.bind(openai.chat.completions), {
139
+ name: "ChatOpenAI",
140
+ run_type: "llm",
141
+ aggregator: chatAggregator,
142
+ argsConfigPath: [1, "langsmithExtra"],
143
+ ...options,
144
+ });
145
+ openai.completions.create = traceable(openai.completions.create.bind(openai.completions), {
146
+ name: "OpenAI",
147
+ run_type: "llm",
148
+ aggregator: textAggregator,
149
+ argsConfigPath: [1, "langsmithExtra"],
150
+ ...options,
151
+ });
173
152
  return openai;
174
153
  };
175
154
  const _wrapClient = (sdk, runName, options) => {
@@ -177,7 +156,7 @@ const _wrapClient = (sdk, runName, options) => {
177
156
  get(target, propKey, receiver) {
178
157
  const originalValue = target[propKey];
179
158
  if (typeof originalValue === "function") {
180
- return traceable(originalValue.bind(target), Object.assign({ name: [runName, propKey.toString()].join("."), run_type: "llm" }, options?.client));
159
+ return traceable(originalValue.bind(target), Object.assign({ name: [runName, propKey.toString()].join("."), run_type: "llm" }, options));
181
160
  }
182
161
  else if (originalValue != null &&
183
162
  !Array.isArray(originalValue) &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.",
5
5
  "packageManager": "yarn@1.22.19",
6
6
  "files": [
@@ -47,8 +47,8 @@
47
47
  "check-version": "node scripts/check-version.js",
48
48
  "check-npm-version": "node scripts/check-npm-version.js",
49
49
  "clean": "rm -rf dist/ && node scripts/create-entrypoints.js clean",
50
- "build:esm": "tsc --outDir dist/ && rm -rf dist/tests dist/**/tests",
51
- "build:cjs": "tsc --outDir dist-cjs/ -p tsconfig.cjs.json && node scripts/move-cjs-to-dist.js && rm -r dist-cjs",
50
+ "build:esm": "rm -f src/package.json && tsc --outDir dist/ && rm -rf dist/tests dist/**/tests",
51
+ "build:cjs": "echo '{}' > src/package.json && tsc --outDir dist-cjs/ -p tsconfig.cjs.json && node scripts/move-cjs-to-dist.js && rm -r dist-cjs src/package.json",
52
52
  "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --passWithNoTests --testPathIgnorePatterns='\\.int\\.test.[tj]s' --testTimeout 30000",
53
53
  "test:integration": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=\\.int\\.test.ts --testTimeout 100000",
54
54
  "test:single": "NODE_OPTIONS=--experimental-vm-modules yarn run jest --config jest.config.cjs --testTimeout 100000",
@@ -104,7 +104,7 @@
104
104
  "prettier": "^2.8.8",
105
105
  "ts-jest": "^29.1.0",
106
106
  "ts-node": "^10.9.1",
107
- "typescript": "^5.0.4"
107
+ "typescript": "^5.4.5"
108
108
  },
109
109
  "peerDependencies": {
110
110
  "openai": "*"