langsmith 0.1.12 → 0.1.13

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 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
@@ -1260,6 +1260,27 @@ class Client {
1260
1260
  }
1261
1261
  return result;
1262
1262
  }
1263
+ async diffDatasetVersions({ datasetId, datasetName, fromVersion, toVersion, }) {
1264
+ let datasetId_ = datasetId;
1265
+ if (datasetId_ === undefined && datasetName === undefined) {
1266
+ throw new Error("Must provide either datasetName or datasetId");
1267
+ }
1268
+ else if (datasetId_ !== undefined && datasetName !== undefined) {
1269
+ throw new Error("Must provide either datasetName or datasetId, not both");
1270
+ }
1271
+ else if (datasetId_ === undefined) {
1272
+ const dataset = await this.readDataset({ datasetName });
1273
+ datasetId_ = dataset.id;
1274
+ }
1275
+ const urlParams = new URLSearchParams({
1276
+ from_version: typeof fromVersion === "string"
1277
+ ? fromVersion
1278
+ : fromVersion.toISOString(),
1279
+ to_version: typeof toVersion === "string" ? toVersion : toVersion.toISOString(),
1280
+ });
1281
+ const response = await this._get(`/datasets/${datasetId_}/versions/diff`, urlParams);
1282
+ return response;
1283
+ }
1263
1284
  async readDatasetOpenaiFinetuning({ datasetId, datasetName, }) {
1264
1285
  const path = "/datasets";
1265
1286
  if (datasetId !== undefined) {
@@ -1413,7 +1434,7 @@ class Client {
1413
1434
  const path = `/examples/${exampleId}`;
1414
1435
  return await this._get(path);
1415
1436
  }
1416
- async *listExamples({ datasetId, datasetName, exampleIds, } = {}) {
1437
+ async *listExamples({ datasetId, datasetName, exampleIds, asOf, inlineS3Urls, } = {}) {
1417
1438
  let datasetId_;
1418
1439
  if (datasetId !== undefined && datasetName !== undefined) {
1419
1440
  throw new Error("Must provide either datasetName or datasetId, not both");
@@ -1429,6 +1450,16 @@ class Client {
1429
1450
  throw new Error("Must provide a datasetName or datasetId");
1430
1451
  }
1431
1452
  const params = new URLSearchParams({ dataset: datasetId_ });
1453
+ const dataset_version = asOf
1454
+ ? typeof asOf === "string"
1455
+ ? asOf
1456
+ : asOf?.toISOString()
1457
+ : undefined;
1458
+ if (dataset_version) {
1459
+ params.append("as_of", dataset_version);
1460
+ }
1461
+ const inlineS3Urls_ = inlineS3Urls ?? true;
1462
+ params.append("inline_s3_urls", inlineS3Urls_.toString());
1432
1463
  if (exampleIds !== undefined) {
1433
1464
  for (const id_ of exampleIds) {
1434
1465
  params.append("id", id_);
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;
@@ -344,6 +344,12 @@ export declare class Client {
344
344
  datasetId?: string;
345
345
  datasetName?: string;
346
346
  }): Promise<Dataset>;
347
+ diffDatasetVersions({ datasetId, datasetName, fromVersion, toVersion, }: {
348
+ datasetId?: string;
349
+ datasetName?: string;
350
+ fromVersion: string | Date;
351
+ toVersion: string | Date;
352
+ }): Promise<DatasetDiffInfo>;
347
353
  readDatasetOpenaiFinetuning({ datasetId, datasetName, }: {
348
354
  datasetId?: string;
349
355
  datasetName?: string;
@@ -371,10 +377,12 @@ export declare class Client {
371
377
  createLLMExample(input: string, generation: string | undefined, options: CreateExampleOptions): Promise<Example>;
372
378
  createChatExample(input: KVMap[] | LangChainBaseMessage[], generations: KVMap | LangChainBaseMessage | undefined, options: CreateExampleOptions): Promise<Example>;
373
379
  readExample(exampleId: string): Promise<Example>;
374
- listExamples({ datasetId, datasetName, exampleIds, }?: {
380
+ listExamples({ datasetId, datasetName, exampleIds, asOf, inlineS3Urls, }?: {
375
381
  datasetId?: string;
376
382
  datasetName?: string;
377
383
  exampleIds?: string[];
384
+ asOf?: string | Date;
385
+ inlineS3Urls?: boolean;
378
386
  }): AsyncIterable<Example>;
379
387
  deleteExample(exampleId: string): Promise<void>;
380
388
  updateExample(exampleId: string, update: ExampleUpdate): Promise<object>;
package/dist/client.js CHANGED
@@ -1233,6 +1233,27 @@ export class Client {
1233
1233
  }
1234
1234
  return result;
1235
1235
  }
1236
+ async diffDatasetVersions({ datasetId, datasetName, fromVersion, toVersion, }) {
1237
+ let datasetId_ = datasetId;
1238
+ if (datasetId_ === undefined && datasetName === undefined) {
1239
+ throw new Error("Must provide either datasetName or datasetId");
1240
+ }
1241
+ else if (datasetId_ !== undefined && datasetName !== undefined) {
1242
+ throw new Error("Must provide either datasetName or datasetId, not both");
1243
+ }
1244
+ else if (datasetId_ === undefined) {
1245
+ const dataset = await this.readDataset({ datasetName });
1246
+ datasetId_ = dataset.id;
1247
+ }
1248
+ const urlParams = new URLSearchParams({
1249
+ from_version: typeof fromVersion === "string"
1250
+ ? fromVersion
1251
+ : fromVersion.toISOString(),
1252
+ to_version: typeof toVersion === "string" ? toVersion : toVersion.toISOString(),
1253
+ });
1254
+ const response = await this._get(`/datasets/${datasetId_}/versions/diff`, urlParams);
1255
+ return response;
1256
+ }
1236
1257
  async readDatasetOpenaiFinetuning({ datasetId, datasetName, }) {
1237
1258
  const path = "/datasets";
1238
1259
  if (datasetId !== undefined) {
@@ -1386,7 +1407,7 @@ export class Client {
1386
1407
  const path = `/examples/${exampleId}`;
1387
1408
  return await this._get(path);
1388
1409
  }
1389
- async *listExamples({ datasetId, datasetName, exampleIds, } = {}) {
1410
+ async *listExamples({ datasetId, datasetName, exampleIds, asOf, inlineS3Urls, } = {}) {
1390
1411
  let datasetId_;
1391
1412
  if (datasetId !== undefined && datasetName !== undefined) {
1392
1413
  throw new Error("Must provide either datasetName or datasetId, not both");
@@ -1402,6 +1423,16 @@ export class Client {
1402
1423
  throw new Error("Must provide a datasetName or datasetId");
1403
1424
  }
1404
1425
  const params = new URLSearchParams({ dataset: datasetId_ });
1426
+ const dataset_version = asOf
1427
+ ? typeof asOf === "string"
1428
+ ? asOf
1429
+ : asOf?.toISOString()
1430
+ : undefined;
1431
+ if (dataset_version) {
1432
+ params.append("as_of", dataset_version);
1433
+ }
1434
+ const inlineS3Urls_ = inlineS3Urls ?? true;
1435
+ params.append("inline_s3_urls", inlineS3Urls_.toString());
1405
1436
  if (exampleIds !== undefined) {
1406
1437
  for (const id_ of exampleIds) {
1407
1438
  params.append("id", id_);
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.12";
9
+ exports.__version__ = "0.1.13";
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.12";
4
+ export declare const __version__ = "0.1.13";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Client } from "./client.js";
2
2
  export { RunTree } from "./run_trees.js";
3
3
  // Update using yarn bump-version
4
- export const __version__ = "0.1.12";
4
+ export const __version__ = "0.1.13";
package/dist/schemas.d.ts CHANGED
@@ -247,3 +247,8 @@ export interface FeedbackConfig {
247
247
  */
248
248
  categories?: FeedbackCategory[] | null;
249
249
  }
250
+ export interface DatasetDiffInfo {
251
+ examples_modified: string[];
252
+ examples_added: string[];
253
+ examples_removed: string[];
254
+ }
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;
@@ -1,5 +1,37 @@
1
- import type { OpenAI } from "openai";
2
1
  import type { Client } from "./index.js";
3
- export declare const wrapOpenAI: (openai: OpenAI, options?: {
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
- }) => OpenAI;
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
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.",
5
5
  "packageManager": "yarn@1.22.19",
6
6
  "files": [