langsmith 0.1.18 → 0.1.19
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/run_trees.cjs +9 -3
- package/dist/run_trees.d.ts +2 -1
- package/dist/run_trees.js +9 -3
- package/dist/traceable.cjs +23 -3
- package/dist/traceable.d.ts +3 -1
- package/dist/traceable.js +23 -3
- package/dist/wrappers/index.cjs +17 -0
- package/dist/wrappers/index.d.ts +1 -0
- package/dist/wrappers/index.js +1 -0
- package/dist/wrappers/openai.cjs +215 -0
- package/dist/wrappers/openai.d.ts +83 -0
- package/dist/wrappers/openai.js +210 -0
- package/package.json +29 -8
- package/wrappers/openai.cjs +1 -0
- package/wrappers/openai.d.cts +1 -0
- package/wrappers/openai.d.ts +1 -0
- package/wrappers/openai.js +1 -0
- package/wrappers.cjs +1 -1
- package/wrappers.d.cts +1 -1
- package/wrappers.d.ts +1 -1
- package/wrappers.js +1 -1
- package/dist/wrappers.cjs +0 -54
- package/dist/wrappers.d.ts +0 -37
- package/dist/wrappers.js +0 -49
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.
|
|
9
|
+
exports.__version__ = "0.1.19";
|
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.
|
|
4
|
+
export declare const __version__ = "0.1.19";
|
package/dist/index.js
CHANGED
package/dist/run_trees.cjs
CHANGED
|
@@ -43,7 +43,7 @@ function convertToDottedOrderFormat(epoch, runId) {
|
|
|
43
43
|
}
|
|
44
44
|
exports.convertToDottedOrderFormat = convertToDottedOrderFormat;
|
|
45
45
|
class RunTree {
|
|
46
|
-
constructor(
|
|
46
|
+
constructor(originalConfig) {
|
|
47
47
|
Object.defineProperty(this, "id", {
|
|
48
48
|
enumerable: true,
|
|
49
49
|
configurable: true,
|
|
@@ -159,7 +159,13 @@ class RunTree {
|
|
|
159
159
|
value: void 0
|
|
160
160
|
});
|
|
161
161
|
const defaultConfig = RunTree.getDefaultConfig();
|
|
162
|
+
const { metadata, ...config } = originalConfig;
|
|
162
163
|
const client = config.client ?? new client_js_1.Client();
|
|
164
|
+
const dedupedMetadata = {
|
|
165
|
+
...metadata,
|
|
166
|
+
...config?.extra?.metadata,
|
|
167
|
+
};
|
|
168
|
+
config.extra = { ...config.extra, metadata: dedupedMetadata };
|
|
163
169
|
Object.assign(this, { ...defaultConfig, ...config, client });
|
|
164
170
|
if (!this.trace_id) {
|
|
165
171
|
if (this.parent_run) {
|
|
@@ -191,7 +197,7 @@ class RunTree {
|
|
|
191
197
|
parentRun = langChainTracer?.getRun?.(parentRunId);
|
|
192
198
|
projectName = langChainTracer?.projectName;
|
|
193
199
|
}
|
|
194
|
-
const
|
|
200
|
+
const dedupedTags = [
|
|
195
201
|
...new Set((parentRun?.tags ?? []).concat(config?.tags ?? [])),
|
|
196
202
|
];
|
|
197
203
|
const dedupedMetadata = {
|
|
@@ -201,7 +207,7 @@ class RunTree {
|
|
|
201
207
|
const rt = new RunTree({
|
|
202
208
|
name: props?.name ?? "<lambda>",
|
|
203
209
|
parent_run: parentRun,
|
|
204
|
-
tags:
|
|
210
|
+
tags: dedupedTags,
|
|
205
211
|
extra: {
|
|
206
212
|
metadata: dedupedMetadata,
|
|
207
213
|
},
|
package/dist/run_trees.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface RunTreeConfig {
|
|
|
12
12
|
start_time?: number;
|
|
13
13
|
end_time?: number;
|
|
14
14
|
extra?: KVMap;
|
|
15
|
+
metadata?: KVMap;
|
|
15
16
|
tags?: string[];
|
|
16
17
|
error?: string;
|
|
17
18
|
serialized?: object;
|
|
@@ -57,7 +58,7 @@ export declare class RunTree implements BaseRun {
|
|
|
57
58
|
events?: KVMap[] | undefined;
|
|
58
59
|
trace_id: string;
|
|
59
60
|
dotted_order: string;
|
|
60
|
-
constructor(
|
|
61
|
+
constructor(originalConfig: RunTreeConfig);
|
|
61
62
|
static fromRunnableConfig(config: RunnableConfigLike, props: {
|
|
62
63
|
name: string;
|
|
63
64
|
tags?: string[];
|
package/dist/run_trees.js
CHANGED
|
@@ -16,7 +16,7 @@ export function convertToDottedOrderFormat(epoch, runId) {
|
|
|
16
16
|
runId);
|
|
17
17
|
}
|
|
18
18
|
export class RunTree {
|
|
19
|
-
constructor(
|
|
19
|
+
constructor(originalConfig) {
|
|
20
20
|
Object.defineProperty(this, "id", {
|
|
21
21
|
enumerable: true,
|
|
22
22
|
configurable: true,
|
|
@@ -132,7 +132,13 @@ export class RunTree {
|
|
|
132
132
|
value: void 0
|
|
133
133
|
});
|
|
134
134
|
const defaultConfig = RunTree.getDefaultConfig();
|
|
135
|
+
const { metadata, ...config } = originalConfig;
|
|
135
136
|
const client = config.client ?? new Client();
|
|
137
|
+
const dedupedMetadata = {
|
|
138
|
+
...metadata,
|
|
139
|
+
...config?.extra?.metadata,
|
|
140
|
+
};
|
|
141
|
+
config.extra = { ...config.extra, metadata: dedupedMetadata };
|
|
136
142
|
Object.assign(this, { ...defaultConfig, ...config, client });
|
|
137
143
|
if (!this.trace_id) {
|
|
138
144
|
if (this.parent_run) {
|
|
@@ -164,7 +170,7 @@ export class RunTree {
|
|
|
164
170
|
parentRun = langChainTracer?.getRun?.(parentRunId);
|
|
165
171
|
projectName = langChainTracer?.projectName;
|
|
166
172
|
}
|
|
167
|
-
const
|
|
173
|
+
const dedupedTags = [
|
|
168
174
|
...new Set((parentRun?.tags ?? []).concat(config?.tags ?? [])),
|
|
169
175
|
];
|
|
170
176
|
const dedupedMetadata = {
|
|
@@ -174,7 +180,7 @@ export class RunTree {
|
|
|
174
180
|
const rt = new RunTree({
|
|
175
181
|
name: props?.name ?? "<lambda>",
|
|
176
182
|
parent_run: parentRun,
|
|
177
|
-
tags:
|
|
183
|
+
tags: dedupedTags,
|
|
178
184
|
extra: {
|
|
179
185
|
metadata: dedupedMetadata,
|
|
180
186
|
},
|
package/dist/traceable.cjs
CHANGED
|
@@ -24,12 +24,13 @@ const isAsyncIterable = (x) => x != null &&
|
|
|
24
24
|
*/
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
26
|
function traceable(wrappedFunc, config) {
|
|
27
|
+
const { aggregator, ...runTreeConfig } = config ?? {};
|
|
27
28
|
const traceableFunc = async (...args) => {
|
|
28
29
|
let currentRunTree;
|
|
29
30
|
let rawInputs;
|
|
30
31
|
const ensuredConfig = {
|
|
31
32
|
name: wrappedFunc.name || "<lambda>",
|
|
32
|
-
...
|
|
33
|
+
...runTreeConfig,
|
|
33
34
|
};
|
|
34
35
|
const previousRunTree = asyncLocalStorage.getStore();
|
|
35
36
|
if ((0, run_trees_js_1.isRunTree)(args[0])) {
|
|
@@ -79,7 +80,26 @@ function traceable(wrappedFunc, config) {
|
|
|
79
80
|
chunks.push(chunk);
|
|
80
81
|
yield chunk;
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
+
let finalOutputs;
|
|
84
|
+
if (aggregator !== undefined) {
|
|
85
|
+
try {
|
|
86
|
+
finalOutputs = await aggregator(chunks);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
console.error(`[ERROR]: LangSmith aggregation failed: `, e);
|
|
90
|
+
finalOutputs = chunks;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
finalOutputs = chunks;
|
|
95
|
+
}
|
|
96
|
+
if (typeof finalOutputs === "object" &&
|
|
97
|
+
!Array.isArray(finalOutputs)) {
|
|
98
|
+
await currentRunTree.end(finalOutputs);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
await currentRunTree.end({ outputs: finalOutputs });
|
|
102
|
+
}
|
|
83
103
|
await currentRunTree.patchRun();
|
|
84
104
|
}
|
|
85
105
|
return resolve(wrapOutputForTracing());
|
|
@@ -112,7 +132,7 @@ function traceable(wrappedFunc, config) {
|
|
|
112
132
|
});
|
|
113
133
|
};
|
|
114
134
|
Object.defineProperty(traceableFunc, "langsmith:traceable", {
|
|
115
|
-
value:
|
|
135
|
+
value: runTreeConfig,
|
|
116
136
|
});
|
|
117
137
|
return traceableFunc;
|
|
118
138
|
}
|
package/dist/traceable.d.ts
CHANGED
|
@@ -44,7 +44,9 @@ export type TraceableFunction<Func extends (...args: any[]) => any> = Func exten
|
|
|
44
44
|
* @param config Additional metadata such as name, tags or providing
|
|
45
45
|
* a custom LangSmith client instance
|
|
46
46
|
*/
|
|
47
|
-
export declare function traceable<Func extends (...args: any[]) => any>(wrappedFunc: Func, config?: Partial<RunTreeConfig>
|
|
47
|
+
export declare function traceable<Func extends (...args: any[]) => any>(wrappedFunc: Func, config?: Partial<RunTreeConfig> & {
|
|
48
|
+
aggregator?: (args: any[]) => any;
|
|
49
|
+
}): TraceableFunction<Func>;
|
|
48
50
|
/**
|
|
49
51
|
* Return the current run tree from within a traceable-wrapped function.
|
|
50
52
|
* Will throw an error if called outside of a traceable function.
|
package/dist/traceable.js
CHANGED
|
@@ -21,12 +21,13 @@ const isAsyncIterable = (x) => x != null &&
|
|
|
21
21
|
*/
|
|
22
22
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
23
|
export function traceable(wrappedFunc, config) {
|
|
24
|
+
const { aggregator, ...runTreeConfig } = config ?? {};
|
|
24
25
|
const traceableFunc = async (...args) => {
|
|
25
26
|
let currentRunTree;
|
|
26
27
|
let rawInputs;
|
|
27
28
|
const ensuredConfig = {
|
|
28
29
|
name: wrappedFunc.name || "<lambda>",
|
|
29
|
-
...
|
|
30
|
+
...runTreeConfig,
|
|
30
31
|
};
|
|
31
32
|
const previousRunTree = asyncLocalStorage.getStore();
|
|
32
33
|
if (isRunTree(args[0])) {
|
|
@@ -76,7 +77,26 @@ export function traceable(wrappedFunc, config) {
|
|
|
76
77
|
chunks.push(chunk);
|
|
77
78
|
yield chunk;
|
|
78
79
|
}
|
|
79
|
-
|
|
80
|
+
let finalOutputs;
|
|
81
|
+
if (aggregator !== undefined) {
|
|
82
|
+
try {
|
|
83
|
+
finalOutputs = await aggregator(chunks);
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
console.error(`[ERROR]: LangSmith aggregation failed: `, e);
|
|
87
|
+
finalOutputs = chunks;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
finalOutputs = chunks;
|
|
92
|
+
}
|
|
93
|
+
if (typeof finalOutputs === "object" &&
|
|
94
|
+
!Array.isArray(finalOutputs)) {
|
|
95
|
+
await currentRunTree.end(finalOutputs);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
await currentRunTree.end({ outputs: finalOutputs });
|
|
99
|
+
}
|
|
80
100
|
await currentRunTree.patchRun();
|
|
81
101
|
}
|
|
82
102
|
return resolve(wrapOutputForTracing());
|
|
@@ -109,7 +129,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
109
129
|
});
|
|
110
130
|
};
|
|
111
131
|
Object.defineProperty(traceableFunc, "langsmith:traceable", {
|
|
112
|
-
value:
|
|
132
|
+
value: runTreeConfig,
|
|
113
133
|
});
|
|
114
134
|
return traceableFunc;
|
|
115
135
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./openai.cjs"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./openai.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./openai.js";
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapSDK = exports.wrapOpenAI = void 0;
|
|
4
|
+
const traceable_js_1 = require("../traceable.cjs");
|
|
5
|
+
function _combineChatCompletionChoices(choices) {
|
|
6
|
+
const reversedChoices = choices.slice().reverse();
|
|
7
|
+
const message = {
|
|
8
|
+
role: "assistant",
|
|
9
|
+
content: "",
|
|
10
|
+
};
|
|
11
|
+
for (const c of reversedChoices) {
|
|
12
|
+
if (c.delta.role) {
|
|
13
|
+
message["role"] = c.delta.role;
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const toolCalls = {};
|
|
18
|
+
for (const c of choices) {
|
|
19
|
+
if (c.delta.content) {
|
|
20
|
+
message.content = message.content.concat(c.delta.content);
|
|
21
|
+
}
|
|
22
|
+
if (c.delta.function_call) {
|
|
23
|
+
if (!message.function_call) {
|
|
24
|
+
message.function_call = { name: "", arguments: "" };
|
|
25
|
+
}
|
|
26
|
+
if (c.delta.function_call.name) {
|
|
27
|
+
message.function_call.name += c.delta.function_call.name;
|
|
28
|
+
}
|
|
29
|
+
if (c.delta.function_call.arguments) {
|
|
30
|
+
message.function_call.arguments += c.delta.function_call.arguments;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (c.delta.tool_calls) {
|
|
34
|
+
for (const tool_call of c.delta.tool_calls) {
|
|
35
|
+
if (!toolCalls[c.index]) {
|
|
36
|
+
toolCalls[c.index] = [];
|
|
37
|
+
}
|
|
38
|
+
toolCalls[c.index].push(tool_call);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (Object.keys(toolCalls).length > 0) {
|
|
43
|
+
message.tool_calls = [...Array(Object.keys(toolCalls).length)];
|
|
44
|
+
for (const [index, toolCallChunks] of Object.entries(toolCalls)) {
|
|
45
|
+
const idx = parseInt(index);
|
|
46
|
+
message.tool_calls[idx] = {
|
|
47
|
+
index: idx,
|
|
48
|
+
id: toolCallChunks.find((c) => c.id)?.id || null,
|
|
49
|
+
type: toolCallChunks.find((c) => c.type)?.type || null,
|
|
50
|
+
};
|
|
51
|
+
for (const chunk of toolCallChunks) {
|
|
52
|
+
if (chunk.function) {
|
|
53
|
+
if (!message.tool_calls[idx].function) {
|
|
54
|
+
message.tool_calls[idx].function = {
|
|
55
|
+
name: "",
|
|
56
|
+
arguments: "",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (chunk.function.name) {
|
|
60
|
+
message.tool_calls[idx].function.name += chunk.function.name;
|
|
61
|
+
}
|
|
62
|
+
if (chunk.function.arguments) {
|
|
63
|
+
message.tool_calls[idx].function.arguments +=
|
|
64
|
+
chunk.function.arguments;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
index: choices[0].index,
|
|
72
|
+
finish_reason: reversedChoices.find((c) => c.finish_reason) || null,
|
|
73
|
+
message: message,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
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));
|
|
87
|
+
}
|
|
88
|
+
else if (Object.keys(openAIOptions).length !== 0) {
|
|
89
|
+
finalArgs.push(openAIOptions);
|
|
90
|
+
}
|
|
91
|
+
return wrappedMethod(...finalArgs);
|
|
92
|
+
}
|
|
93
|
+
const wrappedMethod = (0, traceable_js_1.traceable)(openAIMethod, defaultRunConfig);
|
|
94
|
+
return wrappedMethod(...args);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
98
|
+
* tracing. Method signatures are unchanged, with the exception that you can pass
|
|
99
|
+
* an additional and optional "langsmithExtra" field within the second parameter.
|
|
100
|
+
* @param openai An OpenAI client instance.
|
|
101
|
+
* @param options LangSmith options.
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const patchedStream = await patchedClient.chat.completions.create(
|
|
105
|
+
* {
|
|
106
|
+
* messages: [{ role: "user", content: `Say 'foo'` }],
|
|
107
|
+
* model: "gpt-3.5-turbo",
|
|
108
|
+
* stream: true,
|
|
109
|
+
* },
|
|
110
|
+
* {
|
|
111
|
+
* langsmithExtra: {
|
|
112
|
+
* metadata: {
|
|
113
|
+
* additional_data: "bar",
|
|
114
|
+
* },
|
|
115
|
+
* },
|
|
116
|
+
* },
|
|
117
|
+
* );
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
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
|
+
};
|
|
176
|
+
return openai;
|
|
177
|
+
};
|
|
178
|
+
exports.wrapOpenAI = wrapOpenAI;
|
|
179
|
+
const _wrapClient = (sdk, runName, options) => {
|
|
180
|
+
return new Proxy(sdk, {
|
|
181
|
+
get(target, propKey, receiver) {
|
|
182
|
+
const originalValue = target[propKey];
|
|
183
|
+
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));
|
|
185
|
+
}
|
|
186
|
+
else if (originalValue != null &&
|
|
187
|
+
!Array.isArray(originalValue) &&
|
|
188
|
+
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
189
|
+
!(originalValue instanceof Date) &&
|
|
190
|
+
typeof originalValue === "object") {
|
|
191
|
+
return _wrapClient(originalValue, [runName, propKey.toString()].join("."), options);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
return Reflect.get(target, propKey, receiver);
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Wrap an arbitrary SDK, enabling automatic LangSmith tracing.
|
|
201
|
+
* Method signatures are unchanged.
|
|
202
|
+
*
|
|
203
|
+
* Note that this will wrap and trace ALL SDK methods, not just
|
|
204
|
+
* LLM completion methods. If the passed SDK contains other methods,
|
|
205
|
+
* we recommend using the wrapped instance for LLM calls only.
|
|
206
|
+
* @param sdk An arbitrary SDK instance.
|
|
207
|
+
* @param options LangSmith options.
|
|
208
|
+
* @returns
|
|
209
|
+
*/
|
|
210
|
+
const wrapSDK = (sdk, options) => {
|
|
211
|
+
return _wrapClient(sdk, options?.runName ?? sdk.constructor?.name, {
|
|
212
|
+
client: options?.client,
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
exports.wrapSDK = wrapSDK;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { OpenAI } from "openai";
|
|
2
|
+
import type { Client, RunTreeConfig } from "../index.js";
|
|
3
|
+
import { type RunnableConfigLike } from "../run_trees.js";
|
|
4
|
+
import { type RunTreeLike } from "../traceable.js";
|
|
5
|
+
type OpenAIType = {
|
|
6
|
+
chat: {
|
|
7
|
+
completions: {
|
|
8
|
+
create: (...args: any[]) => any;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
completions: {
|
|
12
|
+
create: (...args: any[]) => any;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type PatchedOpenAIClient<T extends OpenAIType> = {
|
|
16
|
+
[P in keyof T]: T[P];
|
|
17
|
+
} & {
|
|
18
|
+
chat: {
|
|
19
|
+
completions: {
|
|
20
|
+
create: {
|
|
21
|
+
(arg: OpenAI.ChatCompletionCreateParamsStreaming, arg2?: OpenAI.RequestOptions & {
|
|
22
|
+
langsmithExtra?: RunnableConfigLike | RunTreeLike;
|
|
23
|
+
}): Promise<AsyncGenerator<OpenAI.ChatCompletionChunk>>;
|
|
24
|
+
} & {
|
|
25
|
+
(arg: OpenAI.ChatCompletionCreateParamsNonStreaming, arg2?: OpenAI.RequestOptions & {
|
|
26
|
+
langsmithExtra?: RunnableConfigLike | RunTreeLike;
|
|
27
|
+
}): Promise<OpenAI.ChatCompletionChunk>;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
completions: {
|
|
32
|
+
create: {
|
|
33
|
+
(arg: OpenAI.CompletionCreateParamsStreaming, arg2?: OpenAI.RequestOptions & {
|
|
34
|
+
langsmithExtra?: RunnableConfigLike | RunTreeLike;
|
|
35
|
+
}): Promise<AsyncGenerator<OpenAI.Completion>>;
|
|
36
|
+
} & {
|
|
37
|
+
(arg: OpenAI.CompletionCreateParamsNonStreaming, arg2?: OpenAI.RequestOptions & {
|
|
38
|
+
langsmithExtra?: RunnableConfigLike | RunTreeLike;
|
|
39
|
+
}): Promise<OpenAI.Completion>;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
45
|
+
* tracing. Method signatures are unchanged, with the exception that you can pass
|
|
46
|
+
* an additional and optional "langsmithExtra" field within the second parameter.
|
|
47
|
+
* @param openai An OpenAI client instance.
|
|
48
|
+
* @param options LangSmith options.
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const patchedStream = await patchedClient.chat.completions.create(
|
|
52
|
+
* {
|
|
53
|
+
* messages: [{ role: "user", content: `Say 'foo'` }],
|
|
54
|
+
* model: "gpt-3.5-turbo",
|
|
55
|
+
* stream: true,
|
|
56
|
+
* },
|
|
57
|
+
* {
|
|
58
|
+
* langsmithExtra: {
|
|
59
|
+
* metadata: {
|
|
60
|
+
* additional_data: "bar",
|
|
61
|
+
* },
|
|
62
|
+
* },
|
|
63
|
+
* },
|
|
64
|
+
* );
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare const wrapOpenAI: <T extends OpenAIType>(openai: T, options?: Partial<RunTreeConfig>) => PatchedOpenAIClient<T>;
|
|
68
|
+
/**
|
|
69
|
+
* Wrap an arbitrary SDK, enabling automatic LangSmith tracing.
|
|
70
|
+
* Method signatures are unchanged.
|
|
71
|
+
*
|
|
72
|
+
* Note that this will wrap and trace ALL SDK methods, not just
|
|
73
|
+
* LLM completion methods. If the passed SDK contains other methods,
|
|
74
|
+
* we recommend using the wrapped instance for LLM calls only.
|
|
75
|
+
* @param sdk An arbitrary SDK instance.
|
|
76
|
+
* @param options LangSmith options.
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
export declare const wrapSDK: <T extends object>(sdk: T, options?: {
|
|
80
|
+
client?: Client;
|
|
81
|
+
runName?: string;
|
|
82
|
+
}) => T;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { traceable } from "../traceable.js";
|
|
2
|
+
function _combineChatCompletionChoices(choices) {
|
|
3
|
+
const reversedChoices = choices.slice().reverse();
|
|
4
|
+
const message = {
|
|
5
|
+
role: "assistant",
|
|
6
|
+
content: "",
|
|
7
|
+
};
|
|
8
|
+
for (const c of reversedChoices) {
|
|
9
|
+
if (c.delta.role) {
|
|
10
|
+
message["role"] = c.delta.role;
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const toolCalls = {};
|
|
15
|
+
for (const c of choices) {
|
|
16
|
+
if (c.delta.content) {
|
|
17
|
+
message.content = message.content.concat(c.delta.content);
|
|
18
|
+
}
|
|
19
|
+
if (c.delta.function_call) {
|
|
20
|
+
if (!message.function_call) {
|
|
21
|
+
message.function_call = { name: "", arguments: "" };
|
|
22
|
+
}
|
|
23
|
+
if (c.delta.function_call.name) {
|
|
24
|
+
message.function_call.name += c.delta.function_call.name;
|
|
25
|
+
}
|
|
26
|
+
if (c.delta.function_call.arguments) {
|
|
27
|
+
message.function_call.arguments += c.delta.function_call.arguments;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (c.delta.tool_calls) {
|
|
31
|
+
for (const tool_call of c.delta.tool_calls) {
|
|
32
|
+
if (!toolCalls[c.index]) {
|
|
33
|
+
toolCalls[c.index] = [];
|
|
34
|
+
}
|
|
35
|
+
toolCalls[c.index].push(tool_call);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (Object.keys(toolCalls).length > 0) {
|
|
40
|
+
message.tool_calls = [...Array(Object.keys(toolCalls).length)];
|
|
41
|
+
for (const [index, toolCallChunks] of Object.entries(toolCalls)) {
|
|
42
|
+
const idx = parseInt(index);
|
|
43
|
+
message.tool_calls[idx] = {
|
|
44
|
+
index: idx,
|
|
45
|
+
id: toolCallChunks.find((c) => c.id)?.id || null,
|
|
46
|
+
type: toolCallChunks.find((c) => c.type)?.type || null,
|
|
47
|
+
};
|
|
48
|
+
for (const chunk of toolCallChunks) {
|
|
49
|
+
if (chunk.function) {
|
|
50
|
+
if (!message.tool_calls[idx].function) {
|
|
51
|
+
message.tool_calls[idx].function = {
|
|
52
|
+
name: "",
|
|
53
|
+
arguments: "",
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (chunk.function.name) {
|
|
57
|
+
message.tool_calls[idx].function.name += chunk.function.name;
|
|
58
|
+
}
|
|
59
|
+
if (chunk.function.arguments) {
|
|
60
|
+
message.tool_calls[idx].function.arguments +=
|
|
61
|
+
chunk.function.arguments;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
index: choices[0].index,
|
|
69
|
+
finish_reason: reversedChoices.find((c) => c.finish_reason) || null,
|
|
70
|
+
message: message,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
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));
|
|
84
|
+
}
|
|
85
|
+
else if (Object.keys(openAIOptions).length !== 0) {
|
|
86
|
+
finalArgs.push(openAIOptions);
|
|
87
|
+
}
|
|
88
|
+
return wrappedMethod(...finalArgs);
|
|
89
|
+
}
|
|
90
|
+
const wrappedMethod = traceable(openAIMethod, defaultRunConfig);
|
|
91
|
+
return wrappedMethod(...args);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
95
|
+
* tracing. Method signatures are unchanged, with the exception that you can pass
|
|
96
|
+
* an additional and optional "langsmithExtra" field within the second parameter.
|
|
97
|
+
* @param openai An OpenAI client instance.
|
|
98
|
+
* @param options LangSmith options.
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* const patchedStream = await patchedClient.chat.completions.create(
|
|
102
|
+
* {
|
|
103
|
+
* messages: [{ role: "user", content: `Say 'foo'` }],
|
|
104
|
+
* model: "gpt-3.5-turbo",
|
|
105
|
+
* stream: true,
|
|
106
|
+
* },
|
|
107
|
+
* {
|
|
108
|
+
* langsmithExtra: {
|
|
109
|
+
* metadata: {
|
|
110
|
+
* additional_data: "bar",
|
|
111
|
+
* },
|
|
112
|
+
* },
|
|
113
|
+
* },
|
|
114
|
+
* );
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
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
|
+
};
|
|
173
|
+
return openai;
|
|
174
|
+
};
|
|
175
|
+
const _wrapClient = (sdk, runName, options) => {
|
|
176
|
+
return new Proxy(sdk, {
|
|
177
|
+
get(target, propKey, receiver) {
|
|
178
|
+
const originalValue = target[propKey];
|
|
179
|
+
if (typeof originalValue === "function") {
|
|
180
|
+
return traceable(originalValue.bind(target), Object.assign({ name: [runName, propKey.toString()].join("."), run_type: "llm" }, options?.client));
|
|
181
|
+
}
|
|
182
|
+
else if (originalValue != null &&
|
|
183
|
+
!Array.isArray(originalValue) &&
|
|
184
|
+
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
185
|
+
!(originalValue instanceof Date) &&
|
|
186
|
+
typeof originalValue === "object") {
|
|
187
|
+
return _wrapClient(originalValue, [runName, propKey.toString()].join("."), options);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
return Reflect.get(target, propKey, receiver);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Wrap an arbitrary SDK, enabling automatic LangSmith tracing.
|
|
197
|
+
* Method signatures are unchanged.
|
|
198
|
+
*
|
|
199
|
+
* Note that this will wrap and trace ALL SDK methods, not just
|
|
200
|
+
* LLM completion methods. If the passed SDK contains other methods,
|
|
201
|
+
* we recommend using the wrapped instance for LLM calls only.
|
|
202
|
+
* @param sdk An arbitrary SDK instance.
|
|
203
|
+
* @param options LangSmith options.
|
|
204
|
+
* @returns
|
|
205
|
+
*/
|
|
206
|
+
export const wrapSDK = (sdk, options) => {
|
|
207
|
+
return _wrapClient(sdk, options?.runName ?? sdk.constructor?.name, {
|
|
208
|
+
client: options?.client,
|
|
209
|
+
});
|
|
210
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "langsmith",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
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": [
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"wrappers.js",
|
|
30
30
|
"wrappers.d.ts",
|
|
31
31
|
"wrappers.d.cts",
|
|
32
|
+
"wrappers/openai.cjs",
|
|
33
|
+
"wrappers/openai.js",
|
|
34
|
+
"wrappers/openai.d.ts",
|
|
35
|
+
"wrappers/openai.d.cts",
|
|
32
36
|
"index.cjs",
|
|
33
37
|
"index.js",
|
|
34
38
|
"index.d.ts",
|
|
@@ -70,6 +74,13 @@
|
|
|
70
74
|
"url": "https://github.com/langchain-ai/langsmith-sdk/issues"
|
|
71
75
|
},
|
|
72
76
|
"homepage": "https://github.com/langchain-ai/langsmith-sdk#readme",
|
|
77
|
+
"dependencies": {
|
|
78
|
+
"@types/uuid": "^9.0.1",
|
|
79
|
+
"commander": "^10.0.1",
|
|
80
|
+
"p-queue": "^6.6.2",
|
|
81
|
+
"p-retry": "4",
|
|
82
|
+
"uuid": "^9.0.0"
|
|
83
|
+
},
|
|
73
84
|
"devDependencies": {
|
|
74
85
|
"@babel/preset-env": "^7.22.4",
|
|
75
86
|
"@jest/globals": "^29.5.0",
|
|
@@ -88,18 +99,19 @@
|
|
|
88
99
|
"eslint-plugin-no-instanceof": "^1.0.1",
|
|
89
100
|
"eslint-plugin-prettier": "^4.2.1",
|
|
90
101
|
"jest": "^29.5.0",
|
|
91
|
-
"openai": "^4.
|
|
102
|
+
"openai": "^4.38.5",
|
|
92
103
|
"prettier": "^2.8.8",
|
|
93
104
|
"ts-jest": "^29.1.0",
|
|
94
105
|
"ts-node": "^10.9.1",
|
|
95
106
|
"typescript": "^5.0.4"
|
|
96
107
|
},
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
"
|
|
102
|
-
|
|
108
|
+
"peerDependencies": {
|
|
109
|
+
"openai": "*"
|
|
110
|
+
},
|
|
111
|
+
"peerDependenciesMeta": {
|
|
112
|
+
"openai": {
|
|
113
|
+
"optional": true
|
|
114
|
+
}
|
|
103
115
|
},
|
|
104
116
|
"lint-staged": {
|
|
105
117
|
"**/*.{ts,tsx}": [
|
|
@@ -171,6 +183,15 @@
|
|
|
171
183
|
"import": "./wrappers.js",
|
|
172
184
|
"require": "./wrappers.cjs"
|
|
173
185
|
},
|
|
186
|
+
"./wrappers/openai": {
|
|
187
|
+
"types": {
|
|
188
|
+
"import": "./wrappers/openai.d.ts",
|
|
189
|
+
"require": "./wrappers/openai.d.cts",
|
|
190
|
+
"default": "./wrappers/openai.d.ts"
|
|
191
|
+
},
|
|
192
|
+
"import": "./wrappers/openai.js",
|
|
193
|
+
"require": "./wrappers/openai.cjs"
|
|
194
|
+
},
|
|
174
195
|
"./package.json": "./package.json"
|
|
175
196
|
}
|
|
176
197
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('../dist/wrappers/openai.cjs');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/wrappers/openai.js'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/wrappers/openai.js'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/wrappers/openai.js'
|
package/wrappers.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('./dist/wrappers.cjs');
|
|
1
|
+
module.exports = require('./dist/wrappers/index.cjs');
|
package/wrappers.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './dist/wrappers.js'
|
|
1
|
+
export * from './dist/wrappers/index.js'
|
package/wrappers.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './dist/wrappers.js'
|
|
1
|
+
export * from './dist/wrappers/index.js'
|
package/wrappers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './dist/wrappers.js'
|
|
1
|
+
export * from './dist/wrappers/index.js'
|
package/dist/wrappers.cjs
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.wrapSDK = exports.wrapOpenAI = void 0;
|
|
4
|
-
const traceable_js_1 = require("./traceable.cjs");
|
|
5
|
-
/**
|
|
6
|
-
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
7
|
-
* tracing. Method signatures are unchanged.
|
|
8
|
-
* @param openai An OpenAI client instance.
|
|
9
|
-
* @param options LangSmith options.
|
|
10
|
-
* @returns
|
|
11
|
-
*/
|
|
12
|
-
const wrapOpenAI = (openai, options) => {
|
|
13
|
-
openai.chat.completions.create = (0, traceable_js_1.traceable)(openai.chat.completions.create.bind(openai.chat.completions), Object.assign({ name: "ChatOpenAI", run_type: "llm" }, options?.client));
|
|
14
|
-
openai.completions.create = (0, traceable_js_1.traceable)(openai.completions.create.bind(openai.completions), Object.assign({ name: "OpenAI", run_type: "llm" }, options?.client));
|
|
15
|
-
return openai;
|
|
16
|
-
};
|
|
17
|
-
exports.wrapOpenAI = wrapOpenAI;
|
|
18
|
-
const _wrapClient = (sdk, runName, options) => {
|
|
19
|
-
return new Proxy(sdk, {
|
|
20
|
-
get(target, propKey, receiver) {
|
|
21
|
-
const originalValue = target[propKey];
|
|
22
|
-
if (typeof originalValue === "function") {
|
|
23
|
-
return (0, traceable_js_1.traceable)(originalValue.bind(target), Object.assign({ name: [runName, propKey.toString()].join("."), run_type: "llm" }, options?.client));
|
|
24
|
-
}
|
|
25
|
-
else if (originalValue != null &&
|
|
26
|
-
!Array.isArray(originalValue) &&
|
|
27
|
-
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
28
|
-
!(originalValue instanceof Date) &&
|
|
29
|
-
typeof originalValue === "object") {
|
|
30
|
-
return _wrapClient(originalValue, [runName, propKey.toString()].join("."), options);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
return Reflect.get(target, propKey, receiver);
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Wrap an arbitrary SDK, enabling automatic LangSmith tracing.
|
|
40
|
-
* Method signatures are unchanged.
|
|
41
|
-
*
|
|
42
|
-
* Note that this will wrap and trace ALL SDK methods, not just
|
|
43
|
-
* LLM completion methods. If the passed SDK contains other methods,
|
|
44
|
-
* we recommend using the wrapped instance for LLM calls only.
|
|
45
|
-
* @param sdk An arbitrary SDK instance.
|
|
46
|
-
* @param options LangSmith options.
|
|
47
|
-
* @returns
|
|
48
|
-
*/
|
|
49
|
-
const wrapSDK = (sdk, options) => {
|
|
50
|
-
return _wrapClient(sdk, options?.runName ?? sdk.constructor?.name, {
|
|
51
|
-
client: options?.client,
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
exports.wrapSDK = wrapSDK;
|
package/dist/wrappers.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { Client } from "./index.js";
|
|
2
|
-
type OpenAIType = {
|
|
3
|
-
chat: {
|
|
4
|
-
completions: {
|
|
5
|
-
create: (...args: any[]) => any;
|
|
6
|
-
};
|
|
7
|
-
};
|
|
8
|
-
completions: {
|
|
9
|
-
create: (...args: any[]) => any;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
14
|
-
* tracing. Method signatures are unchanged.
|
|
15
|
-
* @param openai An OpenAI client instance.
|
|
16
|
-
* @param options LangSmith options.
|
|
17
|
-
* @returns
|
|
18
|
-
*/
|
|
19
|
-
export declare const wrapOpenAI: <T extends OpenAIType>(openai: T, options?: {
|
|
20
|
-
client?: Client;
|
|
21
|
-
}) => T;
|
|
22
|
-
/**
|
|
23
|
-
* Wrap an arbitrary SDK, enabling automatic LangSmith tracing.
|
|
24
|
-
* Method signatures are unchanged.
|
|
25
|
-
*
|
|
26
|
-
* Note that this will wrap and trace ALL SDK methods, not just
|
|
27
|
-
* LLM completion methods. If the passed SDK contains other methods,
|
|
28
|
-
* we recommend using the wrapped instance for LLM calls only.
|
|
29
|
-
* @param sdk An arbitrary SDK instance.
|
|
30
|
-
* @param options LangSmith options.
|
|
31
|
-
* @returns
|
|
32
|
-
*/
|
|
33
|
-
export declare const wrapSDK: <T extends object>(sdk: T, options?: {
|
|
34
|
-
client?: Client;
|
|
35
|
-
runName?: string;
|
|
36
|
-
}) => T;
|
|
37
|
-
export {};
|
package/dist/wrappers.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { traceable } from "./traceable.js";
|
|
2
|
-
/**
|
|
3
|
-
* Wraps an OpenAI client's completion methods, enabling automatic LangSmith
|
|
4
|
-
* tracing. Method signatures are unchanged.
|
|
5
|
-
* @param openai An OpenAI client instance.
|
|
6
|
-
* @param options LangSmith options.
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
|
-
export const wrapOpenAI = (openai, options) => {
|
|
10
|
-
openai.chat.completions.create = traceable(openai.chat.completions.create.bind(openai.chat.completions), Object.assign({ name: "ChatOpenAI", run_type: "llm" }, options?.client));
|
|
11
|
-
openai.completions.create = traceable(openai.completions.create.bind(openai.completions), Object.assign({ name: "OpenAI", run_type: "llm" }, options?.client));
|
|
12
|
-
return openai;
|
|
13
|
-
};
|
|
14
|
-
const _wrapClient = (sdk, runName, options) => {
|
|
15
|
-
return new Proxy(sdk, {
|
|
16
|
-
get(target, propKey, receiver) {
|
|
17
|
-
const originalValue = target[propKey];
|
|
18
|
-
if (typeof originalValue === "function") {
|
|
19
|
-
return traceable(originalValue.bind(target), Object.assign({ name: [runName, propKey.toString()].join("."), run_type: "llm" }, options?.client));
|
|
20
|
-
}
|
|
21
|
-
else if (originalValue != null &&
|
|
22
|
-
!Array.isArray(originalValue) &&
|
|
23
|
-
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
24
|
-
!(originalValue instanceof Date) &&
|
|
25
|
-
typeof originalValue === "object") {
|
|
26
|
-
return _wrapClient(originalValue, [runName, propKey.toString()].join("."), options);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
return Reflect.get(target, propKey, receiver);
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Wrap an arbitrary SDK, enabling automatic LangSmith tracing.
|
|
36
|
-
* Method signatures are unchanged.
|
|
37
|
-
*
|
|
38
|
-
* Note that this will wrap and trace ALL SDK methods, not just
|
|
39
|
-
* LLM completion methods. If the passed SDK contains other methods,
|
|
40
|
-
* we recommend using the wrapped instance for LLM calls only.
|
|
41
|
-
* @param sdk An arbitrary SDK instance.
|
|
42
|
-
* @param options LangSmith options.
|
|
43
|
-
* @returns
|
|
44
|
-
*/
|
|
45
|
-
export const wrapSDK = (sdk, options) => {
|
|
46
|
-
return _wrapClient(sdk, options?.runName ?? sdk.constructor?.name, {
|
|
47
|
-
client: options?.client,
|
|
48
|
-
});
|
|
49
|
-
};
|