langsmith 0.5.6 → 0.5.8

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.
Files changed (38) hide show
  1. package/dist/client.cjs +378 -3
  2. package/dist/client.d.ts +202 -2
  3. package/dist/client.js +378 -3
  4. package/dist/evaluation/evaluator.cjs +1 -1
  5. package/dist/evaluation/evaluator.js +2 -2
  6. package/dist/experimental/anthropic/index.cjs +15 -1
  7. package/dist/experimental/anthropic/index.js +15 -1
  8. package/dist/experimental/vercel/index.cjs +23 -5
  9. package/dist/experimental/vercel/index.js +23 -5
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/utils/error.cjs +16 -0
  14. package/dist/utils/error.d.ts +8 -0
  15. package/dist/utils/error.js +15 -0
  16. package/dist/utils/fs.browser.cjs +51 -0
  17. package/dist/utils/fs.browser.d.ts +25 -0
  18. package/dist/utils/fs.browser.js +37 -0
  19. package/dist/utils/fs.cjs +101 -0
  20. package/dist/utils/fs.d.ts +21 -0
  21. package/dist/utils/fs.js +54 -0
  22. package/dist/utils/jestlike/vendor/evaluatedBy.cjs +2 -2
  23. package/dist/utils/jestlike/vendor/evaluatedBy.js +3 -3
  24. package/dist/utils/prompt_cache/index.cjs +31 -5
  25. package/dist/utils/prompt_cache/index.d.ts +3 -2
  26. package/dist/utils/prompt_cache/index.js +31 -5
  27. package/dist/utils/prompts.cjs +4 -3
  28. package/dist/utils/prompts.js +4 -3
  29. package/dist/wrappers/anthropic.cjs +8 -3
  30. package/dist/wrappers/anthropic.d.ts +5 -0
  31. package/dist/wrappers/anthropic.js +8 -4
  32. package/package.json +4 -4
  33. package/dist/utils/prompt_cache/fs.browser.cjs +0 -24
  34. package/dist/utils/prompt_cache/fs.browser.d.ts +0 -16
  35. package/dist/utils/prompt_cache/fs.browser.js +0 -20
  36. package/dist/utils/prompt_cache/fs.cjs +0 -86
  37. package/dist/utils/prompt_cache/fs.d.ts +0 -16
  38. package/dist/utils/prompt_cache/fs.js +0 -49
package/dist/client.js CHANGED
@@ -10,6 +10,7 @@ import { warnOnce } from "./utils/warn.js";
10
10
  import { parsePromptIdentifier } from "./utils/prompts.js";
11
11
  import { raiseForStatus, isLangSmithNotFoundError } from "./utils/error.js";
12
12
  import { promptCacheSingleton, } from "./utils/prompt_cache/index.js";
13
+ import * as fsUtils from "./utils/fs.js";
13
14
  import { _shouldStreamForGlobalFetchImplementation, _getFetchImplementation, } from "./singletons/fetch.js";
14
15
  import { serialize as serializePayloadForTracing } from "./utils/fast-safe-stringify/index.js";
15
16
  export function mergeRuntimeEnvIntoRun(run, cachedEnvVars, omitTracedRuntimeInfo) {
@@ -397,6 +398,18 @@ export class Client {
397
398
  writable: true,
398
399
  value: getLangSmithEnvironmentVariable("DISABLE_RUN_COMPRESSION") === "true"
399
400
  });
401
+ Object.defineProperty(this, "failedTracesDir", {
402
+ enumerable: true,
403
+ configurable: true,
404
+ writable: true,
405
+ value: void 0
406
+ });
407
+ Object.defineProperty(this, "failedTracesMaxBytes", {
408
+ enumerable: true,
409
+ configurable: true,
410
+ writable: true,
411
+ value: 100 * 1024 * 1024
412
+ });
400
413
  Object.defineProperty(this, "debug", {
401
414
  enumerable: true,
402
415
  configurable: true,
@@ -428,6 +441,16 @@ export class Client {
428
441
  }
429
442
  this.debug = config.debug ?? this.debug;
430
443
  this.fetchImplementation = config.fetchImplementation;
444
+ // Failed trace dump configuration
445
+ this.failedTracesDir =
446
+ getLangSmithEnvironmentVariable("FAILED_TRACES_DIR") || undefined;
447
+ const failedTracesMb = getLangSmithEnvironmentVariable("FAILED_TRACES_MAX_MB");
448
+ if (failedTracesMb) {
449
+ const n = parseInt(failedTracesMb, 10);
450
+ if (Number.isFinite(n) && n > 0) {
451
+ this.failedTracesMaxBytes = n * 1024 * 1024;
452
+ }
453
+ }
431
454
  // Use maxIngestMemoryBytes for both queues
432
455
  const maxMemory = config.maxIngestMemoryBytes ?? DEFAULT_MAX_SIZE_BYTES;
433
456
  this.batchIngestCaller = new AsyncCaller({
@@ -768,6 +791,63 @@ export class Client {
768
791
  }
769
792
  return Promise.all(promises);
770
793
  }
794
+ /**
795
+ * Persist a failed trace payload to a local fallback directory.
796
+ *
797
+ * Saves a self-contained JSON file containing the endpoint path, the HTTP
798
+ * headers required for replay, and the base64-encoded request body.
799
+ * Can be replayed later with a simple POST:
800
+ *
801
+ * POST /<endpoint>
802
+ * Content-Type: <value from saved headers>
803
+ * [Content-Encoding: <value from saved headers>]
804
+ * <decoded body>
805
+ */
806
+ static async _writeTraceToFallbackDir(directory, body, replayHeaders, endpoint, maxBytes) {
807
+ try {
808
+ const bodyBuffer = typeof body === "string"
809
+ ? Buffer.from(body, "utf8")
810
+ : Buffer.from(body);
811
+ const envelope = JSON.stringify({
812
+ version: 1,
813
+ endpoint,
814
+ headers: replayHeaders,
815
+ body_base64: bodyBuffer.toString("base64"),
816
+ });
817
+ const filename = `trace_${Date.now()}_${uuid.v4().slice(0, 8)}.json`;
818
+ const filepath = fsUtils.path.join(directory, filename);
819
+ if (!Client._fallbackDirsCreated.has(directory)) {
820
+ await fsUtils.mkdir(directory);
821
+ Client._fallbackDirsCreated.add(directory);
822
+ }
823
+ // Check budget before writing — drop new traces if over limit.
824
+ if (maxBytes !== undefined && maxBytes > 0) {
825
+ try {
826
+ const entries = await fsUtils.readdir(directory);
827
+ const traceFiles = entries.filter((f) => f.startsWith("trace_") && f.endsWith(".json"));
828
+ let total = 0;
829
+ for (const name of traceFiles) {
830
+ const { size } = await fsUtils.stat(fsUtils.path.join(directory, name));
831
+ total += size;
832
+ }
833
+ if (total >= maxBytes) {
834
+ console.warn(`Could not write trace to fallback dir ${directory} as it's ` +
835
+ `already over size limit (${total} bytes >= ${maxBytes} bytes). ` +
836
+ `Increase LANGSMITH_FAILED_TRACES_MAX_MB if possible.`);
837
+ return;
838
+ }
839
+ }
840
+ catch {
841
+ // budget check errors must never prevent writing
842
+ }
843
+ }
844
+ await fsUtils.writeFileAtomic(filepath, envelope);
845
+ console.warn(`LangSmith trace upload failed; data saved to ${filepath} for later replay.`);
846
+ }
847
+ catch (writeErr) {
848
+ console.error(`LangSmith tracing error: could not write trace to fallback dir ${directory}:`, writeErr);
849
+ }
850
+ }
771
851
  async _processBatch(batch, options) {
772
852
  if (!batch.length) {
773
853
  return;
@@ -1348,6 +1428,12 @@ export class Client {
1348
1428
  throw e;
1349
1429
  }
1350
1430
  console.warn(`${e.message.trim()}\n\nContext: ${context}`);
1431
+ if (this.failedTracesDir) {
1432
+ const bodyBuffer = await this._createNodeFetchBody(parts, boundary).catch(() => null);
1433
+ if (bodyBuffer) {
1434
+ await Client._writeTraceToFallbackDir(this.failedTracesDir, bodyBuffer, { "Content-Type": `multipart/form-data; boundary=${boundary}` }, "runs/multipart", this.failedTracesMaxBytes);
1435
+ }
1436
+ }
1351
1437
  }
1352
1438
  }
1353
1439
  async updateRun(runId, run, options) {
@@ -1701,6 +1787,128 @@ export class Client {
1701
1787
  }
1702
1788
  }
1703
1789
  }
1790
+ async *readThread(props) {
1791
+ const { threadId, projectId, projectName, isRoot = true, limit, filter: userFilter, order = "asc", } = props;
1792
+ if (!projectId && !projectName) {
1793
+ throw new Error("threadId requires projectId or projectName");
1794
+ }
1795
+ const threadFilter = `eq(thread_id, ${JSON.stringify(threadId)})`;
1796
+ const combinedFilter = userFilter
1797
+ ? `and(${threadFilter}, ${userFilter})`
1798
+ : threadFilter;
1799
+ yield* this.listRuns({
1800
+ projectId: projectId ?? undefined,
1801
+ projectName: projectName ?? undefined,
1802
+ isRoot,
1803
+ limit,
1804
+ filter: combinedFilter,
1805
+ order,
1806
+ });
1807
+ }
1808
+ async listThreads(props) {
1809
+ const { projectId, projectName, limit, offset = 0, filter, startTime, isRoot = true, } = props;
1810
+ if (!projectId && !projectName) {
1811
+ throw new Error("Either projectId or projectName must be provided");
1812
+ }
1813
+ if (projectId && projectName) {
1814
+ throw new Error("Provide exactly one of projectId or projectName");
1815
+ }
1816
+ const sessionId = projectId ?? (await this.readProject({ projectName: projectName })).id;
1817
+ const startTimeResolved = startTime ?? new Date(Date.now() - 1 * 24 * 60 * 60 * 1000);
1818
+ const runSelect = [
1819
+ "id",
1820
+ "name",
1821
+ "status",
1822
+ "start_time",
1823
+ "end_time",
1824
+ "thread_id",
1825
+ "trace_id",
1826
+ "run_type",
1827
+ "error",
1828
+ "tags",
1829
+ "session_id",
1830
+ "parent_run_id",
1831
+ "total_tokens",
1832
+ "total_cost",
1833
+ "dotted_order",
1834
+ "reference_example_id",
1835
+ "feedback_stats",
1836
+ "app_path",
1837
+ "completion_cost",
1838
+ "completion_tokens",
1839
+ "prompt_cost",
1840
+ "prompt_tokens",
1841
+ "first_token_time",
1842
+ ];
1843
+ const bodyQuery = {
1844
+ session: [sessionId],
1845
+ is_root: isRoot,
1846
+ limit: 100,
1847
+ order: "desc",
1848
+ select: runSelect,
1849
+ start_time: startTimeResolved.toISOString(),
1850
+ };
1851
+ if (filter != null) {
1852
+ bodyQuery.filter = filter;
1853
+ }
1854
+ const threadsMap = new Map();
1855
+ for await (const runs of this._getCursorPaginatedList("/runs/query", bodyQuery)) {
1856
+ for (const run of runs) {
1857
+ const tid = run.thread_id;
1858
+ if (tid) {
1859
+ const list = threadsMap.get(tid) ?? [];
1860
+ list.push(run);
1861
+ threadsMap.set(tid, list);
1862
+ }
1863
+ }
1864
+ }
1865
+ const result = [];
1866
+ for (const [threadId, runs] of threadsMap.entries()) {
1867
+ runs.sort((a, b) => {
1868
+ const aRun = a;
1869
+ const bRun = b;
1870
+ const aStart = aRun.start_time ?? "";
1871
+ const bStart = bRun.start_time ?? "";
1872
+ if (aStart !== bStart)
1873
+ return aStart.localeCompare(bStart);
1874
+ const aOrder = aRun.dotted_order ?? "";
1875
+ const bOrder = bRun.dotted_order ?? "";
1876
+ return aOrder.localeCompare(bOrder);
1877
+ });
1878
+ const startTimes = runs
1879
+ .map((r) => r.start_time)
1880
+ .filter(Boolean);
1881
+ const sortedTimes = [...startTimes].sort();
1882
+ const minStart = sortedTimes.length ? sortedTimes[0] : "";
1883
+ const maxStart = sortedTimes.length
1884
+ ? sortedTimes[sortedTimes.length - 1]
1885
+ : "";
1886
+ result.push({
1887
+ thread_id: threadId,
1888
+ runs,
1889
+ count: runs.length,
1890
+ filter: "",
1891
+ total_tokens: 0,
1892
+ total_cost: null,
1893
+ min_start_time: minStart,
1894
+ max_start_time: maxStart,
1895
+ latency_p50: 0,
1896
+ latency_p99: 0,
1897
+ feedback_stats: null,
1898
+ first_inputs: "",
1899
+ last_outputs: "",
1900
+ last_error: null,
1901
+ });
1902
+ }
1903
+ result.sort((a, b) => {
1904
+ const aMax = a.max_start_time ?? "";
1905
+ const bMax = b.max_start_time ?? "";
1906
+ return bMax.localeCompare(aMax);
1907
+ });
1908
+ const withOffset = offset > 0 ? result.slice(offset) : result;
1909
+ const withLimit = limit !== undefined ? withOffset.slice(0, limit) : withOffset;
1910
+ return withLimit;
1911
+ }
1704
1912
  async getRunStats({ id, trace, parentRun, runType, projectNames, projectIds, referenceExampleIds, startTime, endTime, error, query, filter, traceFilter, treeFilter, isRoot, dataSourceType, }) {
1705
1913
  let projectIds_ = projectIds || [];
1706
1914
  if (projectNames) {
@@ -2949,7 +3157,7 @@ export class Client {
2949
3157
  assertUuid(feedback_source.metadata["__run"].run_id);
2950
3158
  }
2951
3159
  const feedback = {
2952
- id: feedbackId ?? uuid.v4(),
3160
+ id: feedbackId ?? uuid.v7(),
2953
3161
  run_id: runId,
2954
3162
  key,
2955
3163
  score: _formatFeedbackScore(score),
@@ -3567,21 +3775,110 @@ export class Client {
3567
3775
  }
3568
3776
  }
3569
3777
  }
3778
+ /**
3779
+ * Check if a prompt exists.
3780
+ * @param promptIdentifier - The identifier of the prompt. Can be in the format:
3781
+ * - "promptName" (for private prompts, owner defaults to "-")
3782
+ * - "owner/promptName" (for prompts with explicit owner)
3783
+ * @returns A Promise that resolves to true if the prompt exists, false otherwise
3784
+ * @example
3785
+ * ```typescript
3786
+ * // Check if a prompt exists before creating a commit
3787
+ * if (await client.promptExists("my-prompt")) {
3788
+ * await client.createCommit("my-prompt", template);
3789
+ * } else {
3790
+ * await client.createPrompt("my-prompt");
3791
+ * }
3792
+ * ```
3793
+ */
3570
3794
  async promptExists(promptIdentifier) {
3571
3795
  const prompt = await this.getPrompt(promptIdentifier);
3572
3796
  return !!prompt;
3573
3797
  }
3798
+ /**
3799
+ * Like a prompt.
3800
+ * @param promptIdentifier - The identifier of the prompt. Can be in the format:
3801
+ * - "promptName" (for private prompts, owner defaults to "-")
3802
+ * - "owner/promptName" (for prompts with explicit owner)
3803
+ * @returns A Promise that resolves to the like response containing the updated like count
3804
+ * @example
3805
+ * ```typescript
3806
+ * // Like a prompt
3807
+ * const response = await client.likePrompt("owner/useful-prompt");
3808
+ * console.log(`Prompt now has ${response.likes} likes`);
3809
+ * ```
3810
+ */
3574
3811
  async likePrompt(promptIdentifier) {
3575
3812
  return this._likeOrUnlikePrompt(promptIdentifier, true);
3576
3813
  }
3814
+ /**
3815
+ * Unlike a prompt (remove a previously added like).
3816
+ * @param promptIdentifier - The identifier of the prompt. Can be in the format:
3817
+ * - "promptName" (for private prompts, owner defaults to "-")
3818
+ * - "owner/promptName" (for prompts with explicit owner)
3819
+ * @returns A Promise that resolves to the like response containing the updated like count
3820
+ * @example
3821
+ * ```typescript
3822
+ * // Unlike a prompt
3823
+ * const response = await client.unlikePrompt("owner/useful-prompt");
3824
+ * console.log(`Prompt now has ${response.likes} likes`);
3825
+ * ```
3826
+ */
3577
3827
  async unlikePrompt(promptIdentifier) {
3578
3828
  return this._likeOrUnlikePrompt(promptIdentifier, false);
3579
3829
  }
3580
- async *listCommits(promptOwnerAndName) {
3581
- for await (const commits of this._getPaginated(`/commits/${promptOwnerAndName}/`, new URLSearchParams(), (res) => res.commits)) {
3830
+ /**
3831
+ * List all commits for a prompt.
3832
+ * @param promptIdentifier - The identifier of the prompt. Can be in the format:
3833
+ * - "promptName" (for private prompts, owner defaults to "-")
3834
+ * - "owner/promptName" (for prompts with explicit owner)
3835
+ * - "promptName:commitHash" (commit hash is ignored, all commits are returned)
3836
+ * @returns An async iterable iterator of PromptCommit objects
3837
+ * @example
3838
+ * ```typescript
3839
+ * // List commits for a private prompt
3840
+ * for await (const commit of client.listCommits("my-prompt")) {
3841
+ * console.log(commit);
3842
+ * }
3843
+ *
3844
+ * // List commits for a prompt with explicit owner
3845
+ * for await (const commit of client.listCommits("owner/my-prompt")) {
3846
+ * console.log(commit);
3847
+ * }
3848
+ * ```
3849
+ */
3850
+ async *listCommits(promptIdentifier) {
3851
+ const [owner, promptName, _] = parsePromptIdentifier(promptIdentifier);
3852
+ for await (const commits of this._getPaginated(`/commits/${owner}/${promptName}/`, new URLSearchParams(), (res) => res.commits)) {
3582
3853
  yield* commits;
3583
3854
  }
3584
3855
  }
3856
+ /**
3857
+ * List prompts by filter.
3858
+ * @param options - Optional filters for listing prompts
3859
+ * @param options.isPublic - Filter by public/private prompts. If undefined, returns all prompts.
3860
+ * @param options.isArchived - Filter by archived status. Defaults to false (non-archived prompts only).
3861
+ * @param options.sortField - Field to sort by. Defaults to "updated_at".
3862
+ * @param options.query - Search query to filter prompts by name or description.
3863
+ * @returns An async iterable iterator of Prompt objects
3864
+ * @example
3865
+ * ```typescript
3866
+ * // List all prompts
3867
+ * for await (const prompt of client.listPrompts()) {
3868
+ * console.log(prompt);
3869
+ * }
3870
+ *
3871
+ * // List only public prompts
3872
+ * for await (const prompt of client.listPrompts({ isPublic: true })) {
3873
+ * console.log(prompt);
3874
+ * }
3875
+ *
3876
+ * // Search for prompts
3877
+ * for await (const prompt of client.listPrompts({ query: "translation" })) {
3878
+ * console.log(prompt);
3879
+ * }
3880
+ * ```
3881
+ */
3585
3882
  async *listPrompts(options) {
3586
3883
  const params = new URLSearchParams();
3587
3884
  params.append("sort_field", options?.sortField ?? "updated_at");
@@ -3597,6 +3894,22 @@ export class Client {
3597
3894
  yield* prompts;
3598
3895
  }
3599
3896
  }
3897
+ /**
3898
+ * Get a prompt by its identifier.
3899
+ * @param promptIdentifier - The identifier of the prompt. Can be in the format:
3900
+ * - "promptName" (for private prompts, owner defaults to "-")
3901
+ * - "owner/promptName" (for prompts with explicit owner)
3902
+ * - "promptName:commitHash" (commit hash is ignored, latest version is returned)
3903
+ * @returns A Promise that resolves to the Prompt object, or null if not found
3904
+ * @example
3905
+ * ```typescript
3906
+ * // Get a private prompt
3907
+ * const prompt = await client.getPrompt("my-prompt");
3908
+ *
3909
+ * // Get a public prompt
3910
+ * const publicPrompt = await client.getPrompt("owner/public-prompt");
3911
+ * ```
3912
+ */
3600
3913
  async getPrompt(promptIdentifier) {
3601
3914
  const [owner, promptName, _] = parsePromptIdentifier(promptIdentifier);
3602
3915
  const response = await this.caller.call(async () => {
@@ -3620,6 +3933,33 @@ export class Client {
3620
3933
  return null;
3621
3934
  }
3622
3935
  }
3936
+ /**
3937
+ * Create a new prompt.
3938
+ * @param promptIdentifier - The identifier for the new prompt. Can be in the format:
3939
+ * - "promptName" (creates a private prompt)
3940
+ * - "owner/promptName" (creates a prompt under a specific owner, must match your tenant)
3941
+ * @param options - Optional configuration for the prompt
3942
+ * @param options.description - A description of the prompt
3943
+ * @param options.readme - Markdown content for the prompt's README
3944
+ * @param options.tags - Array of tags to categorize the prompt
3945
+ * @param options.isPublic - Whether the prompt should be public. Requires a LangChain Hub handle.
3946
+ * @returns A Promise that resolves to the created Prompt object
3947
+ * @throws {Error} If creating a public prompt without a LangChain Hub handle, or if owner doesn't match current tenant
3948
+ * @example
3949
+ * ```typescript
3950
+ * // Create a private prompt
3951
+ * const prompt = await client.createPrompt("my-new-prompt", {
3952
+ * description: "A prompt for translations",
3953
+ * tags: ["translation", "language"]
3954
+ * });
3955
+ *
3956
+ * // Create a public prompt
3957
+ * const publicPrompt = await client.createPrompt("my-public-prompt", {
3958
+ * description: "A public translation prompt",
3959
+ * isPublic: true
3960
+ * });
3961
+ * ```
3962
+ */
3623
3963
  async createPrompt(promptIdentifier, options) {
3624
3964
  const settings = await this._getSettings();
3625
3965
  if (options?.isPublic && !settings.tenant_handle) {
@@ -3654,6 +3994,35 @@ export class Client {
3654
3994
  const { repo } = await response.json();
3655
3995
  return repo;
3656
3996
  }
3997
+ /**
3998
+ * Create a new commit for an existing prompt.
3999
+ * @param promptIdentifier - The identifier of the prompt. Can be in the format:
4000
+ * - "promptName" (for private prompts, owner defaults to "-")
4001
+ * - "owner/promptName" (for prompts with explicit owner)
4002
+ * @param object - The prompt object/manifest to commit (e.g., ChatPromptTemplate, messages array, etc.)
4003
+ * @param options - Optional configuration for the commit
4004
+ * @param options.parentCommitHash - The parent commit hash. Defaults to "latest" (the most recent commit).
4005
+ * @returns A Promise that resolves to the URL of the newly created commit
4006
+ * @throws {Error} If the prompt does not exist
4007
+ * @example
4008
+ * ```typescript
4009
+ * import { ChatPromptTemplate } from "@langchain/core/prompts";
4010
+ *
4011
+ * // Create a commit with a new version of the prompt
4012
+ * const template = ChatPromptTemplate.fromMessages([
4013
+ * ["system", "You are a helpful assistant."],
4014
+ * ["human", "{input}"]
4015
+ * ]);
4016
+ *
4017
+ * const commitUrl = await client.createCommit("my-prompt", template);
4018
+ * console.log(`Commit created: ${commitUrl}`);
4019
+ *
4020
+ * // Create a commit based on a specific parent commit
4021
+ * const commitUrl2 = await client.createCommit("my-prompt", template, {
4022
+ * parentCommitHash: "abc123def456"
4023
+ * });
4024
+ * ```
4025
+ */
3657
4026
  async createCommit(promptIdentifier, object, options) {
3658
4027
  if (!(await this.promptExists(promptIdentifier))) {
3659
4028
  throw new Error("Prompt does not exist, you must create it first.");
@@ -4137,6 +4506,12 @@ export class Client {
4137
4506
  }
4138
4507
  }
4139
4508
  }
4509
+ Object.defineProperty(Client, "_fallbackDirsCreated", {
4510
+ enumerable: true,
4511
+ configurable: true,
4512
+ writable: true,
4513
+ value: new Set()
4514
+ });
4140
4515
  function isExampleCreate(input) {
4141
4516
  return "dataset_id" in input || "dataset_name" in input;
4142
4517
  }
@@ -67,7 +67,7 @@ class DynamicRunEvaluator {
67
67
  * @returns A promise that extracts to the evaluation result.
68
68
  */
69
69
  async evaluateRun(run, example, options) {
70
- let sourceRunId = (0, uuid_1.v4)();
70
+ let sourceRunId = (0, uuid_1.v7)();
71
71
  const metadata = {
72
72
  targetRunId: run.id,
73
73
  };
@@ -1,4 +1,4 @@
1
- import { v4 as uuidv4 } from "uuid";
1
+ import { v7 as uuidv7 } from "uuid";
2
2
  import { traceable } from "../traceable.js";
3
3
  /**
4
4
  * Wraps an evaluator function + implements the RunEvaluator interface.
@@ -63,7 +63,7 @@ export class DynamicRunEvaluator {
63
63
  * @returns A promise that extracts to the evaluation result.
64
64
  */
65
65
  async evaluateRun(run, example, options) {
66
- let sourceRunId = uuidv4();
66
+ let sourceRunId = uuidv7();
67
67
  const metadata = {
68
68
  targetRunId: run.id,
69
69
  };
@@ -1,9 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wrapClaudeAgentSDK = wrapClaudeAgentSDK;
4
+ const module_1 = require("module");
4
5
  const traceable_js_1 = require("../../traceable.cjs");
5
6
  const context_js_1 = require("./context.cjs");
6
7
  const messages_js_1 = require("./messages.cjs");
8
+ function _getPackageVersion(packageName) {
9
+ try {
10
+ const req = (0, module_1.createRequire)(process.cwd() + "/package.json");
11
+ return req(`${packageName}/package.json`).version;
12
+ }
13
+ catch {
14
+ return undefined;
15
+ }
16
+ }
7
17
  /**
8
18
  * Wraps the Claude Agent SDK's query function to add LangSmith tracing.
9
19
  * Traces the entire agent interaction including all streaming messages.
@@ -110,7 +120,11 @@ function wrapClaudeAgentQuery(queryFn, defaultThis, baseConfig) {
110
120
  name: "claude.conversation",
111
121
  run_type: "chain",
112
122
  ...baseConfig,
113
- metadata: { ...baseConfig?.metadata },
123
+ metadata: {
124
+ ls_integration: "claude-agent-sdk",
125
+ ls_integration_version: _getPackageVersion("@anthropic-ai/claude-agent-sdk"),
126
+ ...baseConfig?.metadata,
127
+ },
114
128
  __deferredSerializableArgOptions: { maxDepth: 1 },
115
129
  processInputs,
116
130
  processOutputs,
@@ -1,6 +1,16 @@
1
+ import { createRequire } from "module";
1
2
  import { traceable, isTraceableFunction } from "../../traceable.js";
2
3
  import { StreamManager } from "./context.js";
3
4
  import { convertFromAnthropicMessage } from "./messages.js";
5
+ function _getPackageVersion(packageName) {
6
+ try {
7
+ const req = createRequire(process.cwd() + "/package.json");
8
+ return req(`${packageName}/package.json`).version;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
4
14
  /**
5
15
  * Wraps the Claude Agent SDK's query function to add LangSmith tracing.
6
16
  * Traces the entire agent interaction including all streaming messages.
@@ -107,7 +117,11 @@ function wrapClaudeAgentQuery(queryFn, defaultThis, baseConfig) {
107
117
  name: "claude.conversation",
108
118
  run_type: "chain",
109
119
  ...baseConfig,
110
- metadata: { ...baseConfig?.metadata },
120
+ metadata: {
121
+ ls_integration: "claude-agent-sdk",
122
+ ls_integration_version: _getPackageVersion("@anthropic-ai/claude-agent-sdk"),
123
+ ...baseConfig?.metadata,
124
+ },
111
125
  __deferredSerializableArgOptions: { maxDepth: 1 },
112
126
  processInputs,
113
127
  processOutputs,
@@ -1,6 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertMessageToTracedFormat = exports.wrapAISDK = exports.createLangSmithProviderOptions = void 0;
4
+ const module_1 = require("module");
5
+ function _getPackageVersion(packageName) {
6
+ try {
7
+ const req = (0, module_1.createRequire)(process.cwd() + "/package.json");
8
+ return req(`${packageName}/package.json`).version;
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
4
14
  const middleware_js_1 = require("./middleware.cjs");
5
15
  const utils_js_1 = require("./utils.cjs");
6
16
  Object.defineProperty(exports, "convertMessageToTracedFormat", { enumerable: true, get: function () { return utils_js_1.convertMessageToTracedFormat; } });
@@ -305,6 +315,14 @@ exports.createLangSmithProviderOptions = createLangSmithProviderOptions;
305
315
  * @returns returns.streamObject - Wrapped streamObject function that traces calls to LangSmith
306
316
  */
307
317
  const wrapAISDK = (ai, baseLsConfig) => {
318
+ const _baseLsConfig = {
319
+ ...baseLsConfig,
320
+ metadata: {
321
+ ls_integration: "vercel-ai-sdk",
322
+ ls_integration_version: _getPackageVersion("ai"),
323
+ ...baseLsConfig?.metadata,
324
+ },
325
+ };
308
326
  /**
309
327
  * Wrapped version of AI SDK's generateText with LangSmith tracing.
310
328
  *
@@ -326,7 +344,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
326
344
  const wrappedGenerateText = async (...args) => {
327
345
  const params = args[0];
328
346
  const { langsmith: runtimeLsConfig, ...providerOptions } = params.providerOptions ?? {};
329
- const { resolvedLsConfig, resolvedChildLLMRunConfig, resolvedToolConfig } = _resolveConfigs(baseLsConfig, runtimeLsConfig);
347
+ const { resolvedLsConfig, resolvedChildLLMRunConfig, resolvedToolConfig } = _resolveConfigs(_baseLsConfig, runtimeLsConfig);
330
348
  const hasExplicitOutput = "output" in params;
331
349
  const hasExplicitExperimentalOutput = "experimental_output" in params;
332
350
  const traceableFunc = (0, traceable_js_1.traceable)(async (...args) => {
@@ -378,7 +396,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
378
396
  wrappedGenerateObject = async (...args) => {
379
397
  const params = args[0];
380
398
  const { langsmith: runtimeLsConfig, ...providerOptions } = params.providerOptions ?? {};
381
- const { resolvedLsConfig, resolvedChildLLMRunConfig } = _resolveConfigs(baseLsConfig, runtimeLsConfig);
399
+ const { resolvedLsConfig, resolvedChildLLMRunConfig } = _resolveConfigs(_baseLsConfig, runtimeLsConfig);
382
400
  const traceableFunc = (0, traceable_js_1.traceable)(async (...args) => {
383
401
  const [params, ...rest] = args;
384
402
  const wrappedModel = ai.wrapLanguageModel({
@@ -446,7 +464,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
446
464
  const wrappedStreamText = (...args) => {
447
465
  const params = args[0];
448
466
  const { langsmith: runtimeLsConfig, ...providerOptions } = params.providerOptions ?? {};
449
- const { resolvedLsConfig, resolvedChildLLMRunConfig, resolvedToolConfig } = _resolveConfigs(baseLsConfig, runtimeLsConfig);
467
+ const { resolvedLsConfig, resolvedChildLLMRunConfig, resolvedToolConfig } = _resolveConfigs(_baseLsConfig, runtimeLsConfig);
450
468
  const hasExplicitOutput = "output" in params;
451
469
  const hasExplicitExperimentalOutput = "experimental_output" in params;
452
470
  const traceableFunc = (0, traceable_js_1.traceable)((...args) => {
@@ -499,7 +517,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
499
517
  wrappedStreamObject = (...args) => {
500
518
  const params = args[0];
501
519
  const { langsmith: runtimeLsConfig, ...providerOptions } = params.providerOptions ?? {};
502
- const { resolvedLsConfig, resolvedChildLLMRunConfig } = _resolveConfigs(baseLsConfig, runtimeLsConfig);
520
+ const { resolvedLsConfig, resolvedChildLLMRunConfig } = _resolveConfigs(_baseLsConfig, runtimeLsConfig);
503
521
  const traceableFunc = (0, traceable_js_1.traceable)((...args) => {
504
522
  const [params, ...rest] = args;
505
523
  const wrappedModel = ai.wrapLanguageModel({
@@ -563,7 +581,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
563
581
  construct(ToolLoopAgent, args) {
564
582
  const params = args[0] ?? {};
565
583
  const { langsmith: runtimeLsConfig } = params.providerOptions ?? {};
566
- const { resolvedLsConfig, resolvedChildLLMRunConfig, resolvedToolConfig, } = _resolveConfigs(baseLsConfig, runtimeLsConfig);
584
+ const { resolvedLsConfig, resolvedChildLLMRunConfig, resolvedToolConfig, } = _resolveConfigs(_baseLsConfig, runtimeLsConfig);
567
585
  let wrappedModel = params.model;
568
586
  if (wrappedModel != null) {
569
587
  wrappedModel = ai.wrapLanguageModel({