langsmith 0.1.65 → 0.1.66
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/schemas.d.ts +71 -0
- package/dist/traceable.cjs +44 -22
- package/dist/traceable.d.ts +19 -1
- package/dist/traceable.js +44 -22
- package/dist/wrappers/openai.cjs +38 -0
- package/dist/wrappers/openai.js +38 -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.1.
|
|
11
|
+
exports.__version__ = "0.1.66";
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { Client, type ClientConfig } from "./client.js";
|
|
|
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.1.
|
|
5
|
+
export declare const __version__ = "0.1.66";
|
package/dist/index.js
CHANGED
package/dist/schemas.d.ts
CHANGED
|
@@ -391,4 +391,75 @@ export interface RunWithAnnotationQueueInfo extends BaseRun {
|
|
|
391
391
|
/** The time this run was added to the queue. */
|
|
392
392
|
added_at?: string;
|
|
393
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Breakdown of input token counts.
|
|
396
|
+
*
|
|
397
|
+
* Does not *need* to sum to full input token count. Does *not* need to have all keys.
|
|
398
|
+
*/
|
|
399
|
+
export type InputTokenDetails = {
|
|
400
|
+
/**
|
|
401
|
+
* Audio input tokens.
|
|
402
|
+
*/
|
|
403
|
+
audio?: number;
|
|
404
|
+
/**
|
|
405
|
+
* Input tokens that were cached and there was a cache hit.
|
|
406
|
+
*
|
|
407
|
+
* Since there was a cache hit, the tokens were read from the cache.
|
|
408
|
+
* More precisely, the model state given these tokens was read from the cache.
|
|
409
|
+
*/
|
|
410
|
+
cache_read?: number;
|
|
411
|
+
/**
|
|
412
|
+
* Input tokens that were cached and there was a cache miss.
|
|
413
|
+
*
|
|
414
|
+
* Since there was a cache miss, the cache was created from these tokens.
|
|
415
|
+
*/
|
|
416
|
+
cache_creation?: number;
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* Breakdown of output token counts.
|
|
420
|
+
*
|
|
421
|
+
* Does *not* need to sum to full output token count. Does *not* need to have all keys.
|
|
422
|
+
*/
|
|
423
|
+
export type OutputTokenDetails = {
|
|
424
|
+
/**
|
|
425
|
+
* Audio output tokens
|
|
426
|
+
*/
|
|
427
|
+
audio?: number;
|
|
428
|
+
/**
|
|
429
|
+
* Reasoning output tokens.
|
|
430
|
+
*
|
|
431
|
+
* Tokens generated by the model in a chain of thought process (i.e. by
|
|
432
|
+
* OpenAI's o1 models) that are not returned as part of model output.
|
|
433
|
+
*/
|
|
434
|
+
reasoning?: number;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* Usage metadata for a message, such as token counts.
|
|
438
|
+
*/
|
|
439
|
+
export type UsageMetadata = {
|
|
440
|
+
/**
|
|
441
|
+
* Count of input (or prompt) tokens. Sum of all input token types.
|
|
442
|
+
*/
|
|
443
|
+
input_tokens: number;
|
|
444
|
+
/**
|
|
445
|
+
* Count of output (or completion) tokens. Sum of all output token types.
|
|
446
|
+
*/
|
|
447
|
+
output_tokens: number;
|
|
448
|
+
/**
|
|
449
|
+
* Total token count. Sum of input_tokens + output_tokens.
|
|
450
|
+
*/
|
|
451
|
+
total_tokens: number;
|
|
452
|
+
/**
|
|
453
|
+
* Breakdown of input token counts.
|
|
454
|
+
*
|
|
455
|
+
* Does *not* need to sum to full input token count. Does *not* need to have all keys.
|
|
456
|
+
*/
|
|
457
|
+
input_token_details?: InputTokenDetails;
|
|
458
|
+
/**
|
|
459
|
+
* Breakdown of output token counts.
|
|
460
|
+
*
|
|
461
|
+
* Does *not* need to sum to full output token count. Does *not* need to have all keys.
|
|
462
|
+
*/
|
|
463
|
+
output_token_details?: OutputTokenDetails;
|
|
464
|
+
};
|
|
394
465
|
export {};
|
package/dist/traceable.cjs
CHANGED
|
@@ -8,30 +8,50 @@ const traceable_js_1 = require("./singletons/traceable.cjs");
|
|
|
8
8
|
const constants_js_1 = require("./singletons/constants.cjs");
|
|
9
9
|
const asserts_js_1 = require("./utils/asserts.cjs");
|
|
10
10
|
traceable_js_1.AsyncLocalStorageProviderSingleton.initializeGlobalInstance(new node_async_hooks_1.AsyncLocalStorage());
|
|
11
|
-
const handleRunInputs = (rawInputs) => {
|
|
11
|
+
const handleRunInputs = (rawInputs, processInputs) => {
|
|
12
12
|
const firstInput = rawInputs[0];
|
|
13
|
+
let inputs;
|
|
13
14
|
if (firstInput == null) {
|
|
14
|
-
|
|
15
|
+
inputs = {};
|
|
15
16
|
}
|
|
16
|
-
if (rawInputs.length > 1) {
|
|
17
|
-
|
|
17
|
+
else if (rawInputs.length > 1) {
|
|
18
|
+
inputs = { args: rawInputs };
|
|
18
19
|
}
|
|
19
|
-
if ((0, asserts_js_1.isKVMap)(firstInput)) {
|
|
20
|
-
|
|
20
|
+
else if ((0, asserts_js_1.isKVMap)(firstInput)) {
|
|
21
|
+
inputs = firstInput;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
inputs = { input: firstInput };
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
return processInputs(inputs);
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
console.error("Error occurred during processInputs. Sending raw inputs:", e);
|
|
31
|
+
return inputs;
|
|
21
32
|
}
|
|
22
|
-
return { input: firstInput };
|
|
23
33
|
};
|
|
24
|
-
const handleRunOutputs = (rawOutputs) => {
|
|
34
|
+
const handleRunOutputs = (rawOutputs, processOutputs) => {
|
|
35
|
+
let outputs;
|
|
25
36
|
if ((0, asserts_js_1.isKVMap)(rawOutputs)) {
|
|
26
|
-
|
|
37
|
+
outputs = rawOutputs;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
outputs = { outputs: rawOutputs };
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
return processOutputs(outputs);
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
console.error("Error occurred during processOutputs. Sending raw outputs:", e);
|
|
47
|
+
return outputs;
|
|
27
48
|
}
|
|
28
|
-
return { outputs: rawOutputs };
|
|
29
49
|
};
|
|
30
|
-
const getTracingRunTree = (runTree, inputs, getInvocationParams) => {
|
|
50
|
+
const getTracingRunTree = (runTree, inputs, getInvocationParams, processInputs) => {
|
|
31
51
|
if (!(0, env_js_1.isTracingEnabled)(runTree.tracingEnabled)) {
|
|
32
52
|
return undefined;
|
|
33
53
|
}
|
|
34
|
-
runTree.inputs = handleRunInputs(inputs);
|
|
54
|
+
runTree.inputs = handleRunInputs(inputs, processInputs);
|
|
35
55
|
const invocationParams = getInvocationParams?.(...inputs);
|
|
36
56
|
if (invocationParams != null) {
|
|
37
57
|
runTree.extra ??= {};
|
|
@@ -193,7 +213,9 @@ const convertSerializableArg = (arg) => {
|
|
|
193
213
|
*/
|
|
194
214
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
195
215
|
function traceable(wrappedFunc, config) {
|
|
196
|
-
const { aggregator, argsConfigPath, __finalTracedIteratorKey, ...runTreeConfig } = config ?? {};
|
|
216
|
+
const { aggregator, argsConfigPath, __finalTracedIteratorKey, processInputs, processOutputs, ...runTreeConfig } = config ?? {};
|
|
217
|
+
const processInputsFn = processInputs ?? ((x) => x);
|
|
218
|
+
const processOutputsFn = processOutputs ?? ((x) => x);
|
|
197
219
|
const traceableFunc = (...args) => {
|
|
198
220
|
let ensuredConfig;
|
|
199
221
|
try {
|
|
@@ -251,7 +273,7 @@ function traceable(wrappedFunc, config) {
|
|
|
251
273
|
// used for handoff between LangChain.JS and traceable functions
|
|
252
274
|
if ((0, run_trees_js_1.isRunnableConfigLike)(firstArg)) {
|
|
253
275
|
return [
|
|
254
|
-
getTracingRunTree(run_trees_js_1.RunTree.fromRunnableConfig(firstArg, ensuredConfig), restArgs, config?.getInvocationParams),
|
|
276
|
+
getTracingRunTree(run_trees_js_1.RunTree.fromRunnableConfig(firstArg, ensuredConfig), restArgs, config?.getInvocationParams, processInputsFn),
|
|
255
277
|
restArgs,
|
|
256
278
|
];
|
|
257
279
|
}
|
|
@@ -267,7 +289,7 @@ function traceable(wrappedFunc, config) {
|
|
|
267
289
|
if (firstArg === traceable_js_1.ROOT || (0, run_trees_js_1.isRunTree)(firstArg)) {
|
|
268
290
|
const currentRunTree = getTracingRunTree(firstArg === traceable_js_1.ROOT
|
|
269
291
|
? new run_trees_js_1.RunTree(ensuredConfig)
|
|
270
|
-
: firstArg.createChild(ensuredConfig), restArgs, config?.getInvocationParams);
|
|
292
|
+
: firstArg.createChild(ensuredConfig), restArgs, config?.getInvocationParams, processInputsFn);
|
|
271
293
|
return [currentRunTree, [currentRunTree, ...restArgs]];
|
|
272
294
|
}
|
|
273
295
|
// Node.JS uses AsyncLocalStorage (ALS) and AsyncResource
|
|
@@ -275,11 +297,11 @@ function traceable(wrappedFunc, config) {
|
|
|
275
297
|
const prevRunFromStore = asyncLocalStorage.getStore();
|
|
276
298
|
if ((0, run_trees_js_1.isRunTree)(prevRunFromStore)) {
|
|
277
299
|
return [
|
|
278
|
-
getTracingRunTree(prevRunFromStore.createChild(ensuredConfig), processedArgs, config?.getInvocationParams),
|
|
300
|
+
getTracingRunTree(prevRunFromStore.createChild(ensuredConfig), processedArgs, config?.getInvocationParams, processInputsFn),
|
|
279
301
|
processedArgs,
|
|
280
302
|
];
|
|
281
303
|
}
|
|
282
|
-
const currentRunTree = getTracingRunTree(new run_trees_js_1.RunTree(ensuredConfig), processedArgs, config?.getInvocationParams);
|
|
304
|
+
const currentRunTree = getTracingRunTree(new run_trees_js_1.RunTree(ensuredConfig), processedArgs, config?.getInvocationParams, processInputsFn);
|
|
283
305
|
// If a context var is set by LangChain outside of a traceable,
|
|
284
306
|
// it will be an object with a single property and we should copy
|
|
285
307
|
// context vars over into the new run tree.
|
|
@@ -317,7 +339,7 @@ function traceable(wrappedFunc, config) {
|
|
|
317
339
|
: reader.read());
|
|
318
340
|
if (result.done) {
|
|
319
341
|
finished = true;
|
|
320
|
-
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks)));
|
|
342
|
+
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
|
|
321
343
|
await handleEnd();
|
|
322
344
|
controller.close();
|
|
323
345
|
break;
|
|
@@ -329,7 +351,7 @@ function traceable(wrappedFunc, config) {
|
|
|
329
351
|
async cancel(reason) {
|
|
330
352
|
if (!finished)
|
|
331
353
|
await currentRunTree?.end(undefined, "Cancelled");
|
|
332
|
-
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks)));
|
|
354
|
+
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
|
|
333
355
|
await handleEnd();
|
|
334
356
|
return reader.cancel(reason);
|
|
335
357
|
},
|
|
@@ -359,7 +381,7 @@ function traceable(wrappedFunc, config) {
|
|
|
359
381
|
finally {
|
|
360
382
|
if (!finished)
|
|
361
383
|
await currentRunTree?.end(undefined, "Cancelled");
|
|
362
|
-
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks)));
|
|
384
|
+
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
|
|
363
385
|
await handleEnd();
|
|
364
386
|
}
|
|
365
387
|
}
|
|
@@ -444,7 +466,7 @@ function traceable(wrappedFunc, config) {
|
|
|
444
466
|
memo.push(value);
|
|
445
467
|
}
|
|
446
468
|
return memo;
|
|
447
|
-
}, []))));
|
|
469
|
+
}, [])), processOutputsFn));
|
|
448
470
|
await handleEnd();
|
|
449
471
|
}
|
|
450
472
|
catch (e) {
|
|
@@ -459,7 +481,7 @@ function traceable(wrappedFunc, config) {
|
|
|
459
481
|
})();
|
|
460
482
|
}
|
|
461
483
|
try {
|
|
462
|
-
await currentRunTree?.end(handleRunOutputs(rawOutput));
|
|
484
|
+
await currentRunTree?.end(handleRunOutputs(rawOutput, processOutputsFn));
|
|
463
485
|
await handleEnd();
|
|
464
486
|
}
|
|
465
487
|
finally {
|
package/dist/traceable.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RunTreeConfig } from "./run_trees.js";
|
|
2
|
-
import { InvocationParamsSchema } from "./schemas.js";
|
|
2
|
+
import { InvocationParamsSchema, KVMap } from "./schemas.js";
|
|
3
3
|
import { TraceableFunction } from "./singletons/types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Higher-order function that takes function as input and returns a
|
|
@@ -28,6 +28,24 @@ export declare function traceable<Func extends (...args: any[]) => any>(wrappedF
|
|
|
28
28
|
* @returns Key-value map of the invocation parameters, which will be merged with the existing metadata
|
|
29
29
|
*/
|
|
30
30
|
getInvocationParams?: (...args: Parameters<Func>) => InvocationParamsSchema | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Apply transformations to the inputs before logging.
|
|
33
|
+
* This function should NOT mutate the inputs.
|
|
34
|
+
* `processInputs` is not inherited by nested traceable functions.
|
|
35
|
+
*
|
|
36
|
+
* @param inputs Key-value map of the function inputs.
|
|
37
|
+
* @returns Transformed key-value map
|
|
38
|
+
*/
|
|
39
|
+
processInputs?: (inputs: Readonly<KVMap>) => KVMap;
|
|
40
|
+
/**
|
|
41
|
+
* Apply transformations to the outputs before logging.
|
|
42
|
+
* This function should NOT mutate the outputs.
|
|
43
|
+
* `processOutputs` is not inherited by nested traceable functions.
|
|
44
|
+
*
|
|
45
|
+
* @param outputs Key-value map of the function outputs
|
|
46
|
+
* @returns Transformed key-value map
|
|
47
|
+
*/
|
|
48
|
+
processOutputs?: (outputs: Readonly<KVMap>) => KVMap;
|
|
31
49
|
}): TraceableFunction<Func>;
|
|
32
50
|
export { getCurrentRunTree, isTraceableFunction, withRunTree, ROOT, } from "./singletons/traceable.js";
|
|
33
51
|
export type { RunTreeLike, TraceableFunction } from "./singletons/types.js";
|
package/dist/traceable.js
CHANGED
|
@@ -5,30 +5,50 @@ import { ROOT, AsyncLocalStorageProviderSingleton, } from "./singletons/traceabl
|
|
|
5
5
|
import { _LC_CONTEXT_VARIABLES_KEY } from "./singletons/constants.js";
|
|
6
6
|
import { isKVMap, isReadableStream, isAsyncIterable, isIteratorLike, isThenable, isGenerator, isPromiseMethod, } from "./utils/asserts.js";
|
|
7
7
|
AsyncLocalStorageProviderSingleton.initializeGlobalInstance(new AsyncLocalStorage());
|
|
8
|
-
const handleRunInputs = (rawInputs) => {
|
|
8
|
+
const handleRunInputs = (rawInputs, processInputs) => {
|
|
9
9
|
const firstInput = rawInputs[0];
|
|
10
|
+
let inputs;
|
|
10
11
|
if (firstInput == null) {
|
|
11
|
-
|
|
12
|
+
inputs = {};
|
|
12
13
|
}
|
|
13
|
-
if (rawInputs.length > 1) {
|
|
14
|
-
|
|
14
|
+
else if (rawInputs.length > 1) {
|
|
15
|
+
inputs = { args: rawInputs };
|
|
15
16
|
}
|
|
16
|
-
if (isKVMap(firstInput)) {
|
|
17
|
-
|
|
17
|
+
else if (isKVMap(firstInput)) {
|
|
18
|
+
inputs = firstInput;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
inputs = { input: firstInput };
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
return processInputs(inputs);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
console.error("Error occurred during processInputs. Sending raw inputs:", e);
|
|
28
|
+
return inputs;
|
|
18
29
|
}
|
|
19
|
-
return { input: firstInput };
|
|
20
30
|
};
|
|
21
|
-
const handleRunOutputs = (rawOutputs) => {
|
|
31
|
+
const handleRunOutputs = (rawOutputs, processOutputs) => {
|
|
32
|
+
let outputs;
|
|
22
33
|
if (isKVMap(rawOutputs)) {
|
|
23
|
-
|
|
34
|
+
outputs = rawOutputs;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
outputs = { outputs: rawOutputs };
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return processOutputs(outputs);
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
console.error("Error occurred during processOutputs. Sending raw outputs:", e);
|
|
44
|
+
return outputs;
|
|
24
45
|
}
|
|
25
|
-
return { outputs: rawOutputs };
|
|
26
46
|
};
|
|
27
|
-
const getTracingRunTree = (runTree, inputs, getInvocationParams) => {
|
|
47
|
+
const getTracingRunTree = (runTree, inputs, getInvocationParams, processInputs) => {
|
|
28
48
|
if (!isTracingEnabled(runTree.tracingEnabled)) {
|
|
29
49
|
return undefined;
|
|
30
50
|
}
|
|
31
|
-
runTree.inputs = handleRunInputs(inputs);
|
|
51
|
+
runTree.inputs = handleRunInputs(inputs, processInputs);
|
|
32
52
|
const invocationParams = getInvocationParams?.(...inputs);
|
|
33
53
|
if (invocationParams != null) {
|
|
34
54
|
runTree.extra ??= {};
|
|
@@ -190,7 +210,9 @@ const convertSerializableArg = (arg) => {
|
|
|
190
210
|
*/
|
|
191
211
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
192
212
|
export function traceable(wrappedFunc, config) {
|
|
193
|
-
const { aggregator, argsConfigPath, __finalTracedIteratorKey, ...runTreeConfig } = config ?? {};
|
|
213
|
+
const { aggregator, argsConfigPath, __finalTracedIteratorKey, processInputs, processOutputs, ...runTreeConfig } = config ?? {};
|
|
214
|
+
const processInputsFn = processInputs ?? ((x) => x);
|
|
215
|
+
const processOutputsFn = processOutputs ?? ((x) => x);
|
|
194
216
|
const traceableFunc = (...args) => {
|
|
195
217
|
let ensuredConfig;
|
|
196
218
|
try {
|
|
@@ -248,7 +270,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
248
270
|
// used for handoff between LangChain.JS and traceable functions
|
|
249
271
|
if (isRunnableConfigLike(firstArg)) {
|
|
250
272
|
return [
|
|
251
|
-
getTracingRunTree(RunTree.fromRunnableConfig(firstArg, ensuredConfig), restArgs, config?.getInvocationParams),
|
|
273
|
+
getTracingRunTree(RunTree.fromRunnableConfig(firstArg, ensuredConfig), restArgs, config?.getInvocationParams, processInputsFn),
|
|
252
274
|
restArgs,
|
|
253
275
|
];
|
|
254
276
|
}
|
|
@@ -264,7 +286,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
264
286
|
if (firstArg === ROOT || isRunTree(firstArg)) {
|
|
265
287
|
const currentRunTree = getTracingRunTree(firstArg === ROOT
|
|
266
288
|
? new RunTree(ensuredConfig)
|
|
267
|
-
: firstArg.createChild(ensuredConfig), restArgs, config?.getInvocationParams);
|
|
289
|
+
: firstArg.createChild(ensuredConfig), restArgs, config?.getInvocationParams, processInputsFn);
|
|
268
290
|
return [currentRunTree, [currentRunTree, ...restArgs]];
|
|
269
291
|
}
|
|
270
292
|
// Node.JS uses AsyncLocalStorage (ALS) and AsyncResource
|
|
@@ -272,11 +294,11 @@ export function traceable(wrappedFunc, config) {
|
|
|
272
294
|
const prevRunFromStore = asyncLocalStorage.getStore();
|
|
273
295
|
if (isRunTree(prevRunFromStore)) {
|
|
274
296
|
return [
|
|
275
|
-
getTracingRunTree(prevRunFromStore.createChild(ensuredConfig), processedArgs, config?.getInvocationParams),
|
|
297
|
+
getTracingRunTree(prevRunFromStore.createChild(ensuredConfig), processedArgs, config?.getInvocationParams, processInputsFn),
|
|
276
298
|
processedArgs,
|
|
277
299
|
];
|
|
278
300
|
}
|
|
279
|
-
const currentRunTree = getTracingRunTree(new RunTree(ensuredConfig), processedArgs, config?.getInvocationParams);
|
|
301
|
+
const currentRunTree = getTracingRunTree(new RunTree(ensuredConfig), processedArgs, config?.getInvocationParams, processInputsFn);
|
|
280
302
|
// If a context var is set by LangChain outside of a traceable,
|
|
281
303
|
// it will be an object with a single property and we should copy
|
|
282
304
|
// context vars over into the new run tree.
|
|
@@ -314,7 +336,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
314
336
|
: reader.read());
|
|
315
337
|
if (result.done) {
|
|
316
338
|
finished = true;
|
|
317
|
-
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks)));
|
|
339
|
+
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
|
|
318
340
|
await handleEnd();
|
|
319
341
|
controller.close();
|
|
320
342
|
break;
|
|
@@ -326,7 +348,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
326
348
|
async cancel(reason) {
|
|
327
349
|
if (!finished)
|
|
328
350
|
await currentRunTree?.end(undefined, "Cancelled");
|
|
329
|
-
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks)));
|
|
351
|
+
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
|
|
330
352
|
await handleEnd();
|
|
331
353
|
return reader.cancel(reason);
|
|
332
354
|
},
|
|
@@ -356,7 +378,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
356
378
|
finally {
|
|
357
379
|
if (!finished)
|
|
358
380
|
await currentRunTree?.end(undefined, "Cancelled");
|
|
359
|
-
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks)));
|
|
381
|
+
await currentRunTree?.end(handleRunOutputs(await handleChunks(chunks), processOutputsFn));
|
|
360
382
|
await handleEnd();
|
|
361
383
|
}
|
|
362
384
|
}
|
|
@@ -441,7 +463,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
441
463
|
memo.push(value);
|
|
442
464
|
}
|
|
443
465
|
return memo;
|
|
444
|
-
}, []))));
|
|
466
|
+
}, [])), processOutputsFn));
|
|
445
467
|
await handleEnd();
|
|
446
468
|
}
|
|
447
469
|
catch (e) {
|
|
@@ -456,7 +478,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
456
478
|
})();
|
|
457
479
|
}
|
|
458
480
|
try {
|
|
459
|
-
await currentRunTree?.end(handleRunOutputs(rawOutput));
|
|
481
|
+
await currentRunTree?.end(handleRunOutputs(rawOutput, processOutputsFn));
|
|
460
482
|
await handleEnd();
|
|
461
483
|
}
|
|
462
484
|
finally {
|
package/dist/wrappers/openai.cjs
CHANGED
|
@@ -113,6 +113,43 @@ const textAggregator = (allChunks
|
|
|
113
113
|
];
|
|
114
114
|
return aggregatedOutput;
|
|
115
115
|
};
|
|
116
|
+
function processChatCompletion(outputs) {
|
|
117
|
+
const chatCompletion = outputs;
|
|
118
|
+
// copy the original object, minus usage
|
|
119
|
+
const result = { ...chatCompletion };
|
|
120
|
+
const usage = chatCompletion.usage;
|
|
121
|
+
if (usage) {
|
|
122
|
+
const inputTokenDetails = {
|
|
123
|
+
...(usage.prompt_tokens_details?.audio_tokens !== null && {
|
|
124
|
+
audio: usage.prompt_tokens_details?.audio_tokens,
|
|
125
|
+
}),
|
|
126
|
+
...(usage.prompt_tokens_details?.cached_tokens !== null && {
|
|
127
|
+
cache_read: usage.prompt_tokens_details?.cached_tokens,
|
|
128
|
+
}),
|
|
129
|
+
};
|
|
130
|
+
const outputTokenDetails = {
|
|
131
|
+
...(usage.completion_tokens_details?.audio_tokens !== null && {
|
|
132
|
+
audio: usage.completion_tokens_details?.audio_tokens,
|
|
133
|
+
}),
|
|
134
|
+
...(usage.completion_tokens_details?.reasoning_tokens !== null && {
|
|
135
|
+
reasoning: usage.completion_tokens_details?.reasoning_tokens,
|
|
136
|
+
}),
|
|
137
|
+
};
|
|
138
|
+
result.usage_metadata = {
|
|
139
|
+
input_tokens: usage.prompt_tokens ?? 0,
|
|
140
|
+
output_tokens: usage.completion_tokens ?? 0,
|
|
141
|
+
total_tokens: usage.total_tokens ?? 0,
|
|
142
|
+
...(Object.keys(inputTokenDetails).length > 0 && {
|
|
143
|
+
input_token_details: inputTokenDetails,
|
|
144
|
+
}),
|
|
145
|
+
...(Object.keys(outputTokenDetails).length > 0 && {
|
|
146
|
+
output_token_details: outputTokenDetails,
|
|
147
|
+
}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
delete result.usage;
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
116
153
|
/**
|
|
117
154
|
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
118
155
|
* tracing. Method signatures are unchanged, with the exception that you can pass
|
|
@@ -208,6 +245,7 @@ const wrapOpenAI = (openai, options) => {
|
|
|
208
245
|
ls_stop,
|
|
209
246
|
};
|
|
210
247
|
},
|
|
248
|
+
processOutputs: processChatCompletion,
|
|
211
249
|
...options,
|
|
212
250
|
}),
|
|
213
251
|
},
|
package/dist/wrappers/openai.js
CHANGED
|
@@ -110,6 +110,43 @@ const textAggregator = (allChunks
|
|
|
110
110
|
];
|
|
111
111
|
return aggregatedOutput;
|
|
112
112
|
};
|
|
113
|
+
function processChatCompletion(outputs) {
|
|
114
|
+
const chatCompletion = outputs;
|
|
115
|
+
// copy the original object, minus usage
|
|
116
|
+
const result = { ...chatCompletion };
|
|
117
|
+
const usage = chatCompletion.usage;
|
|
118
|
+
if (usage) {
|
|
119
|
+
const inputTokenDetails = {
|
|
120
|
+
...(usage.prompt_tokens_details?.audio_tokens !== null && {
|
|
121
|
+
audio: usage.prompt_tokens_details?.audio_tokens,
|
|
122
|
+
}),
|
|
123
|
+
...(usage.prompt_tokens_details?.cached_tokens !== null && {
|
|
124
|
+
cache_read: usage.prompt_tokens_details?.cached_tokens,
|
|
125
|
+
}),
|
|
126
|
+
};
|
|
127
|
+
const outputTokenDetails = {
|
|
128
|
+
...(usage.completion_tokens_details?.audio_tokens !== null && {
|
|
129
|
+
audio: usage.completion_tokens_details?.audio_tokens,
|
|
130
|
+
}),
|
|
131
|
+
...(usage.completion_tokens_details?.reasoning_tokens !== null && {
|
|
132
|
+
reasoning: usage.completion_tokens_details?.reasoning_tokens,
|
|
133
|
+
}),
|
|
134
|
+
};
|
|
135
|
+
result.usage_metadata = {
|
|
136
|
+
input_tokens: usage.prompt_tokens ?? 0,
|
|
137
|
+
output_tokens: usage.completion_tokens ?? 0,
|
|
138
|
+
total_tokens: usage.total_tokens ?? 0,
|
|
139
|
+
...(Object.keys(inputTokenDetails).length > 0 && {
|
|
140
|
+
input_token_details: inputTokenDetails,
|
|
141
|
+
}),
|
|
142
|
+
...(Object.keys(outputTokenDetails).length > 0 && {
|
|
143
|
+
output_token_details: outputTokenDetails,
|
|
144
|
+
}),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
delete result.usage;
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
113
150
|
/**
|
|
114
151
|
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
115
152
|
* tracing. Method signatures are unchanged, with the exception that you can pass
|
|
@@ -205,6 +242,7 @@ export const wrapOpenAI = (openai, options) => {
|
|
|
205
242
|
ls_stop,
|
|
206
243
|
};
|
|
207
244
|
},
|
|
245
|
+
processOutputs: processChatCompletion,
|
|
208
246
|
...options,
|
|
209
247
|
}),
|
|
210
248
|
},
|