langsmith 0.1.12 → 0.1.14
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/README.md +32 -0
- package/dist/client.cjs +69 -1
- package/dist/client.d.ts +12 -2
- package/dist/client.js +69 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/schemas.d.ts +5 -0
- package/dist/wrappers.cjs +45 -3
- package/dist/wrappers.d.ts +35 -3
- package/dist/wrappers.js +43 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -292,6 +292,38 @@ export async function POST(req: Request) {
|
|
|
292
292
|
|
|
293
293
|
See the [AI SDK docs](https://sdk.vercel.ai/docs) for more examples.
|
|
294
294
|
|
|
295
|
+
## Arbitrary SDKs
|
|
296
|
+
|
|
297
|
+
You can use the generic `wrapSDK` method to add tracing for arbitrary SDKs.
|
|
298
|
+
|
|
299
|
+
Do note that this will trace ALL methods in the SDK, not just chat completion endpoints.
|
|
300
|
+
If the SDK you are wrapping has other methods, we recommend using it for only LLM calls.
|
|
301
|
+
|
|
302
|
+
Here's an example using the Anthropic SDK:
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
import { wrapSDK } from "langsmith/wrappers";
|
|
306
|
+
import { Anthropic } from "@anthropic-ai/sdk";
|
|
307
|
+
|
|
308
|
+
const originalSDK = new Anthropic();
|
|
309
|
+
const sdkWithTracing = wrapSDK(originalSDK);
|
|
310
|
+
|
|
311
|
+
const response = await sdkWithTracing.messages.create({
|
|
312
|
+
messages: [
|
|
313
|
+
{
|
|
314
|
+
role: "user",
|
|
315
|
+
content: `What is 1 + 1? Respond only with "2" and nothing else.`,
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
model: "claude-3-sonnet-20240229",
|
|
319
|
+
max_tokens: 1024,
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
:::tip
|
|
324
|
+
[Click here](https://smith.langchain.com/public/0e7248af-bbed-47cf-be9f-5967fea1dec1/r) to see an example LangSmith trace of the above.
|
|
325
|
+
:::
|
|
326
|
+
|
|
295
327
|
#### Alternatives: **Log traces using a RunTree.**
|
|
296
328
|
|
|
297
329
|
A RunTree tracks your application. Each RunTree object is required to have a name and run_type. These and other important attributes are as follows:
|
package/dist/client.cjs
CHANGED
|
@@ -265,6 +265,12 @@ class Client {
|
|
|
265
265
|
writable: true,
|
|
266
266
|
value: void 0
|
|
267
267
|
});
|
|
268
|
+
Object.defineProperty(this, "fetchOptions", {
|
|
269
|
+
enumerable: true,
|
|
270
|
+
configurable: true,
|
|
271
|
+
writable: true,
|
|
272
|
+
value: void 0
|
|
273
|
+
});
|
|
268
274
|
const defaultConfig = Client.getDefaultClientConfig();
|
|
269
275
|
this.tracingSampleRate = getTracingSamplingRate();
|
|
270
276
|
this.apiUrl = trimQuotes(config.apiUrl ?? defaultConfig.apiUrl) ?? "";
|
|
@@ -281,6 +287,7 @@ class Client {
|
|
|
281
287
|
this.autoBatchTracing = config.autoBatchTracing ?? this.autoBatchTracing;
|
|
282
288
|
this.pendingAutoBatchedRunLimit =
|
|
283
289
|
config.pendingAutoBatchedRunLimit ?? this.pendingAutoBatchedRunLimit;
|
|
290
|
+
this.fetchOptions = config.fetchOptions || {};
|
|
284
291
|
}
|
|
285
292
|
static getDefaultClientConfig() {
|
|
286
293
|
const apiKey = (0, env_js_1.getEnvironmentVariable)("LANGCHAIN_API_KEY");
|
|
@@ -368,6 +375,7 @@ class Client {
|
|
|
368
375
|
method: "GET",
|
|
369
376
|
headers: this.headers,
|
|
370
377
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
378
|
+
...this.fetchOptions,
|
|
371
379
|
});
|
|
372
380
|
if (!response.ok) {
|
|
373
381
|
throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -389,6 +397,7 @@ class Client {
|
|
|
389
397
|
method: "GET",
|
|
390
398
|
headers: this.headers,
|
|
391
399
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
400
|
+
...this.fetchOptions,
|
|
392
401
|
});
|
|
393
402
|
if (!response.ok) {
|
|
394
403
|
throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -411,6 +420,7 @@ class Client {
|
|
|
411
420
|
method: requestMethod,
|
|
412
421
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
413
422
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
423
|
+
...this.fetchOptions,
|
|
414
424
|
body: JSON.stringify(bodyParams),
|
|
415
425
|
});
|
|
416
426
|
const responseBody = await response.json();
|
|
@@ -504,6 +514,7 @@ class Client {
|
|
|
504
514
|
method: "GET",
|
|
505
515
|
headers: { Accept: "application/json" },
|
|
506
516
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
517
|
+
...this.fetchOptions,
|
|
507
518
|
});
|
|
508
519
|
if (!response.ok) {
|
|
509
520
|
// consume the response body to release the connection
|
|
@@ -551,6 +562,7 @@ class Client {
|
|
|
551
562
|
headers,
|
|
552
563
|
body: JSON.stringify(mergedRunCreateParams[0]),
|
|
553
564
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
565
|
+
...this.fetchOptions,
|
|
554
566
|
});
|
|
555
567
|
await raiseForStatus(response, "create run");
|
|
556
568
|
}
|
|
@@ -650,6 +662,7 @@ class Client {
|
|
|
650
662
|
headers,
|
|
651
663
|
body: body,
|
|
652
664
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
665
|
+
...this.fetchOptions,
|
|
653
666
|
});
|
|
654
667
|
await raiseForStatus(response, "batch create run");
|
|
655
668
|
}
|
|
@@ -686,6 +699,7 @@ class Client {
|
|
|
686
699
|
headers,
|
|
687
700
|
body: JSON.stringify(run),
|
|
688
701
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
702
|
+
...this.fetchOptions,
|
|
689
703
|
});
|
|
690
704
|
await raiseForStatus(response, "update run");
|
|
691
705
|
}
|
|
@@ -880,6 +894,7 @@ class Client {
|
|
|
880
894
|
headers: this.headers,
|
|
881
895
|
body: JSON.stringify(data),
|
|
882
896
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
897
|
+
...this.fetchOptions,
|
|
883
898
|
});
|
|
884
899
|
const result = await response.json();
|
|
885
900
|
if (result === null || !("share_token" in result)) {
|
|
@@ -893,6 +908,7 @@ class Client {
|
|
|
893
908
|
method: "DELETE",
|
|
894
909
|
headers: this.headers,
|
|
895
910
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
911
|
+
...this.fetchOptions,
|
|
896
912
|
});
|
|
897
913
|
await raiseForStatus(response, "unshare run");
|
|
898
914
|
}
|
|
@@ -902,6 +918,7 @@ class Client {
|
|
|
902
918
|
method: "GET",
|
|
903
919
|
headers: this.headers,
|
|
904
920
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
921
|
+
...this.fetchOptions,
|
|
905
922
|
});
|
|
906
923
|
const result = await response.json();
|
|
907
924
|
if (result === null || !("share_token" in result)) {
|
|
@@ -923,6 +940,7 @@ class Client {
|
|
|
923
940
|
method: "GET",
|
|
924
941
|
headers: this.headers,
|
|
925
942
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
943
|
+
...this.fetchOptions,
|
|
926
944
|
});
|
|
927
945
|
const runs = await response.json();
|
|
928
946
|
return runs;
|
|
@@ -940,6 +958,7 @@ class Client {
|
|
|
940
958
|
method: "GET",
|
|
941
959
|
headers: this.headers,
|
|
942
960
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
961
|
+
...this.fetchOptions,
|
|
943
962
|
});
|
|
944
963
|
const shareSchema = await response.json();
|
|
945
964
|
shareSchema.url = `${this.getHostUrl()}/public/${shareSchema.share_token}/d`;
|
|
@@ -962,6 +981,7 @@ class Client {
|
|
|
962
981
|
headers: this.headers,
|
|
963
982
|
body: JSON.stringify(data),
|
|
964
983
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
984
|
+
...this.fetchOptions,
|
|
965
985
|
});
|
|
966
986
|
const shareSchema = await response.json();
|
|
967
987
|
shareSchema.url = `${this.getHostUrl()}/public/${shareSchema.share_token}/d`;
|
|
@@ -973,6 +993,7 @@ class Client {
|
|
|
973
993
|
method: "DELETE",
|
|
974
994
|
headers: this.headers,
|
|
975
995
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
996
|
+
...this.fetchOptions,
|
|
976
997
|
});
|
|
977
998
|
await raiseForStatus(response, "unshare dataset");
|
|
978
999
|
}
|
|
@@ -982,6 +1003,7 @@ class Client {
|
|
|
982
1003
|
method: "GET",
|
|
983
1004
|
headers: this.headers,
|
|
984
1005
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1006
|
+
...this.fetchOptions,
|
|
985
1007
|
});
|
|
986
1008
|
const dataset = await response.json();
|
|
987
1009
|
return dataset;
|
|
@@ -1006,6 +1028,7 @@ class Client {
|
|
|
1006
1028
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1007
1029
|
body: JSON.stringify(body),
|
|
1008
1030
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1031
|
+
...this.fetchOptions,
|
|
1009
1032
|
});
|
|
1010
1033
|
const result = await response.json();
|
|
1011
1034
|
if (!response.ok) {
|
|
@@ -1030,6 +1053,7 @@ class Client {
|
|
|
1030
1053
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1031
1054
|
body: JSON.stringify(body),
|
|
1032
1055
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1056
|
+
...this.fetchOptions,
|
|
1033
1057
|
});
|
|
1034
1058
|
const result = await response.json();
|
|
1035
1059
|
if (!response.ok) {
|
|
@@ -1058,6 +1082,7 @@ class Client {
|
|
|
1058
1082
|
method: "GET",
|
|
1059
1083
|
headers: this.headers,
|
|
1060
1084
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1085
|
+
...this.fetchOptions,
|
|
1061
1086
|
});
|
|
1062
1087
|
// consume the response body to release the connection
|
|
1063
1088
|
// https://undici.nodejs.org/#/?id=garbage-collection
|
|
@@ -1168,6 +1193,7 @@ class Client {
|
|
|
1168
1193
|
method: "DELETE",
|
|
1169
1194
|
headers: this.headers,
|
|
1170
1195
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1196
|
+
...this.fetchOptions,
|
|
1171
1197
|
});
|
|
1172
1198
|
await raiseForStatus(response, `delete session ${projectId_} (${projectName})`);
|
|
1173
1199
|
}
|
|
@@ -1195,6 +1221,7 @@ class Client {
|
|
|
1195
1221
|
headers: this.headers,
|
|
1196
1222
|
body: formData,
|
|
1197
1223
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1224
|
+
...this.fetchOptions,
|
|
1198
1225
|
});
|
|
1199
1226
|
if (!response.ok) {
|
|
1200
1227
|
const result = await response.json();
|
|
@@ -1219,6 +1246,7 @@ class Client {
|
|
|
1219
1246
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1220
1247
|
body: JSON.stringify(body),
|
|
1221
1248
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1249
|
+
...this.fetchOptions,
|
|
1222
1250
|
});
|
|
1223
1251
|
if (!response.ok) {
|
|
1224
1252
|
const result = await response.json();
|
|
@@ -1260,6 +1288,27 @@ class Client {
|
|
|
1260
1288
|
}
|
|
1261
1289
|
return result;
|
|
1262
1290
|
}
|
|
1291
|
+
async diffDatasetVersions({ datasetId, datasetName, fromVersion, toVersion, }) {
|
|
1292
|
+
let datasetId_ = datasetId;
|
|
1293
|
+
if (datasetId_ === undefined && datasetName === undefined) {
|
|
1294
|
+
throw new Error("Must provide either datasetName or datasetId");
|
|
1295
|
+
}
|
|
1296
|
+
else if (datasetId_ !== undefined && datasetName !== undefined) {
|
|
1297
|
+
throw new Error("Must provide either datasetName or datasetId, not both");
|
|
1298
|
+
}
|
|
1299
|
+
else if (datasetId_ === undefined) {
|
|
1300
|
+
const dataset = await this.readDataset({ datasetName });
|
|
1301
|
+
datasetId_ = dataset.id;
|
|
1302
|
+
}
|
|
1303
|
+
const urlParams = new URLSearchParams({
|
|
1304
|
+
from_version: typeof fromVersion === "string"
|
|
1305
|
+
? fromVersion
|
|
1306
|
+
: fromVersion.toISOString(),
|
|
1307
|
+
to_version: typeof toVersion === "string" ? toVersion : toVersion.toISOString(),
|
|
1308
|
+
});
|
|
1309
|
+
const response = await this._get(`/datasets/${datasetId_}/versions/diff`, urlParams);
|
|
1310
|
+
return response;
|
|
1311
|
+
}
|
|
1263
1312
|
async readDatasetOpenaiFinetuning({ datasetId, datasetName, }) {
|
|
1264
1313
|
const path = "/datasets";
|
|
1265
1314
|
if (datasetId !== undefined) {
|
|
@@ -1321,6 +1370,7 @@ class Client {
|
|
|
1321
1370
|
method: "DELETE",
|
|
1322
1371
|
headers: this.headers,
|
|
1323
1372
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1373
|
+
...this.fetchOptions,
|
|
1324
1374
|
});
|
|
1325
1375
|
if (!response.ok) {
|
|
1326
1376
|
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -1352,6 +1402,7 @@ class Client {
|
|
|
1352
1402
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1353
1403
|
body: JSON.stringify(data),
|
|
1354
1404
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1405
|
+
...this.fetchOptions,
|
|
1355
1406
|
});
|
|
1356
1407
|
if (!response.ok) {
|
|
1357
1408
|
throw new Error(`Failed to create example: ${response.status} ${response.statusText}`);
|
|
@@ -1386,6 +1437,7 @@ class Client {
|
|
|
1386
1437
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1387
1438
|
body: JSON.stringify(formattedExamples),
|
|
1388
1439
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1440
|
+
...this.fetchOptions,
|
|
1389
1441
|
});
|
|
1390
1442
|
if (!response.ok) {
|
|
1391
1443
|
throw new Error(`Failed to create examples: ${response.status} ${response.statusText}`);
|
|
@@ -1413,7 +1465,7 @@ class Client {
|
|
|
1413
1465
|
const path = `/examples/${exampleId}`;
|
|
1414
1466
|
return await this._get(path);
|
|
1415
1467
|
}
|
|
1416
|
-
async *listExamples({ datasetId, datasetName, exampleIds, } = {}) {
|
|
1468
|
+
async *listExamples({ datasetId, datasetName, exampleIds, asOf, inlineS3Urls, } = {}) {
|
|
1417
1469
|
let datasetId_;
|
|
1418
1470
|
if (datasetId !== undefined && datasetName !== undefined) {
|
|
1419
1471
|
throw new Error("Must provide either datasetName or datasetId, not both");
|
|
@@ -1429,6 +1481,16 @@ class Client {
|
|
|
1429
1481
|
throw new Error("Must provide a datasetName or datasetId");
|
|
1430
1482
|
}
|
|
1431
1483
|
const params = new URLSearchParams({ dataset: datasetId_ });
|
|
1484
|
+
const dataset_version = asOf
|
|
1485
|
+
? typeof asOf === "string"
|
|
1486
|
+
? asOf
|
|
1487
|
+
: asOf?.toISOString()
|
|
1488
|
+
: undefined;
|
|
1489
|
+
if (dataset_version) {
|
|
1490
|
+
params.append("as_of", dataset_version);
|
|
1491
|
+
}
|
|
1492
|
+
const inlineS3Urls_ = inlineS3Urls ?? true;
|
|
1493
|
+
params.append("inline_s3_urls", inlineS3Urls_.toString());
|
|
1432
1494
|
if (exampleIds !== undefined) {
|
|
1433
1495
|
for (const id_ of exampleIds) {
|
|
1434
1496
|
params.append("id", id_);
|
|
@@ -1445,6 +1507,7 @@ class Client {
|
|
|
1445
1507
|
method: "DELETE",
|
|
1446
1508
|
headers: this.headers,
|
|
1447
1509
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1510
|
+
...this.fetchOptions,
|
|
1448
1511
|
});
|
|
1449
1512
|
if (!response.ok) {
|
|
1450
1513
|
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -1458,6 +1521,7 @@ class Client {
|
|
|
1458
1521
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1459
1522
|
body: JSON.stringify(update),
|
|
1460
1523
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1524
|
+
...this.fetchOptions,
|
|
1461
1525
|
});
|
|
1462
1526
|
if (!response.ok) {
|
|
1463
1527
|
throw new Error(`Failed to update example ${exampleId}: ${response.status} ${response.statusText}`);
|
|
@@ -1527,6 +1591,7 @@ class Client {
|
|
|
1527
1591
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1528
1592
|
body: JSON.stringify(feedback),
|
|
1529
1593
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1594
|
+
...this.fetchOptions,
|
|
1530
1595
|
});
|
|
1531
1596
|
await raiseForStatus(response, "create feedback");
|
|
1532
1597
|
return feedback;
|
|
@@ -1551,6 +1616,7 @@ class Client {
|
|
|
1551
1616
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1552
1617
|
body: JSON.stringify(feedbackUpdate),
|
|
1553
1618
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1619
|
+
...this.fetchOptions,
|
|
1554
1620
|
});
|
|
1555
1621
|
await raiseForStatus(response, "update feedback");
|
|
1556
1622
|
}
|
|
@@ -1567,6 +1633,7 @@ class Client {
|
|
|
1567
1633
|
method: "DELETE",
|
|
1568
1634
|
headers: this.headers,
|
|
1569
1635
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1636
|
+
...this.fetchOptions,
|
|
1570
1637
|
});
|
|
1571
1638
|
if (!response.ok) {
|
|
1572
1639
|
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -1631,6 +1698,7 @@ class Client {
|
|
|
1631
1698
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1632
1699
|
body: JSON.stringify(body),
|
|
1633
1700
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1701
|
+
...this.fetchOptions,
|
|
1634
1702
|
});
|
|
1635
1703
|
const result = await response.json();
|
|
1636
1704
|
return result;
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AsyncCallerParams } from "./utils/async_caller.js";
|
|
2
|
-
import { DataType, Dataset, DatasetShareSchema, Example, ExampleUpdate, Feedback, FeedbackConfig, FeedbackIngestToken, KVMap, LangChainBaseMessage, Run, RunCreate, RunUpdate, ScoreType, TimeDelta, TracerSession, TracerSessionResult, ValueType } from "./schemas.js";
|
|
2
|
+
import { DataType, Dataset, DatasetDiffInfo, DatasetShareSchema, Example, ExampleUpdate, Feedback, FeedbackConfig, FeedbackIngestToken, KVMap, LangChainBaseMessage, Run, RunCreate, RunUpdate, ScoreType, TimeDelta, TracerSession, TracerSessionResult, ValueType } from "./schemas.js";
|
|
3
3
|
import { RunEvaluator } from "./evaluation/evaluator.js";
|
|
4
4
|
interface ClientConfig {
|
|
5
5
|
apiUrl?: string;
|
|
@@ -11,6 +11,7 @@ interface ClientConfig {
|
|
|
11
11
|
hideOutputs?: boolean;
|
|
12
12
|
autoBatchTracing?: boolean;
|
|
13
13
|
pendingAutoBatchedRunLimit?: number;
|
|
14
|
+
fetchOptions?: RequestInit;
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* Represents the parameters for listing runs (spans) from the Langsmith server.
|
|
@@ -162,6 +163,7 @@ export declare class Client {
|
|
|
162
163
|
private autoBatchInitialDelayMs;
|
|
163
164
|
private autoBatchAggregationDelayMs;
|
|
164
165
|
private serverInfo;
|
|
166
|
+
private fetchOptions;
|
|
165
167
|
constructor(config?: ClientConfig);
|
|
166
168
|
static getDefaultClientConfig(): {
|
|
167
169
|
apiUrl: string;
|
|
@@ -344,6 +346,12 @@ export declare class Client {
|
|
|
344
346
|
datasetId?: string;
|
|
345
347
|
datasetName?: string;
|
|
346
348
|
}): Promise<Dataset>;
|
|
349
|
+
diffDatasetVersions({ datasetId, datasetName, fromVersion, toVersion, }: {
|
|
350
|
+
datasetId?: string;
|
|
351
|
+
datasetName?: string;
|
|
352
|
+
fromVersion: string | Date;
|
|
353
|
+
toVersion: string | Date;
|
|
354
|
+
}): Promise<DatasetDiffInfo>;
|
|
347
355
|
readDatasetOpenaiFinetuning({ datasetId, datasetName, }: {
|
|
348
356
|
datasetId?: string;
|
|
349
357
|
datasetName?: string;
|
|
@@ -371,10 +379,12 @@ export declare class Client {
|
|
|
371
379
|
createLLMExample(input: string, generation: string | undefined, options: CreateExampleOptions): Promise<Example>;
|
|
372
380
|
createChatExample(input: KVMap[] | LangChainBaseMessage[], generations: KVMap | LangChainBaseMessage | undefined, options: CreateExampleOptions): Promise<Example>;
|
|
373
381
|
readExample(exampleId: string): Promise<Example>;
|
|
374
|
-
listExamples({ datasetId, datasetName, exampleIds, }?: {
|
|
382
|
+
listExamples({ datasetId, datasetName, exampleIds, asOf, inlineS3Urls, }?: {
|
|
375
383
|
datasetId?: string;
|
|
376
384
|
datasetName?: string;
|
|
377
385
|
exampleIds?: string[];
|
|
386
|
+
asOf?: string | Date;
|
|
387
|
+
inlineS3Urls?: boolean;
|
|
378
388
|
}): AsyncIterable<Example>;
|
|
379
389
|
deleteExample(exampleId: string): Promise<void>;
|
|
380
390
|
updateExample(exampleId: string, update: ExampleUpdate): Promise<object>;
|
package/dist/client.js
CHANGED
|
@@ -238,6 +238,12 @@ export class Client {
|
|
|
238
238
|
writable: true,
|
|
239
239
|
value: void 0
|
|
240
240
|
});
|
|
241
|
+
Object.defineProperty(this, "fetchOptions", {
|
|
242
|
+
enumerable: true,
|
|
243
|
+
configurable: true,
|
|
244
|
+
writable: true,
|
|
245
|
+
value: void 0
|
|
246
|
+
});
|
|
241
247
|
const defaultConfig = Client.getDefaultClientConfig();
|
|
242
248
|
this.tracingSampleRate = getTracingSamplingRate();
|
|
243
249
|
this.apiUrl = trimQuotes(config.apiUrl ?? defaultConfig.apiUrl) ?? "";
|
|
@@ -254,6 +260,7 @@ export class Client {
|
|
|
254
260
|
this.autoBatchTracing = config.autoBatchTracing ?? this.autoBatchTracing;
|
|
255
261
|
this.pendingAutoBatchedRunLimit =
|
|
256
262
|
config.pendingAutoBatchedRunLimit ?? this.pendingAutoBatchedRunLimit;
|
|
263
|
+
this.fetchOptions = config.fetchOptions || {};
|
|
257
264
|
}
|
|
258
265
|
static getDefaultClientConfig() {
|
|
259
266
|
const apiKey = getEnvironmentVariable("LANGCHAIN_API_KEY");
|
|
@@ -341,6 +348,7 @@ export class Client {
|
|
|
341
348
|
method: "GET",
|
|
342
349
|
headers: this.headers,
|
|
343
350
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
351
|
+
...this.fetchOptions,
|
|
344
352
|
});
|
|
345
353
|
if (!response.ok) {
|
|
346
354
|
throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -362,6 +370,7 @@ export class Client {
|
|
|
362
370
|
method: "GET",
|
|
363
371
|
headers: this.headers,
|
|
364
372
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
373
|
+
...this.fetchOptions,
|
|
365
374
|
});
|
|
366
375
|
if (!response.ok) {
|
|
367
376
|
throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -384,6 +393,7 @@ export class Client {
|
|
|
384
393
|
method: requestMethod,
|
|
385
394
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
386
395
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
396
|
+
...this.fetchOptions,
|
|
387
397
|
body: JSON.stringify(bodyParams),
|
|
388
398
|
});
|
|
389
399
|
const responseBody = await response.json();
|
|
@@ -477,6 +487,7 @@ export class Client {
|
|
|
477
487
|
method: "GET",
|
|
478
488
|
headers: { Accept: "application/json" },
|
|
479
489
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
490
|
+
...this.fetchOptions,
|
|
480
491
|
});
|
|
481
492
|
if (!response.ok) {
|
|
482
493
|
// consume the response body to release the connection
|
|
@@ -524,6 +535,7 @@ export class Client {
|
|
|
524
535
|
headers,
|
|
525
536
|
body: JSON.stringify(mergedRunCreateParams[0]),
|
|
526
537
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
538
|
+
...this.fetchOptions,
|
|
527
539
|
});
|
|
528
540
|
await raiseForStatus(response, "create run");
|
|
529
541
|
}
|
|
@@ -623,6 +635,7 @@ export class Client {
|
|
|
623
635
|
headers,
|
|
624
636
|
body: body,
|
|
625
637
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
638
|
+
...this.fetchOptions,
|
|
626
639
|
});
|
|
627
640
|
await raiseForStatus(response, "batch create run");
|
|
628
641
|
}
|
|
@@ -659,6 +672,7 @@ export class Client {
|
|
|
659
672
|
headers,
|
|
660
673
|
body: JSON.stringify(run),
|
|
661
674
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
675
|
+
...this.fetchOptions,
|
|
662
676
|
});
|
|
663
677
|
await raiseForStatus(response, "update run");
|
|
664
678
|
}
|
|
@@ -853,6 +867,7 @@ export class Client {
|
|
|
853
867
|
headers: this.headers,
|
|
854
868
|
body: JSON.stringify(data),
|
|
855
869
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
870
|
+
...this.fetchOptions,
|
|
856
871
|
});
|
|
857
872
|
const result = await response.json();
|
|
858
873
|
if (result === null || !("share_token" in result)) {
|
|
@@ -866,6 +881,7 @@ export class Client {
|
|
|
866
881
|
method: "DELETE",
|
|
867
882
|
headers: this.headers,
|
|
868
883
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
884
|
+
...this.fetchOptions,
|
|
869
885
|
});
|
|
870
886
|
await raiseForStatus(response, "unshare run");
|
|
871
887
|
}
|
|
@@ -875,6 +891,7 @@ export class Client {
|
|
|
875
891
|
method: "GET",
|
|
876
892
|
headers: this.headers,
|
|
877
893
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
894
|
+
...this.fetchOptions,
|
|
878
895
|
});
|
|
879
896
|
const result = await response.json();
|
|
880
897
|
if (result === null || !("share_token" in result)) {
|
|
@@ -896,6 +913,7 @@ export class Client {
|
|
|
896
913
|
method: "GET",
|
|
897
914
|
headers: this.headers,
|
|
898
915
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
916
|
+
...this.fetchOptions,
|
|
899
917
|
});
|
|
900
918
|
const runs = await response.json();
|
|
901
919
|
return runs;
|
|
@@ -913,6 +931,7 @@ export class Client {
|
|
|
913
931
|
method: "GET",
|
|
914
932
|
headers: this.headers,
|
|
915
933
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
934
|
+
...this.fetchOptions,
|
|
916
935
|
});
|
|
917
936
|
const shareSchema = await response.json();
|
|
918
937
|
shareSchema.url = `${this.getHostUrl()}/public/${shareSchema.share_token}/d`;
|
|
@@ -935,6 +954,7 @@ export class Client {
|
|
|
935
954
|
headers: this.headers,
|
|
936
955
|
body: JSON.stringify(data),
|
|
937
956
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
957
|
+
...this.fetchOptions,
|
|
938
958
|
});
|
|
939
959
|
const shareSchema = await response.json();
|
|
940
960
|
shareSchema.url = `${this.getHostUrl()}/public/${shareSchema.share_token}/d`;
|
|
@@ -946,6 +966,7 @@ export class Client {
|
|
|
946
966
|
method: "DELETE",
|
|
947
967
|
headers: this.headers,
|
|
948
968
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
969
|
+
...this.fetchOptions,
|
|
949
970
|
});
|
|
950
971
|
await raiseForStatus(response, "unshare dataset");
|
|
951
972
|
}
|
|
@@ -955,6 +976,7 @@ export class Client {
|
|
|
955
976
|
method: "GET",
|
|
956
977
|
headers: this.headers,
|
|
957
978
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
979
|
+
...this.fetchOptions,
|
|
958
980
|
});
|
|
959
981
|
const dataset = await response.json();
|
|
960
982
|
return dataset;
|
|
@@ -979,6 +1001,7 @@ export class Client {
|
|
|
979
1001
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
980
1002
|
body: JSON.stringify(body),
|
|
981
1003
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1004
|
+
...this.fetchOptions,
|
|
982
1005
|
});
|
|
983
1006
|
const result = await response.json();
|
|
984
1007
|
if (!response.ok) {
|
|
@@ -1003,6 +1026,7 @@ export class Client {
|
|
|
1003
1026
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1004
1027
|
body: JSON.stringify(body),
|
|
1005
1028
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1029
|
+
...this.fetchOptions,
|
|
1006
1030
|
});
|
|
1007
1031
|
const result = await response.json();
|
|
1008
1032
|
if (!response.ok) {
|
|
@@ -1031,6 +1055,7 @@ export class Client {
|
|
|
1031
1055
|
method: "GET",
|
|
1032
1056
|
headers: this.headers,
|
|
1033
1057
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1058
|
+
...this.fetchOptions,
|
|
1034
1059
|
});
|
|
1035
1060
|
// consume the response body to release the connection
|
|
1036
1061
|
// https://undici.nodejs.org/#/?id=garbage-collection
|
|
@@ -1141,6 +1166,7 @@ export class Client {
|
|
|
1141
1166
|
method: "DELETE",
|
|
1142
1167
|
headers: this.headers,
|
|
1143
1168
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1169
|
+
...this.fetchOptions,
|
|
1144
1170
|
});
|
|
1145
1171
|
await raiseForStatus(response, `delete session ${projectId_} (${projectName})`);
|
|
1146
1172
|
}
|
|
@@ -1168,6 +1194,7 @@ export class Client {
|
|
|
1168
1194
|
headers: this.headers,
|
|
1169
1195
|
body: formData,
|
|
1170
1196
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1197
|
+
...this.fetchOptions,
|
|
1171
1198
|
});
|
|
1172
1199
|
if (!response.ok) {
|
|
1173
1200
|
const result = await response.json();
|
|
@@ -1192,6 +1219,7 @@ export class Client {
|
|
|
1192
1219
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1193
1220
|
body: JSON.stringify(body),
|
|
1194
1221
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1222
|
+
...this.fetchOptions,
|
|
1195
1223
|
});
|
|
1196
1224
|
if (!response.ok) {
|
|
1197
1225
|
const result = await response.json();
|
|
@@ -1233,6 +1261,27 @@ export class Client {
|
|
|
1233
1261
|
}
|
|
1234
1262
|
return result;
|
|
1235
1263
|
}
|
|
1264
|
+
async diffDatasetVersions({ datasetId, datasetName, fromVersion, toVersion, }) {
|
|
1265
|
+
let datasetId_ = datasetId;
|
|
1266
|
+
if (datasetId_ === undefined && datasetName === undefined) {
|
|
1267
|
+
throw new Error("Must provide either datasetName or datasetId");
|
|
1268
|
+
}
|
|
1269
|
+
else if (datasetId_ !== undefined && datasetName !== undefined) {
|
|
1270
|
+
throw new Error("Must provide either datasetName or datasetId, not both");
|
|
1271
|
+
}
|
|
1272
|
+
else if (datasetId_ === undefined) {
|
|
1273
|
+
const dataset = await this.readDataset({ datasetName });
|
|
1274
|
+
datasetId_ = dataset.id;
|
|
1275
|
+
}
|
|
1276
|
+
const urlParams = new URLSearchParams({
|
|
1277
|
+
from_version: typeof fromVersion === "string"
|
|
1278
|
+
? fromVersion
|
|
1279
|
+
: fromVersion.toISOString(),
|
|
1280
|
+
to_version: typeof toVersion === "string" ? toVersion : toVersion.toISOString(),
|
|
1281
|
+
});
|
|
1282
|
+
const response = await this._get(`/datasets/${datasetId_}/versions/diff`, urlParams);
|
|
1283
|
+
return response;
|
|
1284
|
+
}
|
|
1236
1285
|
async readDatasetOpenaiFinetuning({ datasetId, datasetName, }) {
|
|
1237
1286
|
const path = "/datasets";
|
|
1238
1287
|
if (datasetId !== undefined) {
|
|
@@ -1294,6 +1343,7 @@ export class Client {
|
|
|
1294
1343
|
method: "DELETE",
|
|
1295
1344
|
headers: this.headers,
|
|
1296
1345
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1346
|
+
...this.fetchOptions,
|
|
1297
1347
|
});
|
|
1298
1348
|
if (!response.ok) {
|
|
1299
1349
|
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -1325,6 +1375,7 @@ export class Client {
|
|
|
1325
1375
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1326
1376
|
body: JSON.stringify(data),
|
|
1327
1377
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1378
|
+
...this.fetchOptions,
|
|
1328
1379
|
});
|
|
1329
1380
|
if (!response.ok) {
|
|
1330
1381
|
throw new Error(`Failed to create example: ${response.status} ${response.statusText}`);
|
|
@@ -1359,6 +1410,7 @@ export class Client {
|
|
|
1359
1410
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1360
1411
|
body: JSON.stringify(formattedExamples),
|
|
1361
1412
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1413
|
+
...this.fetchOptions,
|
|
1362
1414
|
});
|
|
1363
1415
|
if (!response.ok) {
|
|
1364
1416
|
throw new Error(`Failed to create examples: ${response.status} ${response.statusText}`);
|
|
@@ -1386,7 +1438,7 @@ export class Client {
|
|
|
1386
1438
|
const path = `/examples/${exampleId}`;
|
|
1387
1439
|
return await this._get(path);
|
|
1388
1440
|
}
|
|
1389
|
-
async *listExamples({ datasetId, datasetName, exampleIds, } = {}) {
|
|
1441
|
+
async *listExamples({ datasetId, datasetName, exampleIds, asOf, inlineS3Urls, } = {}) {
|
|
1390
1442
|
let datasetId_;
|
|
1391
1443
|
if (datasetId !== undefined && datasetName !== undefined) {
|
|
1392
1444
|
throw new Error("Must provide either datasetName or datasetId, not both");
|
|
@@ -1402,6 +1454,16 @@ export class Client {
|
|
|
1402
1454
|
throw new Error("Must provide a datasetName or datasetId");
|
|
1403
1455
|
}
|
|
1404
1456
|
const params = new URLSearchParams({ dataset: datasetId_ });
|
|
1457
|
+
const dataset_version = asOf
|
|
1458
|
+
? typeof asOf === "string"
|
|
1459
|
+
? asOf
|
|
1460
|
+
: asOf?.toISOString()
|
|
1461
|
+
: undefined;
|
|
1462
|
+
if (dataset_version) {
|
|
1463
|
+
params.append("as_of", dataset_version);
|
|
1464
|
+
}
|
|
1465
|
+
const inlineS3Urls_ = inlineS3Urls ?? true;
|
|
1466
|
+
params.append("inline_s3_urls", inlineS3Urls_.toString());
|
|
1405
1467
|
if (exampleIds !== undefined) {
|
|
1406
1468
|
for (const id_ of exampleIds) {
|
|
1407
1469
|
params.append("id", id_);
|
|
@@ -1418,6 +1480,7 @@ export class Client {
|
|
|
1418
1480
|
method: "DELETE",
|
|
1419
1481
|
headers: this.headers,
|
|
1420
1482
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1483
|
+
...this.fetchOptions,
|
|
1421
1484
|
});
|
|
1422
1485
|
if (!response.ok) {
|
|
1423
1486
|
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -1431,6 +1494,7 @@ export class Client {
|
|
|
1431
1494
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1432
1495
|
body: JSON.stringify(update),
|
|
1433
1496
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1497
|
+
...this.fetchOptions,
|
|
1434
1498
|
});
|
|
1435
1499
|
if (!response.ok) {
|
|
1436
1500
|
throw new Error(`Failed to update example ${exampleId}: ${response.status} ${response.statusText}`);
|
|
@@ -1500,6 +1564,7 @@ export class Client {
|
|
|
1500
1564
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1501
1565
|
body: JSON.stringify(feedback),
|
|
1502
1566
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1567
|
+
...this.fetchOptions,
|
|
1503
1568
|
});
|
|
1504
1569
|
await raiseForStatus(response, "create feedback");
|
|
1505
1570
|
return feedback;
|
|
@@ -1524,6 +1589,7 @@ export class Client {
|
|
|
1524
1589
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1525
1590
|
body: JSON.stringify(feedbackUpdate),
|
|
1526
1591
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1592
|
+
...this.fetchOptions,
|
|
1527
1593
|
});
|
|
1528
1594
|
await raiseForStatus(response, "update feedback");
|
|
1529
1595
|
}
|
|
@@ -1540,6 +1606,7 @@ export class Client {
|
|
|
1540
1606
|
method: "DELETE",
|
|
1541
1607
|
headers: this.headers,
|
|
1542
1608
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1609
|
+
...this.fetchOptions,
|
|
1543
1610
|
});
|
|
1544
1611
|
if (!response.ok) {
|
|
1545
1612
|
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
@@ -1604,6 +1671,7 @@ export class Client {
|
|
|
1604
1671
|
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
1605
1672
|
body: JSON.stringify(body),
|
|
1606
1673
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1674
|
+
...this.fetchOptions,
|
|
1607
1675
|
});
|
|
1608
1676
|
const result = await response.json();
|
|
1609
1677
|
return result;
|
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.14";
|
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.14";
|
package/dist/index.js
CHANGED
package/dist/schemas.d.ts
CHANGED
package/dist/wrappers.cjs
CHANGED
|
@@ -1,12 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.wrapOpenAI = void 0;
|
|
3
|
+
exports.wrapSDK = exports.wrapOpenAI = void 0;
|
|
4
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
|
+
*/
|
|
5
12
|
const wrapOpenAI = (openai, options) => {
|
|
6
|
-
// @ts-expect-error Promise<APIPromise<...>> != APIPromise<...>
|
|
7
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));
|
|
8
|
-
// @ts-expect-error Promise<APIPromise<...>> != APIPromise<...>
|
|
9
14
|
openai.completions.create = (0, traceable_js_1.traceable)(openai.completions.create.bind(openai.completions), Object.assign({ name: "OpenAI", run_type: "llm" }, options?.client));
|
|
10
15
|
return openai;
|
|
11
16
|
};
|
|
12
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
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
|
-
import type { OpenAI } from "openai";
|
|
2
1
|
import type { Client } from "./index.js";
|
|
3
|
-
|
|
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?: {
|
|
4
20
|
client?: Client;
|
|
5
|
-
}) =>
|
|
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
CHANGED
|
@@ -1,8 +1,49 @@
|
|
|
1
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
|
+
*/
|
|
2
9
|
export const wrapOpenAI = (openai, options) => {
|
|
3
|
-
// @ts-expect-error Promise<APIPromise<...>> != APIPromise<...>
|
|
4
10
|
openai.chat.completions.create = traceable(openai.chat.completions.create.bind(openai.chat.completions), Object.assign({ name: "ChatOpenAI", run_type: "llm" }, options?.client));
|
|
5
|
-
// @ts-expect-error Promise<APIPromise<...>> != APIPromise<...>
|
|
6
11
|
openai.completions.create = traceable(openai.completions.create.bind(openai.completions), Object.assign({ name: "OpenAI", run_type: "llm" }, options?.client));
|
|
7
12
|
return openai;
|
|
8
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
|
+
};
|