langsmith 0.1.43 → 0.1.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs +160 -99
- package/dist/client.d.ts +32 -3
- package/dist/client.js +160 -99
- package/dist/evaluation/_runner.cjs +29 -5
- package/dist/evaluation/_runner.d.ts +2 -1
- package/dist/evaluation/_runner.js +28 -5
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/schemas.d.ts +2 -0
- package/dist/utils/error.cjs +65 -1
- package/dist/utils/error.d.ts +43 -0
- package/dist/utils/error.js +62 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -6,6 +6,7 @@ import { __version__ } from "./index.js";
|
|
|
6
6
|
import { assertUuid } from "./utils/_uuid.js";
|
|
7
7
|
import { warnOnce } from "./utils/warn.js";
|
|
8
8
|
import { isVersionGreaterOrEqual, parsePromptIdentifier, } from "./utils/prompts.js";
|
|
9
|
+
import { raiseForStatus } from "./utils/error.js";
|
|
9
10
|
async function mergeRuntimeEnvIntoRunCreates(runs) {
|
|
10
11
|
const runtimeEnv = await getRuntimeEnvironment();
|
|
11
12
|
const envVars = getLangChainEnvVarsMetadata();
|
|
@@ -46,14 +47,6 @@ const isLocalhost = (url) => {
|
|
|
46
47
|
const hostname = strippedUrl.split("/")[0].split(":")[0];
|
|
47
48
|
return (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1");
|
|
48
49
|
};
|
|
49
|
-
const raiseForStatus = async (response, operation) => {
|
|
50
|
-
// consume the response body to release the connection
|
|
51
|
-
// https://undici.nodejs.org/#/?id=garbage-collection
|
|
52
|
-
const body = await response.text();
|
|
53
|
-
if (!response.ok) {
|
|
54
|
-
throw new Error(`Failed to ${operation}: ${response.status} ${response.statusText} ${body}`);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
50
|
async function toArray(iterable) {
|
|
58
51
|
const result = [];
|
|
59
52
|
for await (const item of iterable) {
|
|
@@ -360,9 +353,7 @@ export class Client {
|
|
|
360
353
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
361
354
|
...this.fetchOptions,
|
|
362
355
|
});
|
|
363
|
-
|
|
364
|
-
throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
|
|
365
|
-
}
|
|
356
|
+
await raiseForStatus(response, `Failed to fetch ${path}`);
|
|
366
357
|
return response;
|
|
367
358
|
}
|
|
368
359
|
async _get(path, queryParams) {
|
|
@@ -382,9 +373,7 @@ export class Client {
|
|
|
382
373
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
383
374
|
...this.fetchOptions,
|
|
384
375
|
});
|
|
385
|
-
|
|
386
|
-
throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
|
|
387
|
-
}
|
|
376
|
+
await raiseForStatus(response, `Failed to fetch ${path}`);
|
|
388
377
|
const items = transform
|
|
389
378
|
? transform(await response.json())
|
|
390
379
|
: await response.json();
|
|
@@ -501,12 +490,7 @@ export class Client {
|
|
|
501
490
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
502
491
|
...this.fetchOptions,
|
|
503
492
|
});
|
|
504
|
-
|
|
505
|
-
// consume the response body to release the connection
|
|
506
|
-
// https://undici.nodejs.org/#/?id=garbage-collection
|
|
507
|
-
await response.text();
|
|
508
|
-
throw new Error("Failed to retrieve server info.");
|
|
509
|
-
}
|
|
493
|
+
await raiseForStatus(response, "get server info");
|
|
510
494
|
return response.json();
|
|
511
495
|
}
|
|
512
496
|
async batchEndpointIsSupported() {
|
|
@@ -555,7 +539,7 @@ export class Client {
|
|
|
555
539
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
556
540
|
...this.fetchOptions,
|
|
557
541
|
});
|
|
558
|
-
await raiseForStatus(response, "create run");
|
|
542
|
+
await raiseForStatus(response, "create run", true);
|
|
559
543
|
}
|
|
560
544
|
/**
|
|
561
545
|
* Batch ingest/upsert multiple runs in the Langsmith system.
|
|
@@ -655,7 +639,7 @@ export class Client {
|
|
|
655
639
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
656
640
|
...this.fetchOptions,
|
|
657
641
|
});
|
|
658
|
-
await raiseForStatus(response, "batch create run");
|
|
642
|
+
await raiseForStatus(response, "batch create run", true);
|
|
659
643
|
}
|
|
660
644
|
async updateRun(runId, run) {
|
|
661
645
|
assertUuid(runId);
|
|
@@ -692,7 +676,7 @@ export class Client {
|
|
|
692
676
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
693
677
|
...this.fetchOptions,
|
|
694
678
|
});
|
|
695
|
-
await raiseForStatus(response, "update run");
|
|
679
|
+
await raiseForStatus(response, "update run", true);
|
|
696
680
|
}
|
|
697
681
|
async readRun(runId, { loadChildRuns } = { loadChildRuns: false }) {
|
|
698
682
|
assertUuid(runId);
|
|
@@ -985,7 +969,7 @@ export class Client {
|
|
|
985
969
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
986
970
|
...this.fetchOptions,
|
|
987
971
|
});
|
|
988
|
-
await raiseForStatus(response, "unshare run");
|
|
972
|
+
await raiseForStatus(response, "unshare run", true);
|
|
989
973
|
}
|
|
990
974
|
async readRunSharedLink(runId) {
|
|
991
975
|
assertUuid(runId);
|
|
@@ -1070,7 +1054,7 @@ export class Client {
|
|
|
1070
1054
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1071
1055
|
...this.fetchOptions,
|
|
1072
1056
|
});
|
|
1073
|
-
await raiseForStatus(response, "unshare dataset");
|
|
1057
|
+
await raiseForStatus(response, "unshare dataset", true);
|
|
1074
1058
|
}
|
|
1075
1059
|
async readSharedDataset(shareToken) {
|
|
1076
1060
|
assertUuid(shareToken);
|
|
@@ -1083,6 +1067,46 @@ export class Client {
|
|
|
1083
1067
|
const dataset = await response.json();
|
|
1084
1068
|
return dataset;
|
|
1085
1069
|
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Get shared examples.
|
|
1072
|
+
*
|
|
1073
|
+
* @param {string} shareToken The share token to get examples for. A share token is the UUID (or LangSmith URL, including UUID) generated when explicitly marking an example as public.
|
|
1074
|
+
* @param {Object} [options] Additional options for listing the examples.
|
|
1075
|
+
* @param {string[] | undefined} [options.exampleIds] A list of example IDs to filter by.
|
|
1076
|
+
* @returns {Promise<Example[]>} The shared examples.
|
|
1077
|
+
*/
|
|
1078
|
+
async listSharedExamples(shareToken, options) {
|
|
1079
|
+
const params = {};
|
|
1080
|
+
if (options?.exampleIds) {
|
|
1081
|
+
params.id = options.exampleIds;
|
|
1082
|
+
}
|
|
1083
|
+
const urlParams = new URLSearchParams();
|
|
1084
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
1085
|
+
if (Array.isArray(value)) {
|
|
1086
|
+
value.forEach((v) => urlParams.append(key, v));
|
|
1087
|
+
}
|
|
1088
|
+
else {
|
|
1089
|
+
urlParams.append(key, value);
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
const response = await this.caller.call(fetch, `${this.apiUrl}/public/${shareToken}/examples?${urlParams.toString()}`, {
|
|
1093
|
+
method: "GET",
|
|
1094
|
+
headers: this.headers,
|
|
1095
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1096
|
+
...this.fetchOptions,
|
|
1097
|
+
});
|
|
1098
|
+
const result = await response.json();
|
|
1099
|
+
if (!response.ok) {
|
|
1100
|
+
if ("detail" in result) {
|
|
1101
|
+
throw new Error(`Failed to list shared examples.\nStatus: ${response.status}\nMessage: ${result.detail.join("\n")}`);
|
|
1102
|
+
}
|
|
1103
|
+
throw new Error(`Failed to list shared examples: ${response.status} ${response.statusText}`);
|
|
1104
|
+
}
|
|
1105
|
+
return result.map((example) => ({
|
|
1106
|
+
...example,
|
|
1107
|
+
_hostUrl: this.getHostUrl(),
|
|
1108
|
+
}));
|
|
1109
|
+
}
|
|
1086
1110
|
async createProject({ projectName, description = null, metadata = null, upsert = false, projectExtra = null, referenceDatasetId = null, }) {
|
|
1087
1111
|
const upsert_ = upsert ? `?upsert=true` : "";
|
|
1088
1112
|
const endpoint = `${this.apiUrl}/sessions${upsert_}`;
|
|
@@ -1105,10 +1129,8 @@ export class Client {
|
|
|
1105
1129
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1106
1130
|
...this.fetchOptions,
|
|
1107
1131
|
});
|
|
1132
|
+
await raiseForStatus(response, "create project");
|
|
1108
1133
|
const result = await response.json();
|
|
1109
|
-
if (!response.ok) {
|
|
1110
|
-
throw new Error(`Failed to create session ${projectName}: ${response.status} ${response.statusText}`);
|
|
1111
|
-
}
|
|
1112
1134
|
return result;
|
|
1113
1135
|
}
|
|
1114
1136
|
async updateProject(projectId, { name = null, description = null, metadata = null, projectExtra = null, endTime = null, }) {
|
|
@@ -1130,10 +1152,8 @@ export class Client {
|
|
|
1130
1152
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1131
1153
|
...this.fetchOptions,
|
|
1132
1154
|
});
|
|
1155
|
+
await raiseForStatus(response, "update project");
|
|
1133
1156
|
const result = await response.json();
|
|
1134
|
-
if (!response.ok) {
|
|
1135
|
-
throw new Error(`Failed to update project ${projectId}: ${response.status} ${response.statusText}`);
|
|
1136
|
-
}
|
|
1137
1157
|
return result;
|
|
1138
1158
|
}
|
|
1139
1159
|
async hasProject({ projectId, projectName, }) {
|
|
@@ -1289,7 +1309,7 @@ export class Client {
|
|
|
1289
1309
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1290
1310
|
...this.fetchOptions,
|
|
1291
1311
|
});
|
|
1292
|
-
await raiseForStatus(response, `delete session ${projectId_} (${projectName})
|
|
1312
|
+
await raiseForStatus(response, `delete session ${projectId_} (${projectName})`, true);
|
|
1293
1313
|
}
|
|
1294
1314
|
async uploadCsv({ csvFile, fileName, inputKeys, outputKeys, description, dataType, name, }) {
|
|
1295
1315
|
const url = `${this.apiUrl}/datasets/upload`;
|
|
@@ -1317,20 +1337,15 @@ export class Client {
|
|
|
1317
1337
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1318
1338
|
...this.fetchOptions,
|
|
1319
1339
|
});
|
|
1320
|
-
|
|
1321
|
-
const result = await response.json();
|
|
1322
|
-
if (result.detail && result.detail.includes("already exists")) {
|
|
1323
|
-
throw new Error(`Dataset ${fileName} already exists`);
|
|
1324
|
-
}
|
|
1325
|
-
throw new Error(`Failed to upload CSV: ${response.status} ${response.statusText}`);
|
|
1326
|
-
}
|
|
1340
|
+
await raiseForStatus(response, "upload CSV");
|
|
1327
1341
|
const result = await response.json();
|
|
1328
1342
|
return result;
|
|
1329
1343
|
}
|
|
1330
|
-
async createDataset(name, { description, dataType, inputsSchema, outputsSchema, } = {}) {
|
|
1344
|
+
async createDataset(name, { description, dataType, inputsSchema, outputsSchema, metadata, } = {}) {
|
|
1331
1345
|
const body = {
|
|
1332
1346
|
name,
|
|
1333
1347
|
description,
|
|
1348
|
+
extra: metadata ? { metadata } : undefined,
|
|
1334
1349
|
};
|
|
1335
1350
|
if (dataType) {
|
|
1336
1351
|
body.data_type = dataType;
|
|
@@ -1348,13 +1363,7 @@ export class Client {
|
|
|
1348
1363
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1349
1364
|
...this.fetchOptions,
|
|
1350
1365
|
});
|
|
1351
|
-
|
|
1352
|
-
const result = await response.json();
|
|
1353
|
-
if (result.detail && result.detail.includes("already exists")) {
|
|
1354
|
-
throw new Error(`Dataset ${name} already exists`);
|
|
1355
|
-
}
|
|
1356
|
-
throw new Error(`Failed to create dataset ${response.status} ${response.statusText}`);
|
|
1357
|
-
}
|
|
1366
|
+
await raiseForStatus(response, "create dataset");
|
|
1358
1367
|
const result = await response.json();
|
|
1359
1368
|
return result;
|
|
1360
1369
|
}
|
|
@@ -1443,7 +1452,7 @@ export class Client {
|
|
|
1443
1452
|
.map((line) => JSON.parse(line));
|
|
1444
1453
|
return dataset;
|
|
1445
1454
|
}
|
|
1446
|
-
async *listDatasets({ limit = 100, offset = 0, datasetIds, datasetName, datasetNameContains, } = {}) {
|
|
1455
|
+
async *listDatasets({ limit = 100, offset = 0, datasetIds, datasetName, datasetNameContains, metadata, } = {}) {
|
|
1447
1456
|
const path = "/datasets";
|
|
1448
1457
|
const params = new URLSearchParams({
|
|
1449
1458
|
limit: limit.toString(),
|
|
@@ -1460,6 +1469,9 @@ export class Client {
|
|
|
1460
1469
|
if (datasetNameContains !== undefined) {
|
|
1461
1470
|
params.append("name_contains", datasetNameContains);
|
|
1462
1471
|
}
|
|
1472
|
+
if (metadata !== undefined) {
|
|
1473
|
+
params.append("metadata", JSON.stringify(metadata));
|
|
1474
|
+
}
|
|
1463
1475
|
for await (const datasets of this._getPaginated(path, params)) {
|
|
1464
1476
|
yield* datasets;
|
|
1465
1477
|
}
|
|
@@ -1483,9 +1495,7 @@ export class Client {
|
|
|
1483
1495
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1484
1496
|
...this.fetchOptions,
|
|
1485
1497
|
});
|
|
1486
|
-
|
|
1487
|
-
throw new Error(`Failed to update dataset ${_datasetId}: ${response.status} ${response.statusText}`);
|
|
1488
|
-
}
|
|
1498
|
+
await raiseForStatus(response, "update dataset");
|
|
1489
1499
|
return (await response.json());
|
|
1490
1500
|
}
|
|
1491
1501
|
async deleteDataset({ datasetId, datasetName, }) {
|
|
@@ -1511,9 +1521,7 @@ export class Client {
|
|
|
1511
1521
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1512
1522
|
...this.fetchOptions,
|
|
1513
1523
|
});
|
|
1514
|
-
|
|
1515
|
-
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
1516
|
-
}
|
|
1524
|
+
await raiseForStatus(response, `delete ${path}`);
|
|
1517
1525
|
await response.json();
|
|
1518
1526
|
}
|
|
1519
1527
|
async indexDataset({ datasetId, datasetName, tag, }) {
|
|
@@ -1539,9 +1547,7 @@ export class Client {
|
|
|
1539
1547
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1540
1548
|
...this.fetchOptions,
|
|
1541
1549
|
});
|
|
1542
|
-
|
|
1543
|
-
throw new Error(`Failed to index dataset ${datasetId_}: ${response.status} ${response.statusText}`);
|
|
1544
|
-
}
|
|
1550
|
+
await raiseForStatus(response, "index dataset");
|
|
1545
1551
|
await response.json();
|
|
1546
1552
|
}
|
|
1547
1553
|
/**
|
|
@@ -1580,9 +1586,7 @@ export class Client {
|
|
|
1580
1586
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1581
1587
|
...this.fetchOptions,
|
|
1582
1588
|
});
|
|
1583
|
-
|
|
1584
|
-
throw new Error(`Failed to fetch similar examples: ${response.status} ${response.statusText}`);
|
|
1585
|
-
}
|
|
1589
|
+
await raiseForStatus(response, "fetch similar examples");
|
|
1586
1590
|
const result = await response.json();
|
|
1587
1591
|
return result["examples"];
|
|
1588
1592
|
}
|
|
@@ -1615,9 +1619,7 @@ export class Client {
|
|
|
1615
1619
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1616
1620
|
...this.fetchOptions,
|
|
1617
1621
|
});
|
|
1618
|
-
|
|
1619
|
-
throw new Error(`Failed to create example: ${response.status} ${response.statusText}`);
|
|
1620
|
-
}
|
|
1622
|
+
await raiseForStatus(response, "create example");
|
|
1621
1623
|
const result = await response.json();
|
|
1622
1624
|
return result;
|
|
1623
1625
|
}
|
|
@@ -1652,9 +1654,7 @@ export class Client {
|
|
|
1652
1654
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1653
1655
|
...this.fetchOptions,
|
|
1654
1656
|
});
|
|
1655
|
-
|
|
1656
|
-
throw new Error(`Failed to create examples: ${response.status} ${response.statusText}`);
|
|
1657
|
-
}
|
|
1657
|
+
await raiseForStatus(response, "create examples");
|
|
1658
1658
|
const result = await response.json();
|
|
1659
1659
|
return result;
|
|
1660
1660
|
}
|
|
@@ -1747,9 +1747,7 @@ export class Client {
|
|
|
1747
1747
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1748
1748
|
...this.fetchOptions,
|
|
1749
1749
|
});
|
|
1750
|
-
|
|
1751
|
-
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
1752
|
-
}
|
|
1750
|
+
await raiseForStatus(response, `delete ${path}`);
|
|
1753
1751
|
await response.json();
|
|
1754
1752
|
}
|
|
1755
1753
|
async updateExample(exampleId, update) {
|
|
@@ -1761,9 +1759,7 @@ export class Client {
|
|
|
1761
1759
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1762
1760
|
...this.fetchOptions,
|
|
1763
1761
|
});
|
|
1764
|
-
|
|
1765
|
-
throw new Error(`Failed to update example ${exampleId}: ${response.status} ${response.statusText}`);
|
|
1766
|
-
}
|
|
1762
|
+
await raiseForStatus(response, "update example");
|
|
1767
1763
|
const result = await response.json();
|
|
1768
1764
|
return result;
|
|
1769
1765
|
}
|
|
@@ -1775,9 +1771,7 @@ export class Client {
|
|
|
1775
1771
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1776
1772
|
...this.fetchOptions,
|
|
1777
1773
|
});
|
|
1778
|
-
|
|
1779
|
-
throw new Error(`Failed to update examples: ${response.status} ${response.statusText}`);
|
|
1780
|
-
}
|
|
1774
|
+
await raiseForStatus(response, "update examples");
|
|
1781
1775
|
const result = await response.json();
|
|
1782
1776
|
return result;
|
|
1783
1777
|
}
|
|
@@ -1840,7 +1834,7 @@ export class Client {
|
|
|
1840
1834
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1841
1835
|
...this.fetchOptions,
|
|
1842
1836
|
});
|
|
1843
|
-
await raiseForStatus(response, "update dataset splits");
|
|
1837
|
+
await raiseForStatus(response, "update dataset splits", true);
|
|
1844
1838
|
}
|
|
1845
1839
|
/**
|
|
1846
1840
|
* @deprecated This method is deprecated and will be removed in future LangSmith versions, use `evaluate` from `langsmith/evaluation` instead.
|
|
@@ -1906,7 +1900,7 @@ export class Client {
|
|
|
1906
1900
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1907
1901
|
...this.fetchOptions,
|
|
1908
1902
|
});
|
|
1909
|
-
await raiseForStatus(response, "create feedback");
|
|
1903
|
+
await raiseForStatus(response, "create feedback", true);
|
|
1910
1904
|
return feedback;
|
|
1911
1905
|
}
|
|
1912
1906
|
async updateFeedback(feedbackId, { score, value, correction, comment, }) {
|
|
@@ -1931,7 +1925,7 @@ export class Client {
|
|
|
1931
1925
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1932
1926
|
...this.fetchOptions,
|
|
1933
1927
|
});
|
|
1934
|
-
await raiseForStatus(response, "update feedback");
|
|
1928
|
+
await raiseForStatus(response, "update feedback", true);
|
|
1935
1929
|
}
|
|
1936
1930
|
async readFeedback(feedbackId) {
|
|
1937
1931
|
assertUuid(feedbackId);
|
|
@@ -1948,9 +1942,7 @@ export class Client {
|
|
|
1948
1942
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
1949
1943
|
...this.fetchOptions,
|
|
1950
1944
|
});
|
|
1951
|
-
|
|
1952
|
-
throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
|
|
1953
|
-
}
|
|
1945
|
+
await raiseForStatus(response, `delete ${path}`);
|
|
1954
1946
|
await response.json();
|
|
1955
1947
|
}
|
|
1956
1948
|
async *listFeedback({ runIds, feedbackKeys, feedbackSourceTypes, } = {}) {
|
|
@@ -2143,9 +2135,7 @@ export class Client {
|
|
|
2143
2135
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
2144
2136
|
...this.fetchOptions,
|
|
2145
2137
|
});
|
|
2146
|
-
|
|
2147
|
-
throw new Error(`Failed to ${like ? "like" : "unlike"} prompt: ${response.status} ${await response.text()}`);
|
|
2148
|
-
}
|
|
2138
|
+
await raiseForStatus(response, `${like ? "like" : "unlike"} prompt`);
|
|
2149
2139
|
return await response.json();
|
|
2150
2140
|
}
|
|
2151
2141
|
async _getPromptUrl(promptIdentifier) {
|
|
@@ -2209,9 +2199,7 @@ export class Client {
|
|
|
2209
2199
|
if (response.status === 404) {
|
|
2210
2200
|
return null;
|
|
2211
2201
|
}
|
|
2212
|
-
|
|
2213
|
-
throw new Error(`Failed to get prompt: ${response.status} ${await response.text()}`);
|
|
2214
|
-
}
|
|
2202
|
+
await raiseForStatus(response, "get prompt");
|
|
2215
2203
|
const result = await response.json();
|
|
2216
2204
|
if (result.repo) {
|
|
2217
2205
|
return result.repo;
|
|
@@ -2246,9 +2234,7 @@ export class Client {
|
|
|
2246
2234
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
2247
2235
|
...this.fetchOptions,
|
|
2248
2236
|
});
|
|
2249
|
-
|
|
2250
|
-
throw new Error(`Failed to create prompt: ${response.status} ${await response.text()}`);
|
|
2251
|
-
}
|
|
2237
|
+
await raiseForStatus(response, "create prompt");
|
|
2252
2238
|
const { repo } = await response.json();
|
|
2253
2239
|
return repo;
|
|
2254
2240
|
}
|
|
@@ -2271,9 +2257,7 @@ export class Client {
|
|
|
2271
2257
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
2272
2258
|
...this.fetchOptions,
|
|
2273
2259
|
});
|
|
2274
|
-
|
|
2275
|
-
throw new Error(`Failed to create commit: ${response.status} ${await response.text()}`);
|
|
2276
|
-
}
|
|
2260
|
+
await raiseForStatus(response, "create commit");
|
|
2277
2261
|
const result = await response.json();
|
|
2278
2262
|
return this._getPromptUrl(`${owner}/${promptName}${result.commit_hash ? `:${result.commit_hash}` : ""}`);
|
|
2279
2263
|
}
|
|
@@ -2310,9 +2294,7 @@ export class Client {
|
|
|
2310
2294
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
2311
2295
|
...this.fetchOptions,
|
|
2312
2296
|
});
|
|
2313
|
-
|
|
2314
|
-
throw new Error(`HTTP Error: ${response.status} - ${await response.text()}`);
|
|
2315
|
-
}
|
|
2297
|
+
await raiseForStatus(response, "update prompt");
|
|
2316
2298
|
return response.json();
|
|
2317
2299
|
}
|
|
2318
2300
|
async deletePrompt(promptIdentifier) {
|
|
@@ -2351,9 +2333,7 @@ export class Client {
|
|
|
2351
2333
|
signal: AbortSignal.timeout(this.timeout_ms),
|
|
2352
2334
|
...this.fetchOptions,
|
|
2353
2335
|
});
|
|
2354
|
-
|
|
2355
|
-
throw new Error(`Failed to pull prompt commit: ${response.status} ${response.statusText}`);
|
|
2356
|
-
}
|
|
2336
|
+
await raiseForStatus(response, "pull prompt commit");
|
|
2357
2337
|
const result = await response.json();
|
|
2358
2338
|
return {
|
|
2359
2339
|
owner,
|
|
@@ -2406,4 +2386,85 @@ export class Client {
|
|
|
2406
2386
|
});
|
|
2407
2387
|
return url;
|
|
2408
2388
|
}
|
|
2389
|
+
/**
|
|
2390
|
+
* Clone a public dataset to your own langsmith tenant.
|
|
2391
|
+
* This operation is idempotent. If you already have a dataset with the given name,
|
|
2392
|
+
* this function will do nothing.
|
|
2393
|
+
|
|
2394
|
+
* @param {string} tokenOrUrl The token of the public dataset to clone.
|
|
2395
|
+
* @param {Object} [options] Additional options for cloning the dataset.
|
|
2396
|
+
* @param {string} [options.sourceApiUrl] The URL of the langsmith server where the data is hosted. Defaults to the API URL of your current client.
|
|
2397
|
+
* @param {string} [options.datasetName] The name of the dataset to create in your tenant. Defaults to the name of the public dataset.
|
|
2398
|
+
* @returns {Promise<void>}
|
|
2399
|
+
*/
|
|
2400
|
+
async clonePublicDataset(tokenOrUrl, options = {}) {
|
|
2401
|
+
const { sourceApiUrl = this.apiUrl, datasetName } = options;
|
|
2402
|
+
const [parsedApiUrl, tokenUuid] = this.parseTokenOrUrl(tokenOrUrl, sourceApiUrl);
|
|
2403
|
+
const sourceClient = new Client({
|
|
2404
|
+
apiUrl: parsedApiUrl,
|
|
2405
|
+
// Placeholder API key not needed anymore in most cases, but
|
|
2406
|
+
// some private deployments may have API key-based rate limiting
|
|
2407
|
+
// that would cause this to fail if we provide no value.
|
|
2408
|
+
apiKey: "placeholder",
|
|
2409
|
+
});
|
|
2410
|
+
const ds = await sourceClient.readSharedDataset(tokenUuid);
|
|
2411
|
+
const finalDatasetName = datasetName || ds.name;
|
|
2412
|
+
try {
|
|
2413
|
+
if (await this.hasDataset({ datasetId: finalDatasetName })) {
|
|
2414
|
+
console.log(`Dataset ${finalDatasetName} already exists in your tenant. Skipping.`);
|
|
2415
|
+
return;
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
catch (_) {
|
|
2419
|
+
// `.hasDataset` will throw an error if the dataset does not exist.
|
|
2420
|
+
// no-op in that case
|
|
2421
|
+
}
|
|
2422
|
+
// Fetch examples first, then create the dataset
|
|
2423
|
+
const examples = await sourceClient.listSharedExamples(tokenUuid);
|
|
2424
|
+
const dataset = await this.createDataset(finalDatasetName, {
|
|
2425
|
+
description: ds.description,
|
|
2426
|
+
dataType: ds.data_type || "kv",
|
|
2427
|
+
inputsSchema: ds.inputs_schema_definition ?? undefined,
|
|
2428
|
+
outputsSchema: ds.outputs_schema_definition ?? undefined,
|
|
2429
|
+
});
|
|
2430
|
+
try {
|
|
2431
|
+
await this.createExamples({
|
|
2432
|
+
inputs: examples.map((e) => e.inputs),
|
|
2433
|
+
outputs: examples.flatMap((e) => (e.outputs ? [e.outputs] : [])),
|
|
2434
|
+
datasetId: dataset.id,
|
|
2435
|
+
});
|
|
2436
|
+
}
|
|
2437
|
+
catch (e) {
|
|
2438
|
+
console.error(`An error occurred while creating dataset ${finalDatasetName}. ` +
|
|
2439
|
+
"You should delete it manually.");
|
|
2440
|
+
throw e;
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
parseTokenOrUrl(urlOrToken, apiUrl, numParts = 2, kind = "dataset") {
|
|
2444
|
+
// Try parsing as UUID
|
|
2445
|
+
try {
|
|
2446
|
+
assertUuid(urlOrToken); // Will throw if it's not a UUID.
|
|
2447
|
+
return [apiUrl, urlOrToken];
|
|
2448
|
+
}
|
|
2449
|
+
catch (_) {
|
|
2450
|
+
// no-op if it's not a uuid
|
|
2451
|
+
}
|
|
2452
|
+
// Parse as URL
|
|
2453
|
+
try {
|
|
2454
|
+
const parsedUrl = new URL(urlOrToken);
|
|
2455
|
+
const pathParts = parsedUrl.pathname
|
|
2456
|
+
.split("/")
|
|
2457
|
+
.filter((part) => part !== "");
|
|
2458
|
+
if (pathParts.length >= numParts) {
|
|
2459
|
+
const tokenUuid = pathParts[pathParts.length - numParts];
|
|
2460
|
+
return [apiUrl, tokenUuid];
|
|
2461
|
+
}
|
|
2462
|
+
else {
|
|
2463
|
+
throw new Error(`Invalid public ${kind} URL: ${urlOrToken}`);
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
catch (error) {
|
|
2467
|
+
throw new Error(`Invalid public ${kind} URL or token: ${urlOrToken}`);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2409
2470
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.evaluate = void 0;
|
|
3
|
+
exports._ExperimentManager = exports.evaluate = void 0;
|
|
4
4
|
const index_js_1 = require("../index.cjs");
|
|
5
5
|
const langchain_js_1 = require("../langchain.cjs");
|
|
6
6
|
const traceable_js_1 = require("../traceable.cjs");
|
|
@@ -232,17 +232,40 @@ class _ExperimentManager {
|
|
|
232
232
|
}
|
|
233
233
|
return projectMetadata;
|
|
234
234
|
}
|
|
235
|
-
async
|
|
235
|
+
async _createProject(firstExample, projectMetadata) {
|
|
236
|
+
// Create the project, updating the experimentName until we find a unique one.
|
|
236
237
|
let project;
|
|
237
|
-
|
|
238
|
+
const originalExperimentName = this._experimentName;
|
|
239
|
+
for (let i = 0; i < 10; i++) {
|
|
238
240
|
try {
|
|
239
|
-
const projectMetadata = await this._getExperimentMetadata();
|
|
240
241
|
project = await this.client.createProject({
|
|
241
|
-
projectName: this.
|
|
242
|
+
projectName: this._experimentName,
|
|
242
243
|
referenceDatasetId: firstExample.dataset_id,
|
|
243
244
|
metadata: projectMetadata,
|
|
244
245
|
description: this._description,
|
|
245
246
|
});
|
|
247
|
+
return project;
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
// Naming collision
|
|
251
|
+
if (e?.name === "LangSmithConflictError") {
|
|
252
|
+
const ent = (0, uuid_1.v4)().slice(0, 6);
|
|
253
|
+
this._experimentName = `${originalExperimentName}-${ent}`;
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
throw e;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
throw new Error("Could not generate a unique experiment name within 10 attempts." +
|
|
261
|
+
" Please try again with a different name.");
|
|
262
|
+
}
|
|
263
|
+
async _getProject(firstExample) {
|
|
264
|
+
let project;
|
|
265
|
+
if (!this._experiment) {
|
|
266
|
+
try {
|
|
267
|
+
const projectMetadata = await this._getExperimentMetadata();
|
|
268
|
+
project = await this._createProject(firstExample, projectMetadata);
|
|
246
269
|
this._experiment = project;
|
|
247
270
|
}
|
|
248
271
|
catch (e) {
|
|
@@ -554,6 +577,7 @@ class _ExperimentManager {
|
|
|
554
577
|
});
|
|
555
578
|
}
|
|
556
579
|
}
|
|
580
|
+
exports._ExperimentManager = _ExperimentManager;
|
|
557
581
|
/**
|
|
558
582
|
* Represents the results of an evaluate() call.
|
|
559
583
|
* This class provides an iterator interface to iterate over the experiment results
|
|
@@ -88,7 +88,7 @@ interface ExperimentResultRow {
|
|
|
88
88
|
* Supports lazily running predictions and evaluations in parallel to facilitate
|
|
89
89
|
* result streaming and early debugging.
|
|
90
90
|
*/
|
|
91
|
-
declare class _ExperimentManager {
|
|
91
|
+
export declare class _ExperimentManager {
|
|
92
92
|
_data?: DataT;
|
|
93
93
|
_runs?: AsyncGenerator<Run>;
|
|
94
94
|
_evaluationResults?: AsyncGenerator<EvaluationResults>;
|
|
@@ -110,6 +110,7 @@ declare class _ExperimentManager {
|
|
|
110
110
|
constructor(args: _ExperimentManagerArgs);
|
|
111
111
|
_getExperiment(): TracerSession;
|
|
112
112
|
_getExperimentMetadata(): Promise<KVMap>;
|
|
113
|
+
_createProject(firstExample: Example, projectMetadata: KVMap): Promise<TracerSession>;
|
|
113
114
|
_getProject(firstExample: Example): Promise<TracerSession>;
|
|
114
115
|
protected _printExperimentStart(): Promise<void>;
|
|
115
116
|
start(): Promise<_ExperimentManager>;
|
|
@@ -23,7 +23,7 @@ target, options) {
|
|
|
23
23
|
* Supports lazily running predictions and evaluations in parallel to facilitate
|
|
24
24
|
* result streaming and early debugging.
|
|
25
25
|
*/
|
|
26
|
-
class _ExperimentManager {
|
|
26
|
+
export class _ExperimentManager {
|
|
27
27
|
get experimentName() {
|
|
28
28
|
if (this._experimentName) {
|
|
29
29
|
return this._experimentName;
|
|
@@ -228,17 +228,40 @@ class _ExperimentManager {
|
|
|
228
228
|
}
|
|
229
229
|
return projectMetadata;
|
|
230
230
|
}
|
|
231
|
-
async
|
|
231
|
+
async _createProject(firstExample, projectMetadata) {
|
|
232
|
+
// Create the project, updating the experimentName until we find a unique one.
|
|
232
233
|
let project;
|
|
233
|
-
|
|
234
|
+
const originalExperimentName = this._experimentName;
|
|
235
|
+
for (let i = 0; i < 10; i++) {
|
|
234
236
|
try {
|
|
235
|
-
const projectMetadata = await this._getExperimentMetadata();
|
|
236
237
|
project = await this.client.createProject({
|
|
237
|
-
projectName: this.
|
|
238
|
+
projectName: this._experimentName,
|
|
238
239
|
referenceDatasetId: firstExample.dataset_id,
|
|
239
240
|
metadata: projectMetadata,
|
|
240
241
|
description: this._description,
|
|
241
242
|
});
|
|
243
|
+
return project;
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
// Naming collision
|
|
247
|
+
if (e?.name === "LangSmithConflictError") {
|
|
248
|
+
const ent = uuidv4().slice(0, 6);
|
|
249
|
+
this._experimentName = `${originalExperimentName}-${ent}`;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
throw e;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
throw new Error("Could not generate a unique experiment name within 10 attempts." +
|
|
257
|
+
" Please try again with a different name.");
|
|
258
|
+
}
|
|
259
|
+
async _getProject(firstExample) {
|
|
260
|
+
let project;
|
|
261
|
+
if (!this._experiment) {
|
|
262
|
+
try {
|
|
263
|
+
const projectMetadata = await this._getExperimentMetadata();
|
|
264
|
+
project = await this._createProject(firstExample, projectMetadata);
|
|
242
265
|
this._experiment = project;
|
|
243
266
|
}
|
|
244
267
|
catch (e) {
|
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.45";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Client } from "./client.js";
|
|
1
|
+
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
|
-
export declare const __version__ = "0.1.
|
|
4
|
+
export declare const __version__ = "0.1.45";
|
package/dist/index.js
CHANGED