langsmith 0.1.7 → 0.1.10

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
@@ -1,5 +1,9 @@
1
1
  # LangSmith Client SDK
2
2
 
3
+ ![NPM Version](https://img.shields.io/npm/v/langsmith?logo=npm)
4
+ [![JS Downloads](https://img.shields.io/npm/dm/langsmith)](https://www.npmjs.com/package/langsmith)
5
+
6
+
3
7
  This package contains the TypeScript client for interacting with the [LangSmith platform](https://smith.langchain.com/).
4
8
 
5
9
  To install:
package/dist/client.cjs CHANGED
@@ -328,15 +328,27 @@ class Client {
328
328
  return headers;
329
329
  }
330
330
  processInputs(inputs) {
331
- if (this.hideInputs) {
331
+ if (this.hideInputs === false) {
332
+ return inputs;
333
+ }
334
+ if (this.hideInputs === true) {
332
335
  return {};
333
336
  }
337
+ if (typeof this.hideInputs === "function") {
338
+ return this.hideInputs(inputs);
339
+ }
334
340
  return inputs;
335
341
  }
336
342
  processOutputs(outputs) {
337
- if (this.hideOutputs) {
343
+ if (this.hideOutputs === false) {
344
+ return outputs;
345
+ }
346
+ if (this.hideOutputs === true) {
338
347
  return {};
339
348
  }
349
+ if (typeof this.hideOutputs === "function") {
350
+ return this.hideOutputs(outputs);
351
+ }
340
352
  return outputs;
341
353
  }
342
354
  prepareRunCreateOrUpdateInputs(run) {
@@ -743,7 +755,89 @@ class Client {
743
755
  }
744
756
  return run;
745
757
  }
746
- async *listRuns({ projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, limit, }) {
758
+ /**
759
+ * List runs from the LangSmith server.
760
+ * @param projectId - The ID of the project to filter by.
761
+ * @param projectName - The name of the project to filter by.
762
+ * @param parentRunId - The ID of the parent run to filter by.
763
+ * @param traceId - The ID of the trace to filter by.
764
+ * @param referenceExampleId - The ID of the reference example to filter by.
765
+ * @param startTime - The start time to filter by.
766
+ * @param executionOrder - The execution order to filter by.
767
+ * @param runType - The run type to filter by.
768
+ * @param error - Indicates whether to filter by error runs.
769
+ * @param id - The ID of the run to filter by.
770
+ * @param query - The query string to filter by.
771
+ * @param filter - The filter string to apply to the run spans.
772
+ * @param traceFilter - The filter string to apply on the root run of the trace.
773
+ * @param limit - The maximum number of runs to retrieve.
774
+ * @returns {AsyncIterable<Run>} - The runs.
775
+ *
776
+ * @example
777
+ * // List all runs in a project
778
+ * const projectRuns = client.listRuns({ projectName: "<your_project>" });
779
+ *
780
+ * @example
781
+ * // List LLM and Chat runs in the last 24 hours
782
+ * const todaysLLMRuns = client.listRuns({
783
+ * projectName: "<your_project>",
784
+ * start_time: new Date(Date.now() - 24 * 60 * 60 * 1000),
785
+ * run_type: "llm",
786
+ * });
787
+ *
788
+ * @example
789
+ * // List traces in a project
790
+ * const rootRuns = client.listRuns({
791
+ * projectName: "<your_project>",
792
+ * execution_order: 1,
793
+ * });
794
+ *
795
+ * @example
796
+ * // List runs without errors
797
+ * const correctRuns = client.listRuns({
798
+ * projectName: "<your_project>",
799
+ * error: false,
800
+ * });
801
+ *
802
+ * @example
803
+ * // List runs by run ID
804
+ * const runIds = [
805
+ * "a36092d2-4ad5-4fb4-9c0d-0dba9a2ed836",
806
+ * "9398e6be-964f-4aa4-8ae9-ad78cd4b7074",
807
+ * ];
808
+ * const selectedRuns = client.listRuns({ run_ids: runIds });
809
+ *
810
+ * @example
811
+ * // List all "chain" type runs that took more than 10 seconds and had `total_tokens` greater than 5000
812
+ * const chainRuns = client.listRuns({
813
+ * projectName: "<your_project>",
814
+ * filter: 'and(eq(run_type, "chain"), gt(latency, 10), gt(total_tokens, 5000))',
815
+ * });
816
+ *
817
+ * @example
818
+ * // List all runs called "extractor" whose root of the trace was assigned feedback "user_score" score of 1
819
+ * const goodExtractorRuns = client.listRuns({
820
+ * projectName: "<your_project>",
821
+ * filter: 'eq(name, "extractor")',
822
+ * traceFilter: 'and(eq(feedback_key, "user_score"), eq(feedback_score, 1))',
823
+ * });
824
+ *
825
+ * @example
826
+ * // List all runs that started after a specific timestamp and either have "error" not equal to null or a "Correctness" feedback score equal to 0
827
+ * const complexRuns = client.listRuns({
828
+ * projectName: "<your_project>",
829
+ * filter: 'and(gt(start_time, "2023-07-15T12:34:56Z"), or(neq(error, null), and(eq(feedback_key, "Correctness"), eq(feedback_score, 0.0))))',
830
+ * });
831
+ *
832
+ * @example
833
+ * // List all runs where `tags` include "experimental" or "beta" and `latency` is greater than 2 seconds
834
+ * const taggedRuns = client.listRuns({
835
+ * projectName: "<your_project>",
836
+ * filter: 'and(or(has(tags, "experimental"), has(tags, "beta")), gt(latency, 2))',
837
+ * });
838
+ */
839
+ async *listRuns(props) {
840
+ const { projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, traceFilter, limit, } = props;
747
841
  let projectIds = [];
748
842
  if (projectId) {
749
843
  projectIds = Array.isArray(projectId) ? projectId : [projectId];
@@ -761,6 +855,7 @@ class Client {
761
855
  reference_example: referenceExampleId,
762
856
  query,
763
857
  filter,
858
+ trace_filter: traceFilter,
764
859
  execution_order: executionOrder,
765
860
  parent_run: parentRunId ? [parentRunId] : null,
766
861
  start_time: startTime ? startTime.toISOString() : null,
@@ -1400,7 +1495,7 @@ class Client {
1400
1495
  sourceRunId: feedbackResult?.sourceRunId,
1401
1496
  });
1402
1497
  }
1403
- async createFeedback(runId, key, { score, value, correction, comment, sourceInfo, feedbackSourceType = "api", sourceRunId, feedbackId, eager = false, }) {
1498
+ async createFeedback(runId, key, { score, value, correction, comment, sourceInfo, feedbackSourceType = "api", sourceRunId, feedbackId, feedbackConfig, }) {
1404
1499
  const feedback_source = {
1405
1500
  type: feedbackSourceType ?? "api",
1406
1501
  metadata: sourceInfo ?? {},
@@ -1423,8 +1518,9 @@ class Client {
1423
1518
  correction,
1424
1519
  comment,
1425
1520
  feedback_source: feedback_source,
1521
+ feedbackConfig,
1426
1522
  };
1427
- const url = `${this.apiUrl}/feedback` + (eager ? "/eager" : "");
1523
+ const url = `${this.apiUrl}/feedback`;
1428
1524
  const response = await this.caller.call(fetch, url, {
1429
1525
  method: "POST",
1430
1526
  headers: { ...this.headers, "Content-Type": "application/json" },
@@ -1495,5 +1591,60 @@ class Client {
1495
1591
  yield* feedbacks;
1496
1592
  }
1497
1593
  }
1594
+ /**
1595
+ * Creates a presigned feedback token and URL.
1596
+ *
1597
+ * The token can be used to authorize feedback metrics without
1598
+ * needing an API key. This is useful for giving browser-based
1599
+ * applications the ability to submit feedback without needing
1600
+ * to expose an API key.
1601
+ *
1602
+ * @param runId - The ID of the run.
1603
+ * @param feedbackKey - The feedback key.
1604
+ * @param options - Additional options for the token.
1605
+ * @param options.expiration - The expiration time for the token.
1606
+ *
1607
+ * @returns A promise that resolves to a FeedbackIngestToken.
1608
+ */
1609
+ async createPresignedFeedbackToken(runId, feedbackKey, { expiration, feedbackConfig, } = {}) {
1610
+ const body = {
1611
+ run_id: runId,
1612
+ feedback_key: feedbackKey,
1613
+ feedback_config: feedbackConfig,
1614
+ };
1615
+ if (expiration) {
1616
+ if (typeof expiration === "string") {
1617
+ body["expires_at"] = expiration;
1618
+ }
1619
+ else if (expiration?.hours || expiration?.minutes || expiration?.days) {
1620
+ body["expires_in"] = expiration;
1621
+ }
1622
+ }
1623
+ else {
1624
+ body["expires_in"] = {
1625
+ hours: 3,
1626
+ };
1627
+ }
1628
+ const response = await this.caller.call(fetch, `${this.apiUrl}/feedback/tokens`, {
1629
+ method: "POST",
1630
+ headers: { ...this.headers, "Content-Type": "application/json" },
1631
+ body: JSON.stringify(body),
1632
+ signal: AbortSignal.timeout(this.timeout_ms),
1633
+ });
1634
+ const result = await response.json();
1635
+ return result;
1636
+ }
1637
+ /**
1638
+ * Retrieves a list of presigned feedback tokens for a given run ID.
1639
+ * @param runId The ID of the run.
1640
+ * @returns An async iterable of FeedbackIngestToken objects.
1641
+ */
1642
+ async *listPresignedFeedbackTokens(runId) {
1643
+ assertUuid(runId);
1644
+ const params = new URLSearchParams({ run_id: runId });
1645
+ for await (const tokens of this._getPaginated("/feedback/tokens", params)) {
1646
+ yield* tokens;
1647
+ }
1648
+ }
1498
1649
  }
1499
1650
  exports.Client = Client;
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, KVMap, LangChainBaseMessage, Run, RunCreate, RunUpdate, ScoreType, TracerSession, TracerSessionResult, ValueType } from "./schemas.js";
2
+ import { DataType, Dataset, 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;
@@ -12,20 +12,82 @@ interface ClientConfig {
12
12
  autoBatchTracing?: boolean;
13
13
  pendingAutoBatchedRunLimit?: number;
14
14
  }
15
+ /**
16
+ * Represents the parameters for listing runs (spans) from the Langsmith server.
17
+ */
15
18
  interface ListRunsParams {
19
+ /**
20
+ * The ID or IDs of the project(s) to filter by.
21
+ */
16
22
  projectId?: string | string[];
23
+ /**
24
+ * The name or names of the project(s) to filter by.
25
+ */
17
26
  projectName?: string | string[];
27
+ /**
28
+ * The ID of the trace to filter by.
29
+ */
18
30
  traceId?: string;
31
+ /**
32
+ * The execution order to filter by.
33
+ */
19
34
  executionOrder?: number;
35
+ /**
36
+ * The ID of the parent run to filter by.
37
+ */
20
38
  parentRunId?: string;
39
+ /**
40
+ * The ID of the reference example to filter by.
41
+ */
21
42
  referenceExampleId?: string;
43
+ /**
44
+ * The start time to filter by.
45
+ */
22
46
  startTime?: Date;
47
+ /**
48
+ * The run type to filter by.
49
+ */
23
50
  runType?: string;
51
+ /**
52
+ * Indicates whether to filter by error runs.
53
+ */
24
54
  error?: boolean;
55
+ /**
56
+ * The ID or IDs of the runs to filter by.
57
+ */
25
58
  id?: string[];
59
+ /**
60
+ * The maximum number of runs to retrieve.
61
+ */
26
62
  limit?: number;
63
+ /**
64
+ * The query string to filter by.
65
+ */
27
66
  query?: string;
67
+ /**
68
+ * The filter string to apply.
69
+ *
70
+ * Run Filtering:
71
+ * Listing runs with query params is useful for simple queries, but doesn't support many common needs, such as filtering by metadata, tags, or other fields.
72
+ * LangSmith supports a filter query language to permit more complex filtering operations when fetching runs. This guide will provide a high level overview of the grammar as well as a few examples of when it can be useful.
73
+ * If you'd prefer a more visual guide, you can get a taste of the language by viewing the table of runs on any of your projects' pages. We provide some recommended filters to get you started that you can copy and use the SDK.
74
+ *
75
+ * Grammar:
76
+ * The filtering grammar is based on common comparators on fields in the run object. Supported comparators include:
77
+ * - gte (greater than or equal to)
78
+ * - gt (greater than)
79
+ * - lte (less than or equal to)
80
+ * - lt (less than)
81
+ * - eq (equal to)
82
+ * - neq (not equal to)
83
+ * - has (check if run contains a tag or metadata json blob)
84
+ * - search (search for a substring in a string field)
85
+ */
28
86
  filter?: string;
87
+ /**
88
+ * The trace filter string to apply. Uses the same grammar as the filter string.
89
+ */
90
+ traceFilter?: string;
29
91
  }
30
92
  interface UploadCSVParams {
31
93
  csvFile: Blob;
@@ -135,7 +197,88 @@ export declare class Client {
135
197
  projectOpts?: ProjectOptions;
136
198
  }): Promise<string>;
137
199
  private _loadChildRuns;
138
- listRuns({ projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, limit, }: ListRunsParams): AsyncIterable<Run>;
200
+ /**
201
+ * List runs from the LangSmith server.
202
+ * @param projectId - The ID of the project to filter by.
203
+ * @param projectName - The name of the project to filter by.
204
+ * @param parentRunId - The ID of the parent run to filter by.
205
+ * @param traceId - The ID of the trace to filter by.
206
+ * @param referenceExampleId - The ID of the reference example to filter by.
207
+ * @param startTime - The start time to filter by.
208
+ * @param executionOrder - The execution order to filter by.
209
+ * @param runType - The run type to filter by.
210
+ * @param error - Indicates whether to filter by error runs.
211
+ * @param id - The ID of the run to filter by.
212
+ * @param query - The query string to filter by.
213
+ * @param filter - The filter string to apply to the run spans.
214
+ * @param traceFilter - The filter string to apply on the root run of the trace.
215
+ * @param limit - The maximum number of runs to retrieve.
216
+ * @returns {AsyncIterable<Run>} - The runs.
217
+ *
218
+ * @example
219
+ * // List all runs in a project
220
+ * const projectRuns = client.listRuns({ projectName: "<your_project>" });
221
+ *
222
+ * @example
223
+ * // List LLM and Chat runs in the last 24 hours
224
+ * const todaysLLMRuns = client.listRuns({
225
+ * projectName: "<your_project>",
226
+ * start_time: new Date(Date.now() - 24 * 60 * 60 * 1000),
227
+ * run_type: "llm",
228
+ * });
229
+ *
230
+ * @example
231
+ * // List traces in a project
232
+ * const rootRuns = client.listRuns({
233
+ * projectName: "<your_project>",
234
+ * execution_order: 1,
235
+ * });
236
+ *
237
+ * @example
238
+ * // List runs without errors
239
+ * const correctRuns = client.listRuns({
240
+ * projectName: "<your_project>",
241
+ * error: false,
242
+ * });
243
+ *
244
+ * @example
245
+ * // List runs by run ID
246
+ * const runIds = [
247
+ * "a36092d2-4ad5-4fb4-9c0d-0dba9a2ed836",
248
+ * "9398e6be-964f-4aa4-8ae9-ad78cd4b7074",
249
+ * ];
250
+ * const selectedRuns = client.listRuns({ run_ids: runIds });
251
+ *
252
+ * @example
253
+ * // List all "chain" type runs that took more than 10 seconds and had `total_tokens` greater than 5000
254
+ * const chainRuns = client.listRuns({
255
+ * projectName: "<your_project>",
256
+ * filter: 'and(eq(run_type, "chain"), gt(latency, 10), gt(total_tokens, 5000))',
257
+ * });
258
+ *
259
+ * @example
260
+ * // List all runs called "extractor" whose root of the trace was assigned feedback "user_score" score of 1
261
+ * const goodExtractorRuns = client.listRuns({
262
+ * projectName: "<your_project>",
263
+ * filter: 'eq(name, "extractor")',
264
+ * traceFilter: 'and(eq(feedback_key, "user_score"), eq(feedback_score, 1))',
265
+ * });
266
+ *
267
+ * @example
268
+ * // List all runs that started after a specific timestamp and either have "error" not equal to null or a "Correctness" feedback score equal to 0
269
+ * const complexRuns = client.listRuns({
270
+ * projectName: "<your_project>",
271
+ * filter: 'and(gt(start_time, "2023-07-15T12:34:56Z"), or(neq(error, null), and(eq(feedback_key, "Correctness"), eq(feedback_score, 0.0))))',
272
+ * });
273
+ *
274
+ * @example
275
+ * // List all runs where `tags` include "experimental" or "beta" and `latency` is greater than 2 seconds
276
+ * const taggedRuns = client.listRuns({
277
+ * projectName: "<your_project>",
278
+ * filter: 'and(or(has(tags, "experimental"), has(tags, "beta")), gt(latency, 2))',
279
+ * });
280
+ */
281
+ listRuns(props: ListRunsParams): AsyncIterable<Run>;
139
282
  shareRun(runId: string, { shareId }?: {
140
283
  shareId?: string;
141
284
  }): Promise<string>;
@@ -233,13 +376,14 @@ export declare class Client {
233
376
  loadChildRuns: boolean;
234
377
  referenceExample?: Example;
235
378
  }): Promise<Feedback>;
236
- createFeedback(runId: string, key: string, { score, value, correction, comment, sourceInfo, feedbackSourceType, sourceRunId, feedbackId, eager, }: {
379
+ createFeedback(runId: string, key: string, { score, value, correction, comment, sourceInfo, feedbackSourceType, sourceRunId, feedbackId, feedbackConfig, }: {
237
380
  score?: ScoreType;
238
381
  value?: ValueType;
239
382
  correction?: object;
240
383
  comment?: string;
241
384
  sourceInfo?: object;
242
385
  feedbackSourceType?: FeedbackSourceType;
386
+ feedbackConfig?: FeedbackConfig;
243
387
  sourceRunId?: string;
244
388
  feedbackId?: string;
245
389
  eager?: boolean;
@@ -257,5 +401,30 @@ export declare class Client {
257
401
  feedbackKeys?: string[];
258
402
  feedbackSourceTypes?: FeedbackSourceType[];
259
403
  }): AsyncIterable<Feedback>;
404
+ /**
405
+ * Creates a presigned feedback token and URL.
406
+ *
407
+ * The token can be used to authorize feedback metrics without
408
+ * needing an API key. This is useful for giving browser-based
409
+ * applications the ability to submit feedback without needing
410
+ * to expose an API key.
411
+ *
412
+ * @param runId - The ID of the run.
413
+ * @param feedbackKey - The feedback key.
414
+ * @param options - Additional options for the token.
415
+ * @param options.expiration - The expiration time for the token.
416
+ *
417
+ * @returns A promise that resolves to a FeedbackIngestToken.
418
+ */
419
+ createPresignedFeedbackToken(runId: string, feedbackKey: string, { expiration, feedbackConfig, }?: {
420
+ expiration?: string | TimeDelta;
421
+ feedbackConfig?: FeedbackConfig;
422
+ }): Promise<FeedbackIngestToken>;
423
+ /**
424
+ * Retrieves a list of presigned feedback tokens for a given run ID.
425
+ * @param runId The ID of the run.
426
+ * @returns An async iterable of FeedbackIngestToken objects.
427
+ */
428
+ listPresignedFeedbackTokens(runId: string): AsyncIterable<FeedbackIngestToken>;
260
429
  }
261
430
  export {};
package/dist/client.js CHANGED
@@ -301,15 +301,27 @@ export class Client {
301
301
  return headers;
302
302
  }
303
303
  processInputs(inputs) {
304
- if (this.hideInputs) {
304
+ if (this.hideInputs === false) {
305
+ return inputs;
306
+ }
307
+ if (this.hideInputs === true) {
305
308
  return {};
306
309
  }
310
+ if (typeof this.hideInputs === "function") {
311
+ return this.hideInputs(inputs);
312
+ }
307
313
  return inputs;
308
314
  }
309
315
  processOutputs(outputs) {
310
- if (this.hideOutputs) {
316
+ if (this.hideOutputs === false) {
317
+ return outputs;
318
+ }
319
+ if (this.hideOutputs === true) {
311
320
  return {};
312
321
  }
322
+ if (typeof this.hideOutputs === "function") {
323
+ return this.hideOutputs(outputs);
324
+ }
313
325
  return outputs;
314
326
  }
315
327
  prepareRunCreateOrUpdateInputs(run) {
@@ -716,7 +728,89 @@ export class Client {
716
728
  }
717
729
  return run;
718
730
  }
719
- async *listRuns({ projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, limit, }) {
731
+ /**
732
+ * List runs from the LangSmith server.
733
+ * @param projectId - The ID of the project to filter by.
734
+ * @param projectName - The name of the project to filter by.
735
+ * @param parentRunId - The ID of the parent run to filter by.
736
+ * @param traceId - The ID of the trace to filter by.
737
+ * @param referenceExampleId - The ID of the reference example to filter by.
738
+ * @param startTime - The start time to filter by.
739
+ * @param executionOrder - The execution order to filter by.
740
+ * @param runType - The run type to filter by.
741
+ * @param error - Indicates whether to filter by error runs.
742
+ * @param id - The ID of the run to filter by.
743
+ * @param query - The query string to filter by.
744
+ * @param filter - The filter string to apply to the run spans.
745
+ * @param traceFilter - The filter string to apply on the root run of the trace.
746
+ * @param limit - The maximum number of runs to retrieve.
747
+ * @returns {AsyncIterable<Run>} - The runs.
748
+ *
749
+ * @example
750
+ * // List all runs in a project
751
+ * const projectRuns = client.listRuns({ projectName: "<your_project>" });
752
+ *
753
+ * @example
754
+ * // List LLM and Chat runs in the last 24 hours
755
+ * const todaysLLMRuns = client.listRuns({
756
+ * projectName: "<your_project>",
757
+ * start_time: new Date(Date.now() - 24 * 60 * 60 * 1000),
758
+ * run_type: "llm",
759
+ * });
760
+ *
761
+ * @example
762
+ * // List traces in a project
763
+ * const rootRuns = client.listRuns({
764
+ * projectName: "<your_project>",
765
+ * execution_order: 1,
766
+ * });
767
+ *
768
+ * @example
769
+ * // List runs without errors
770
+ * const correctRuns = client.listRuns({
771
+ * projectName: "<your_project>",
772
+ * error: false,
773
+ * });
774
+ *
775
+ * @example
776
+ * // List runs by run ID
777
+ * const runIds = [
778
+ * "a36092d2-4ad5-4fb4-9c0d-0dba9a2ed836",
779
+ * "9398e6be-964f-4aa4-8ae9-ad78cd4b7074",
780
+ * ];
781
+ * const selectedRuns = client.listRuns({ run_ids: runIds });
782
+ *
783
+ * @example
784
+ * // List all "chain" type runs that took more than 10 seconds and had `total_tokens` greater than 5000
785
+ * const chainRuns = client.listRuns({
786
+ * projectName: "<your_project>",
787
+ * filter: 'and(eq(run_type, "chain"), gt(latency, 10), gt(total_tokens, 5000))',
788
+ * });
789
+ *
790
+ * @example
791
+ * // List all runs called "extractor" whose root of the trace was assigned feedback "user_score" score of 1
792
+ * const goodExtractorRuns = client.listRuns({
793
+ * projectName: "<your_project>",
794
+ * filter: 'eq(name, "extractor")',
795
+ * traceFilter: 'and(eq(feedback_key, "user_score"), eq(feedback_score, 1))',
796
+ * });
797
+ *
798
+ * @example
799
+ * // List all runs that started after a specific timestamp and either have "error" not equal to null or a "Correctness" feedback score equal to 0
800
+ * const complexRuns = client.listRuns({
801
+ * projectName: "<your_project>",
802
+ * filter: 'and(gt(start_time, "2023-07-15T12:34:56Z"), or(neq(error, null), and(eq(feedback_key, "Correctness"), eq(feedback_score, 0.0))))',
803
+ * });
804
+ *
805
+ * @example
806
+ * // List all runs where `tags` include "experimental" or "beta" and `latency` is greater than 2 seconds
807
+ * const taggedRuns = client.listRuns({
808
+ * projectName: "<your_project>",
809
+ * filter: 'and(or(has(tags, "experimental"), has(tags, "beta")), gt(latency, 2))',
810
+ * });
811
+ */
812
+ async *listRuns(props) {
813
+ const { projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, traceFilter, limit, } = props;
720
814
  let projectIds = [];
721
815
  if (projectId) {
722
816
  projectIds = Array.isArray(projectId) ? projectId : [projectId];
@@ -734,6 +828,7 @@ export class Client {
734
828
  reference_example: referenceExampleId,
735
829
  query,
736
830
  filter,
831
+ trace_filter: traceFilter,
737
832
  execution_order: executionOrder,
738
833
  parent_run: parentRunId ? [parentRunId] : null,
739
834
  start_time: startTime ? startTime.toISOString() : null,
@@ -1373,7 +1468,7 @@ export class Client {
1373
1468
  sourceRunId: feedbackResult?.sourceRunId,
1374
1469
  });
1375
1470
  }
1376
- async createFeedback(runId, key, { score, value, correction, comment, sourceInfo, feedbackSourceType = "api", sourceRunId, feedbackId, eager = false, }) {
1471
+ async createFeedback(runId, key, { score, value, correction, comment, sourceInfo, feedbackSourceType = "api", sourceRunId, feedbackId, feedbackConfig, }) {
1377
1472
  const feedback_source = {
1378
1473
  type: feedbackSourceType ?? "api",
1379
1474
  metadata: sourceInfo ?? {},
@@ -1396,8 +1491,9 @@ export class Client {
1396
1491
  correction,
1397
1492
  comment,
1398
1493
  feedback_source: feedback_source,
1494
+ feedbackConfig,
1399
1495
  };
1400
- const url = `${this.apiUrl}/feedback` + (eager ? "/eager" : "");
1496
+ const url = `${this.apiUrl}/feedback`;
1401
1497
  const response = await this.caller.call(fetch, url, {
1402
1498
  method: "POST",
1403
1499
  headers: { ...this.headers, "Content-Type": "application/json" },
@@ -1468,4 +1564,59 @@ export class Client {
1468
1564
  yield* feedbacks;
1469
1565
  }
1470
1566
  }
1567
+ /**
1568
+ * Creates a presigned feedback token and URL.
1569
+ *
1570
+ * The token can be used to authorize feedback metrics without
1571
+ * needing an API key. This is useful for giving browser-based
1572
+ * applications the ability to submit feedback without needing
1573
+ * to expose an API key.
1574
+ *
1575
+ * @param runId - The ID of the run.
1576
+ * @param feedbackKey - The feedback key.
1577
+ * @param options - Additional options for the token.
1578
+ * @param options.expiration - The expiration time for the token.
1579
+ *
1580
+ * @returns A promise that resolves to a FeedbackIngestToken.
1581
+ */
1582
+ async createPresignedFeedbackToken(runId, feedbackKey, { expiration, feedbackConfig, } = {}) {
1583
+ const body = {
1584
+ run_id: runId,
1585
+ feedback_key: feedbackKey,
1586
+ feedback_config: feedbackConfig,
1587
+ };
1588
+ if (expiration) {
1589
+ if (typeof expiration === "string") {
1590
+ body["expires_at"] = expiration;
1591
+ }
1592
+ else if (expiration?.hours || expiration?.minutes || expiration?.days) {
1593
+ body["expires_in"] = expiration;
1594
+ }
1595
+ }
1596
+ else {
1597
+ body["expires_in"] = {
1598
+ hours: 3,
1599
+ };
1600
+ }
1601
+ const response = await this.caller.call(fetch, `${this.apiUrl}/feedback/tokens`, {
1602
+ method: "POST",
1603
+ headers: { ...this.headers, "Content-Type": "application/json" },
1604
+ body: JSON.stringify(body),
1605
+ signal: AbortSignal.timeout(this.timeout_ms),
1606
+ });
1607
+ const result = await response.json();
1608
+ return result;
1609
+ }
1610
+ /**
1611
+ * Retrieves a list of presigned feedback tokens for a given run ID.
1612
+ * @param runId The ID of the run.
1613
+ * @returns An async iterable of FeedbackIngestToken objects.
1614
+ */
1615
+ async *listPresignedFeedbackTokens(runId) {
1616
+ assertUuid(runId);
1617
+ const params = new URLSearchParams({ run_id: runId });
1618
+ for await (const tokens of this._getPaginated("/feedback/tokens", params)) {
1619
+ yield* tokens;
1620
+ }
1621
+ }
1471
1622
  }
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.7";
9
+ exports.__version__ = "0.1.10";
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.7";
4
+ export declare const __version__ = "0.1.10";
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.7";
4
+ export const __version__ = "0.1.10";
package/dist/schemas.d.ts CHANGED
@@ -209,3 +209,41 @@ export interface LangChainBaseMessage {
209
209
  content: string;
210
210
  additional_kwargs?: KVMap;
211
211
  }
212
+ export interface FeedbackIngestToken {
213
+ id: string;
214
+ url: string;
215
+ expires_at: string;
216
+ }
217
+ export interface TimeDelta {
218
+ days?: number;
219
+ hours?: number;
220
+ minutes?: number;
221
+ }
222
+ export interface FeedbackCategory {
223
+ value: number;
224
+ label?: string | null;
225
+ }
226
+ /**
227
+ * Represents the configuration for feedback.
228
+ * This determines how the LangSmith service interprets feedback
229
+ * values of the associated key.
230
+ */
231
+ export interface FeedbackConfig {
232
+ /**
233
+ * The type of feedback.
234
+ */
235
+ type: "continuous" | "categorical" | "freeform";
236
+ /**
237
+ * The minimum value for continuous feedback.
238
+ */
239
+ min?: number | null;
240
+ /**
241
+ * The maximum value for continuous feedback.
242
+ */
243
+ max?: number | null;
244
+ /**
245
+ * If feedback is categorical, this defines the valid categories the server will accept.
246
+ * Not applicable to continuous or freeform feedback types.
247
+ */
248
+ categories?: FeedbackCategory[] | null;
249
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.1.7",
3
+ "version": "0.1.10",
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": [