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 CHANGED
@@ -32,6 +32,7 @@ const index_js_1 = require("./index.cjs");
32
32
  const _uuid_js_1 = require("./utils/_uuid.cjs");
33
33
  const warn_js_1 = require("./utils/warn.cjs");
34
34
  const prompts_js_1 = require("./utils/prompts.cjs");
35
+ const error_js_1 = require("./utils/error.cjs");
35
36
  async function mergeRuntimeEnvIntoRunCreates(runs) {
36
37
  const runtimeEnv = await (0, env_js_1.getRuntimeEnvironment)();
37
38
  const envVars = (0, env_js_1.getLangChainEnvVarsMetadata)();
@@ -72,14 +73,6 @@ const isLocalhost = (url) => {
72
73
  const hostname = strippedUrl.split("/")[0].split(":")[0];
73
74
  return (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1");
74
75
  };
75
- const raiseForStatus = async (response, operation) => {
76
- // consume the response body to release the connection
77
- // https://undici.nodejs.org/#/?id=garbage-collection
78
- const body = await response.text();
79
- if (!response.ok) {
80
- throw new Error(`Failed to ${operation}: ${response.status} ${response.statusText} ${body}`);
81
- }
82
- };
83
76
  async function toArray(iterable) {
84
77
  const result = [];
85
78
  for await (const item of iterable) {
@@ -387,9 +380,7 @@ class Client {
387
380
  signal: AbortSignal.timeout(this.timeout_ms),
388
381
  ...this.fetchOptions,
389
382
  });
390
- if (!response.ok) {
391
- throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
392
- }
383
+ await (0, error_js_1.raiseForStatus)(response, `Failed to fetch ${path}`);
393
384
  return response;
394
385
  }
395
386
  async _get(path, queryParams) {
@@ -409,9 +400,7 @@ class Client {
409
400
  signal: AbortSignal.timeout(this.timeout_ms),
410
401
  ...this.fetchOptions,
411
402
  });
412
- if (!response.ok) {
413
- throw new Error(`Failed to fetch ${path}: ${response.status} ${response.statusText}`);
414
- }
403
+ await (0, error_js_1.raiseForStatus)(response, `Failed to fetch ${path}`);
415
404
  const items = transform
416
405
  ? transform(await response.json())
417
406
  : await response.json();
@@ -528,12 +517,7 @@ class Client {
528
517
  signal: AbortSignal.timeout(this.timeout_ms),
529
518
  ...this.fetchOptions,
530
519
  });
531
- if (!response.ok) {
532
- // consume the response body to release the connection
533
- // https://undici.nodejs.org/#/?id=garbage-collection
534
- await response.text();
535
- throw new Error("Failed to retrieve server info.");
536
- }
520
+ await (0, error_js_1.raiseForStatus)(response, "get server info");
537
521
  return response.json();
538
522
  }
539
523
  async batchEndpointIsSupported() {
@@ -582,7 +566,7 @@ class Client {
582
566
  signal: AbortSignal.timeout(this.timeout_ms),
583
567
  ...this.fetchOptions,
584
568
  });
585
- await raiseForStatus(response, "create run");
569
+ await (0, error_js_1.raiseForStatus)(response, "create run", true);
586
570
  }
587
571
  /**
588
572
  * Batch ingest/upsert multiple runs in the Langsmith system.
@@ -682,7 +666,7 @@ class Client {
682
666
  signal: AbortSignal.timeout(this.timeout_ms),
683
667
  ...this.fetchOptions,
684
668
  });
685
- await raiseForStatus(response, "batch create run");
669
+ await (0, error_js_1.raiseForStatus)(response, "batch create run", true);
686
670
  }
687
671
  async updateRun(runId, run) {
688
672
  (0, _uuid_js_1.assertUuid)(runId);
@@ -719,7 +703,7 @@ class Client {
719
703
  signal: AbortSignal.timeout(this.timeout_ms),
720
704
  ...this.fetchOptions,
721
705
  });
722
- await raiseForStatus(response, "update run");
706
+ await (0, error_js_1.raiseForStatus)(response, "update run", true);
723
707
  }
724
708
  async readRun(runId, { loadChildRuns } = { loadChildRuns: false }) {
725
709
  (0, _uuid_js_1.assertUuid)(runId);
@@ -1012,7 +996,7 @@ class Client {
1012
996
  signal: AbortSignal.timeout(this.timeout_ms),
1013
997
  ...this.fetchOptions,
1014
998
  });
1015
- await raiseForStatus(response, "unshare run");
999
+ await (0, error_js_1.raiseForStatus)(response, "unshare run", true);
1016
1000
  }
1017
1001
  async readRunSharedLink(runId) {
1018
1002
  (0, _uuid_js_1.assertUuid)(runId);
@@ -1097,7 +1081,7 @@ class Client {
1097
1081
  signal: AbortSignal.timeout(this.timeout_ms),
1098
1082
  ...this.fetchOptions,
1099
1083
  });
1100
- await raiseForStatus(response, "unshare dataset");
1084
+ await (0, error_js_1.raiseForStatus)(response, "unshare dataset", true);
1101
1085
  }
1102
1086
  async readSharedDataset(shareToken) {
1103
1087
  (0, _uuid_js_1.assertUuid)(shareToken);
@@ -1110,6 +1094,46 @@ class Client {
1110
1094
  const dataset = await response.json();
1111
1095
  return dataset;
1112
1096
  }
1097
+ /**
1098
+ * Get shared examples.
1099
+ *
1100
+ * @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.
1101
+ * @param {Object} [options] Additional options for listing the examples.
1102
+ * @param {string[] | undefined} [options.exampleIds] A list of example IDs to filter by.
1103
+ * @returns {Promise<Example[]>} The shared examples.
1104
+ */
1105
+ async listSharedExamples(shareToken, options) {
1106
+ const params = {};
1107
+ if (options?.exampleIds) {
1108
+ params.id = options.exampleIds;
1109
+ }
1110
+ const urlParams = new URLSearchParams();
1111
+ Object.entries(params).forEach(([key, value]) => {
1112
+ if (Array.isArray(value)) {
1113
+ value.forEach((v) => urlParams.append(key, v));
1114
+ }
1115
+ else {
1116
+ urlParams.append(key, value);
1117
+ }
1118
+ });
1119
+ const response = await this.caller.call(fetch, `${this.apiUrl}/public/${shareToken}/examples?${urlParams.toString()}`, {
1120
+ method: "GET",
1121
+ headers: this.headers,
1122
+ signal: AbortSignal.timeout(this.timeout_ms),
1123
+ ...this.fetchOptions,
1124
+ });
1125
+ const result = await response.json();
1126
+ if (!response.ok) {
1127
+ if ("detail" in result) {
1128
+ throw new Error(`Failed to list shared examples.\nStatus: ${response.status}\nMessage: ${result.detail.join("\n")}`);
1129
+ }
1130
+ throw new Error(`Failed to list shared examples: ${response.status} ${response.statusText}`);
1131
+ }
1132
+ return result.map((example) => ({
1133
+ ...example,
1134
+ _hostUrl: this.getHostUrl(),
1135
+ }));
1136
+ }
1113
1137
  async createProject({ projectName, description = null, metadata = null, upsert = false, projectExtra = null, referenceDatasetId = null, }) {
1114
1138
  const upsert_ = upsert ? `?upsert=true` : "";
1115
1139
  const endpoint = `${this.apiUrl}/sessions${upsert_}`;
@@ -1132,10 +1156,8 @@ class Client {
1132
1156
  signal: AbortSignal.timeout(this.timeout_ms),
1133
1157
  ...this.fetchOptions,
1134
1158
  });
1159
+ await (0, error_js_1.raiseForStatus)(response, "create project");
1135
1160
  const result = await response.json();
1136
- if (!response.ok) {
1137
- throw new Error(`Failed to create session ${projectName}: ${response.status} ${response.statusText}`);
1138
- }
1139
1161
  return result;
1140
1162
  }
1141
1163
  async updateProject(projectId, { name = null, description = null, metadata = null, projectExtra = null, endTime = null, }) {
@@ -1157,10 +1179,8 @@ class Client {
1157
1179
  signal: AbortSignal.timeout(this.timeout_ms),
1158
1180
  ...this.fetchOptions,
1159
1181
  });
1182
+ await (0, error_js_1.raiseForStatus)(response, "update project");
1160
1183
  const result = await response.json();
1161
- if (!response.ok) {
1162
- throw new Error(`Failed to update project ${projectId}: ${response.status} ${response.statusText}`);
1163
- }
1164
1184
  return result;
1165
1185
  }
1166
1186
  async hasProject({ projectId, projectName, }) {
@@ -1316,7 +1336,7 @@ class Client {
1316
1336
  signal: AbortSignal.timeout(this.timeout_ms),
1317
1337
  ...this.fetchOptions,
1318
1338
  });
1319
- await raiseForStatus(response, `delete session ${projectId_} (${projectName})`);
1339
+ await (0, error_js_1.raiseForStatus)(response, `delete session ${projectId_} (${projectName})`, true);
1320
1340
  }
1321
1341
  async uploadCsv({ csvFile, fileName, inputKeys, outputKeys, description, dataType, name, }) {
1322
1342
  const url = `${this.apiUrl}/datasets/upload`;
@@ -1344,20 +1364,15 @@ class Client {
1344
1364
  signal: AbortSignal.timeout(this.timeout_ms),
1345
1365
  ...this.fetchOptions,
1346
1366
  });
1347
- if (!response.ok) {
1348
- const result = await response.json();
1349
- if (result.detail && result.detail.includes("already exists")) {
1350
- throw new Error(`Dataset ${fileName} already exists`);
1351
- }
1352
- throw new Error(`Failed to upload CSV: ${response.status} ${response.statusText}`);
1353
- }
1367
+ await (0, error_js_1.raiseForStatus)(response, "upload CSV");
1354
1368
  const result = await response.json();
1355
1369
  return result;
1356
1370
  }
1357
- async createDataset(name, { description, dataType, inputsSchema, outputsSchema, } = {}) {
1371
+ async createDataset(name, { description, dataType, inputsSchema, outputsSchema, metadata, } = {}) {
1358
1372
  const body = {
1359
1373
  name,
1360
1374
  description,
1375
+ extra: metadata ? { metadata } : undefined,
1361
1376
  };
1362
1377
  if (dataType) {
1363
1378
  body.data_type = dataType;
@@ -1375,13 +1390,7 @@ class Client {
1375
1390
  signal: AbortSignal.timeout(this.timeout_ms),
1376
1391
  ...this.fetchOptions,
1377
1392
  });
1378
- if (!response.ok) {
1379
- const result = await response.json();
1380
- if (result.detail && result.detail.includes("already exists")) {
1381
- throw new Error(`Dataset ${name} already exists`);
1382
- }
1383
- throw new Error(`Failed to create dataset ${response.status} ${response.statusText}`);
1384
- }
1393
+ await (0, error_js_1.raiseForStatus)(response, "create dataset");
1385
1394
  const result = await response.json();
1386
1395
  return result;
1387
1396
  }
@@ -1470,7 +1479,7 @@ class Client {
1470
1479
  .map((line) => JSON.parse(line));
1471
1480
  return dataset;
1472
1481
  }
1473
- async *listDatasets({ limit = 100, offset = 0, datasetIds, datasetName, datasetNameContains, } = {}) {
1482
+ async *listDatasets({ limit = 100, offset = 0, datasetIds, datasetName, datasetNameContains, metadata, } = {}) {
1474
1483
  const path = "/datasets";
1475
1484
  const params = new URLSearchParams({
1476
1485
  limit: limit.toString(),
@@ -1487,6 +1496,9 @@ class Client {
1487
1496
  if (datasetNameContains !== undefined) {
1488
1497
  params.append("name_contains", datasetNameContains);
1489
1498
  }
1499
+ if (metadata !== undefined) {
1500
+ params.append("metadata", JSON.stringify(metadata));
1501
+ }
1490
1502
  for await (const datasets of this._getPaginated(path, params)) {
1491
1503
  yield* datasets;
1492
1504
  }
@@ -1510,9 +1522,7 @@ class Client {
1510
1522
  signal: AbortSignal.timeout(this.timeout_ms),
1511
1523
  ...this.fetchOptions,
1512
1524
  });
1513
- if (!response.ok) {
1514
- throw new Error(`Failed to update dataset ${_datasetId}: ${response.status} ${response.statusText}`);
1515
- }
1525
+ await (0, error_js_1.raiseForStatus)(response, "update dataset");
1516
1526
  return (await response.json());
1517
1527
  }
1518
1528
  async deleteDataset({ datasetId, datasetName, }) {
@@ -1538,9 +1548,7 @@ class Client {
1538
1548
  signal: AbortSignal.timeout(this.timeout_ms),
1539
1549
  ...this.fetchOptions,
1540
1550
  });
1541
- if (!response.ok) {
1542
- throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
1543
- }
1551
+ await (0, error_js_1.raiseForStatus)(response, `delete ${path}`);
1544
1552
  await response.json();
1545
1553
  }
1546
1554
  async indexDataset({ datasetId, datasetName, tag, }) {
@@ -1566,9 +1574,7 @@ class Client {
1566
1574
  signal: AbortSignal.timeout(this.timeout_ms),
1567
1575
  ...this.fetchOptions,
1568
1576
  });
1569
- if (!response.ok) {
1570
- throw new Error(`Failed to index dataset ${datasetId_}: ${response.status} ${response.statusText}`);
1571
- }
1577
+ await (0, error_js_1.raiseForStatus)(response, "index dataset");
1572
1578
  await response.json();
1573
1579
  }
1574
1580
  /**
@@ -1607,9 +1613,7 @@ class Client {
1607
1613
  signal: AbortSignal.timeout(this.timeout_ms),
1608
1614
  ...this.fetchOptions,
1609
1615
  });
1610
- if (!response.ok) {
1611
- throw new Error(`Failed to fetch similar examples: ${response.status} ${response.statusText}`);
1612
- }
1616
+ await (0, error_js_1.raiseForStatus)(response, "fetch similar examples");
1613
1617
  const result = await response.json();
1614
1618
  return result["examples"];
1615
1619
  }
@@ -1642,9 +1646,7 @@ class Client {
1642
1646
  signal: AbortSignal.timeout(this.timeout_ms),
1643
1647
  ...this.fetchOptions,
1644
1648
  });
1645
- if (!response.ok) {
1646
- throw new Error(`Failed to create example: ${response.status} ${response.statusText}`);
1647
- }
1649
+ await (0, error_js_1.raiseForStatus)(response, "create example");
1648
1650
  const result = await response.json();
1649
1651
  return result;
1650
1652
  }
@@ -1679,9 +1681,7 @@ class Client {
1679
1681
  signal: AbortSignal.timeout(this.timeout_ms),
1680
1682
  ...this.fetchOptions,
1681
1683
  });
1682
- if (!response.ok) {
1683
- throw new Error(`Failed to create examples: ${response.status} ${response.statusText}`);
1684
- }
1684
+ await (0, error_js_1.raiseForStatus)(response, "create examples");
1685
1685
  const result = await response.json();
1686
1686
  return result;
1687
1687
  }
@@ -1774,9 +1774,7 @@ class Client {
1774
1774
  signal: AbortSignal.timeout(this.timeout_ms),
1775
1775
  ...this.fetchOptions,
1776
1776
  });
1777
- if (!response.ok) {
1778
- throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
1779
- }
1777
+ await (0, error_js_1.raiseForStatus)(response, `delete ${path}`);
1780
1778
  await response.json();
1781
1779
  }
1782
1780
  async updateExample(exampleId, update) {
@@ -1788,9 +1786,7 @@ class Client {
1788
1786
  signal: AbortSignal.timeout(this.timeout_ms),
1789
1787
  ...this.fetchOptions,
1790
1788
  });
1791
- if (!response.ok) {
1792
- throw new Error(`Failed to update example ${exampleId}: ${response.status} ${response.statusText}`);
1793
- }
1789
+ await (0, error_js_1.raiseForStatus)(response, "update example");
1794
1790
  const result = await response.json();
1795
1791
  return result;
1796
1792
  }
@@ -1802,9 +1798,7 @@ class Client {
1802
1798
  signal: AbortSignal.timeout(this.timeout_ms),
1803
1799
  ...this.fetchOptions,
1804
1800
  });
1805
- if (!response.ok) {
1806
- throw new Error(`Failed to update examples: ${response.status} ${response.statusText}`);
1807
- }
1801
+ await (0, error_js_1.raiseForStatus)(response, "update examples");
1808
1802
  const result = await response.json();
1809
1803
  return result;
1810
1804
  }
@@ -1867,7 +1861,7 @@ class Client {
1867
1861
  signal: AbortSignal.timeout(this.timeout_ms),
1868
1862
  ...this.fetchOptions,
1869
1863
  });
1870
- await raiseForStatus(response, "update dataset splits");
1864
+ await (0, error_js_1.raiseForStatus)(response, "update dataset splits", true);
1871
1865
  }
1872
1866
  /**
1873
1867
  * @deprecated This method is deprecated and will be removed in future LangSmith versions, use `evaluate` from `langsmith/evaluation` instead.
@@ -1933,7 +1927,7 @@ class Client {
1933
1927
  signal: AbortSignal.timeout(this.timeout_ms),
1934
1928
  ...this.fetchOptions,
1935
1929
  });
1936
- await raiseForStatus(response, "create feedback");
1930
+ await (0, error_js_1.raiseForStatus)(response, "create feedback", true);
1937
1931
  return feedback;
1938
1932
  }
1939
1933
  async updateFeedback(feedbackId, { score, value, correction, comment, }) {
@@ -1958,7 +1952,7 @@ class Client {
1958
1952
  signal: AbortSignal.timeout(this.timeout_ms),
1959
1953
  ...this.fetchOptions,
1960
1954
  });
1961
- await raiseForStatus(response, "update feedback");
1955
+ await (0, error_js_1.raiseForStatus)(response, "update feedback", true);
1962
1956
  }
1963
1957
  async readFeedback(feedbackId) {
1964
1958
  (0, _uuid_js_1.assertUuid)(feedbackId);
@@ -1975,9 +1969,7 @@ class Client {
1975
1969
  signal: AbortSignal.timeout(this.timeout_ms),
1976
1970
  ...this.fetchOptions,
1977
1971
  });
1978
- if (!response.ok) {
1979
- throw new Error(`Failed to delete ${path}: ${response.status} ${response.statusText}`);
1980
- }
1972
+ await (0, error_js_1.raiseForStatus)(response, `delete ${path}`);
1981
1973
  await response.json();
1982
1974
  }
1983
1975
  async *listFeedback({ runIds, feedbackKeys, feedbackSourceTypes, } = {}) {
@@ -2170,9 +2162,7 @@ class Client {
2170
2162
  signal: AbortSignal.timeout(this.timeout_ms),
2171
2163
  ...this.fetchOptions,
2172
2164
  });
2173
- if (!response.ok) {
2174
- throw new Error(`Failed to ${like ? "like" : "unlike"} prompt: ${response.status} ${await response.text()}`);
2175
- }
2165
+ await (0, error_js_1.raiseForStatus)(response, `${like ? "like" : "unlike"} prompt`);
2176
2166
  return await response.json();
2177
2167
  }
2178
2168
  async _getPromptUrl(promptIdentifier) {
@@ -2236,9 +2226,7 @@ class Client {
2236
2226
  if (response.status === 404) {
2237
2227
  return null;
2238
2228
  }
2239
- if (!response.ok) {
2240
- throw new Error(`Failed to get prompt: ${response.status} ${await response.text()}`);
2241
- }
2229
+ await (0, error_js_1.raiseForStatus)(response, "get prompt");
2242
2230
  const result = await response.json();
2243
2231
  if (result.repo) {
2244
2232
  return result.repo;
@@ -2273,9 +2261,7 @@ class Client {
2273
2261
  signal: AbortSignal.timeout(this.timeout_ms),
2274
2262
  ...this.fetchOptions,
2275
2263
  });
2276
- if (!response.ok) {
2277
- throw new Error(`Failed to create prompt: ${response.status} ${await response.text()}`);
2278
- }
2264
+ await (0, error_js_1.raiseForStatus)(response, "create prompt");
2279
2265
  const { repo } = await response.json();
2280
2266
  return repo;
2281
2267
  }
@@ -2298,9 +2284,7 @@ class Client {
2298
2284
  signal: AbortSignal.timeout(this.timeout_ms),
2299
2285
  ...this.fetchOptions,
2300
2286
  });
2301
- if (!response.ok) {
2302
- throw new Error(`Failed to create commit: ${response.status} ${await response.text()}`);
2303
- }
2287
+ await (0, error_js_1.raiseForStatus)(response, "create commit");
2304
2288
  const result = await response.json();
2305
2289
  return this._getPromptUrl(`${owner}/${promptName}${result.commit_hash ? `:${result.commit_hash}` : ""}`);
2306
2290
  }
@@ -2337,9 +2321,7 @@ class Client {
2337
2321
  signal: AbortSignal.timeout(this.timeout_ms),
2338
2322
  ...this.fetchOptions,
2339
2323
  });
2340
- if (!response.ok) {
2341
- throw new Error(`HTTP Error: ${response.status} - ${await response.text()}`);
2342
- }
2324
+ await (0, error_js_1.raiseForStatus)(response, "update prompt");
2343
2325
  return response.json();
2344
2326
  }
2345
2327
  async deletePrompt(promptIdentifier) {
@@ -2378,9 +2360,7 @@ class Client {
2378
2360
  signal: AbortSignal.timeout(this.timeout_ms),
2379
2361
  ...this.fetchOptions,
2380
2362
  });
2381
- if (!response.ok) {
2382
- throw new Error(`Failed to pull prompt commit: ${response.status} ${response.statusText}`);
2383
- }
2363
+ await (0, error_js_1.raiseForStatus)(response, "pull prompt commit");
2384
2364
  const result = await response.json();
2385
2365
  return {
2386
2366
  owner,
@@ -2433,5 +2413,86 @@ class Client {
2433
2413
  });
2434
2414
  return url;
2435
2415
  }
2416
+ /**
2417
+ * Clone a public dataset to your own langsmith tenant.
2418
+ * This operation is idempotent. If you already have a dataset with the given name,
2419
+ * this function will do nothing.
2420
+
2421
+ * @param {string} tokenOrUrl The token of the public dataset to clone.
2422
+ * @param {Object} [options] Additional options for cloning the dataset.
2423
+ * @param {string} [options.sourceApiUrl] The URL of the langsmith server where the data is hosted. Defaults to the API URL of your current client.
2424
+ * @param {string} [options.datasetName] The name of the dataset to create in your tenant. Defaults to the name of the public dataset.
2425
+ * @returns {Promise<void>}
2426
+ */
2427
+ async clonePublicDataset(tokenOrUrl, options = {}) {
2428
+ const { sourceApiUrl = this.apiUrl, datasetName } = options;
2429
+ const [parsedApiUrl, tokenUuid] = this.parseTokenOrUrl(tokenOrUrl, sourceApiUrl);
2430
+ const sourceClient = new Client({
2431
+ apiUrl: parsedApiUrl,
2432
+ // Placeholder API key not needed anymore in most cases, but
2433
+ // some private deployments may have API key-based rate limiting
2434
+ // that would cause this to fail if we provide no value.
2435
+ apiKey: "placeholder",
2436
+ });
2437
+ const ds = await sourceClient.readSharedDataset(tokenUuid);
2438
+ const finalDatasetName = datasetName || ds.name;
2439
+ try {
2440
+ if (await this.hasDataset({ datasetId: finalDatasetName })) {
2441
+ console.log(`Dataset ${finalDatasetName} already exists in your tenant. Skipping.`);
2442
+ return;
2443
+ }
2444
+ }
2445
+ catch (_) {
2446
+ // `.hasDataset` will throw an error if the dataset does not exist.
2447
+ // no-op in that case
2448
+ }
2449
+ // Fetch examples first, then create the dataset
2450
+ const examples = await sourceClient.listSharedExamples(tokenUuid);
2451
+ const dataset = await this.createDataset(finalDatasetName, {
2452
+ description: ds.description,
2453
+ dataType: ds.data_type || "kv",
2454
+ inputsSchema: ds.inputs_schema_definition ?? undefined,
2455
+ outputsSchema: ds.outputs_schema_definition ?? undefined,
2456
+ });
2457
+ try {
2458
+ await this.createExamples({
2459
+ inputs: examples.map((e) => e.inputs),
2460
+ outputs: examples.flatMap((e) => (e.outputs ? [e.outputs] : [])),
2461
+ datasetId: dataset.id,
2462
+ });
2463
+ }
2464
+ catch (e) {
2465
+ console.error(`An error occurred while creating dataset ${finalDatasetName}. ` +
2466
+ "You should delete it manually.");
2467
+ throw e;
2468
+ }
2469
+ }
2470
+ parseTokenOrUrl(urlOrToken, apiUrl, numParts = 2, kind = "dataset") {
2471
+ // Try parsing as UUID
2472
+ try {
2473
+ (0, _uuid_js_1.assertUuid)(urlOrToken); // Will throw if it's not a UUID.
2474
+ return [apiUrl, urlOrToken];
2475
+ }
2476
+ catch (_) {
2477
+ // no-op if it's not a uuid
2478
+ }
2479
+ // Parse as URL
2480
+ try {
2481
+ const parsedUrl = new URL(urlOrToken);
2482
+ const pathParts = parsedUrl.pathname
2483
+ .split("/")
2484
+ .filter((part) => part !== "");
2485
+ if (pathParts.length >= numParts) {
2486
+ const tokenUuid = pathParts[pathParts.length - numParts];
2487
+ return [apiUrl, tokenUuid];
2488
+ }
2489
+ else {
2490
+ throw new Error(`Invalid public ${kind} URL: ${urlOrToken}`);
2491
+ }
2492
+ }
2493
+ catch (error) {
2494
+ throw new Error(`Invalid public ${kind} URL or token: ${urlOrToken}`);
2495
+ }
2496
+ }
2436
2497
  }
2437
2498
  exports.Client = Client;
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { AsyncCallerParams } from "./utils/async_caller.js";
2
2
  import { ComparativeExperiment, DataType, Dataset, DatasetDiffInfo, DatasetShareSchema, Example, ExampleUpdate, ExampleUpdateWithId, Feedback, FeedbackConfig, FeedbackIngestToken, KVMap, LangChainBaseMessage, LangSmithSettings, LikePromptResponse, Prompt, PromptCommit, PromptSortField, Run, RunCreate, RunUpdate, ScoreType, ExampleSearch, TimeDelta, TracerSession, TracerSessionResult, ValueType } from "./schemas.js";
3
3
  import { EvaluationResult, EvaluationResults, RunEvaluator } from "./evaluation/evaluator.js";
4
- interface ClientConfig {
4
+ export interface ClientConfig {
5
5
  apiUrl?: string;
6
6
  apiKey?: string;
7
7
  callerOptions?: AsyncCallerParams;
@@ -332,6 +332,17 @@ export declare class Client {
332
332
  shareDataset(datasetId?: string, datasetName?: string): Promise<DatasetShareSchema>;
333
333
  unshareDataset(datasetId: string): Promise<void>;
334
334
  readSharedDataset(shareToken: string): Promise<Dataset>;
335
+ /**
336
+ * Get shared examples.
337
+ *
338
+ * @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.
339
+ * @param {Object} [options] Additional options for listing the examples.
340
+ * @param {string[] | undefined} [options.exampleIds] A list of example IDs to filter by.
341
+ * @returns {Promise<Example[]>} The shared examples.
342
+ */
343
+ listSharedExamples(shareToken: string, options?: {
344
+ exampleIds?: string[];
345
+ }): Promise<Example[]>;
335
346
  createProject({ projectName, description, metadata, upsert, projectExtra, referenceDatasetId, }: {
336
347
  projectName: string;
337
348
  description?: string | null;
@@ -379,11 +390,12 @@ export declare class Client {
379
390
  projectName?: string;
380
391
  }): Promise<void>;
381
392
  uploadCsv({ csvFile, fileName, inputKeys, outputKeys, description, dataType, name, }: UploadCSVParams): Promise<Dataset>;
382
- createDataset(name: string, { description, dataType, inputsSchema, outputsSchema, }?: {
393
+ createDataset(name: string, { description, dataType, inputsSchema, outputsSchema, metadata, }?: {
383
394
  description?: string;
384
395
  dataType?: DataType;
385
396
  inputsSchema?: KVMap;
386
397
  outputsSchema?: KVMap;
398
+ metadata?: RecordStringAny;
387
399
  }): Promise<Dataset>;
388
400
  readDataset({ datasetId, datasetName, }: {
389
401
  datasetId?: string;
@@ -403,12 +415,13 @@ export declare class Client {
403
415
  datasetId?: string;
404
416
  datasetName?: string;
405
417
  }): Promise<any[]>;
406
- listDatasets({ limit, offset, datasetIds, datasetName, datasetNameContains, }?: {
418
+ listDatasets({ limit, offset, datasetIds, datasetName, datasetNameContains, metadata, }?: {
407
419
  limit?: number;
408
420
  offset?: number;
409
421
  datasetIds?: string[];
410
422
  datasetName?: string;
411
423
  datasetNameContains?: string;
424
+ metadata?: RecordStringAny;
412
425
  }): AsyncIterable<Dataset>;
413
426
  /**
414
427
  * Update a dataset
@@ -625,5 +638,21 @@ export declare class Client {
625
638
  readme?: string;
626
639
  tags?: string[];
627
640
  }): Promise<string>;
641
+ /**
642
+ * Clone a public dataset to your own langsmith tenant.
643
+ * This operation is idempotent. If you already have a dataset with the given name,
644
+ * this function will do nothing.
645
+
646
+ * @param {string} tokenOrUrl The token of the public dataset to clone.
647
+ * @param {Object} [options] Additional options for cloning the dataset.
648
+ * @param {string} [options.sourceApiUrl] The URL of the langsmith server where the data is hosted. Defaults to the API URL of your current client.
649
+ * @param {string} [options.datasetName] The name of the dataset to create in your tenant. Defaults to the name of the public dataset.
650
+ * @returns {Promise<void>}
651
+ */
652
+ clonePublicDataset(tokenOrUrl: string, options?: {
653
+ sourceApiUrl?: string;
654
+ datasetName?: string;
655
+ }): Promise<void>;
656
+ private parseTokenOrUrl;
628
657
  }
629
658
  export {};