langsmith 0.8.10 → 0.8.12

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 (43) hide show
  1. package/dist/_openapi_client/resources/issues.d.ts +6 -0
  2. package/dist/_openapi_client/resources/online-evaluators.cjs +2 -2
  3. package/dist/_openapi_client/resources/online-evaluators.d.ts +7 -2
  4. package/dist/_openapi_client/resources/online-evaluators.js +2 -2
  5. package/dist/_openapi_client/resources/public/runs.d.ts +1 -1
  6. package/dist/_openapi_client/resources/sandboxes/boxes.cjs +2 -0
  7. package/dist/_openapi_client/resources/sandboxes/boxes.d.ts +25 -0
  8. package/dist/_openapi_client/resources/sandboxes/boxes.js +2 -0
  9. package/dist/_openapi_client/resources/sandboxes/sandboxes.d.ts +7 -2
  10. package/dist/_openapi_client/resources/sandboxes/sandboxes.js +1 -1
  11. package/dist/_openapi_client/resources/sandboxes/snapshots.cjs +12 -2
  12. package/dist/_openapi_client/resources/sandboxes/snapshots.d.ts +25 -3
  13. package/dist/_openapi_client/resources/sandboxes/snapshots.js +12 -2
  14. package/dist/_openapi_client/resources/threads.cjs +1 -1
  15. package/dist/_openapi_client/resources/threads.d.ts +26 -1
  16. package/dist/_openapi_client/resources/threads.js +1 -1
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +1 -1
  20. package/dist/sandbox/client.cjs +66 -12
  21. package/dist/sandbox/client.d.ts +31 -5
  22. package/dist/sandbox/client.js +66 -12
  23. package/dist/sandbox/errors.cjs +17 -6
  24. package/dist/sandbox/errors.d.ts +12 -5
  25. package/dist/sandbox/errors.js +15 -5
  26. package/dist/sandbox/index.cjs +3 -1
  27. package/dist/sandbox/index.d.ts +3 -3
  28. package/dist/sandbox/index.js +2 -2
  29. package/dist/sandbox/mounts.cjs +25 -2
  30. package/dist/sandbox/mounts.d.ts +12 -1
  31. package/dist/sandbox/mounts.js +24 -2
  32. package/dist/sandbox/proxy_config.cjs +28 -4
  33. package/dist/sandbox/proxy_config.d.ts +4 -2
  34. package/dist/sandbox/proxy_config.js +28 -4
  35. package/dist/sandbox/sandbox.cjs +27 -1
  36. package/dist/sandbox/sandbox.d.ts +25 -1
  37. package/dist/sandbox/sandbox.js +28 -2
  38. package/dist/sandbox/types.d.ts +71 -1
  39. package/dist/sandbox/ws_execute.cjs +7 -3
  40. package/dist/sandbox/ws_execute.js +8 -4
  41. package/dist/wrappers/anthropic.cjs +39 -6
  42. package/dist/wrappers/anthropic.js +39 -6
  43. package/package.json +12 -2
@@ -400,6 +400,10 @@ export class SandboxClient {
400
400
  * Callers can add specific status checks (e.g. 404) before calling this.
401
401
  * @internal
402
402
  */
403
+ _boxUrl(name, ...segments) {
404
+ const suffix = segments.length ? `/${segments.join("/")}` : "";
405
+ return `${this._baseUrl}/boxes/${encodeURIComponent(name)}${suffix}`;
406
+ }
403
407
  async _postJson(url, body, options) {
404
408
  const response = await this._fetch(url, {
405
409
  method: "POST",
@@ -484,7 +488,7 @@ export class SandboxClient {
484
488
  * @throws LangSmithResourceNotFoundError if sandbox not found.
485
489
  */
486
490
  async getSandbox(name, options) {
487
- const url = `${this._baseUrl}/boxes/${encodeURIComponent(name)}`;
491
+ const url = this._boxUrl(name);
488
492
  const response = await this._fetch(url, { signal: options?.signal });
489
493
  if (!response.ok) {
490
494
  if (response.status === 404) {
@@ -524,7 +528,7 @@ export class SandboxClient {
524
528
  deleteAfterStopSeconds === undefined) {
525
529
  return this.getSandbox(name);
526
530
  }
527
- const url = `${this._baseUrl}/boxes/${encodeURIComponent(name)}`;
531
+ const url = this._boxUrl(name);
528
532
  const payload = {};
529
533
  if (newName !== undefined) {
530
534
  payload.name = newName;
@@ -561,7 +565,7 @@ export class SandboxClient {
561
565
  * @throws LangSmithResourceNotFoundError if sandbox not found.
562
566
  */
563
567
  async deleteSandbox(name) {
564
- const url = `${this._baseUrl}/boxes/${encodeURIComponent(name)}`;
568
+ const url = this._boxUrl(name);
565
569
  const response = await this._fetch(url, { method: "DELETE" });
566
570
  if (!response.ok) {
567
571
  if (response.status === 404) {
@@ -581,7 +585,7 @@ export class SandboxClient {
581
585
  * @throws LangSmithResourceNotFoundError if sandbox not found.
582
586
  */
583
587
  async getSandboxStatus(name, options) {
584
- const url = `${this._baseUrl}/boxes/${encodeURIComponent(name)}/status`;
588
+ const url = this._boxUrl(name, "status");
585
589
  const response = await this._fetch(url, { signal: options?.signal });
586
590
  if (!response.ok) {
587
591
  if (response.status === 404) {
@@ -644,17 +648,61 @@ export class SandboxClient {
644
648
  */
645
649
  async startSandbox(name, options = {}) {
646
650
  const { timeout = 120, signal } = options;
647
- const url = `${this._baseUrl}/boxes/${encodeURIComponent(name)}/start`;
651
+ const url = this._boxUrl(name, "start");
648
652
  await this._postJson(url, {}, { signal });
649
653
  return this.waitForSandbox(name, { timeout, signal });
650
654
  }
655
+ /**
656
+ * Create a link that downloads one file from a sandbox.
657
+ *
658
+ * The link carries its own token, so anyone holding the URL can fetch that
659
+ * one file without a LangSmith credential. It is pinned to the sandbox and
660
+ * the exact path and cannot be repointed at another file. Fetching wakes a
661
+ * stopped sandbox.
662
+ *
663
+ * Do not modify the file after minting a link for it. The link is pinned to
664
+ * a path, not to a snapshot of the contents, so a later write to that path
665
+ * may or may not be reflected in what the link serves. Write a new file and
666
+ * mint a new link when the contents change.
667
+ *
668
+ * @param name - Sandbox name.
669
+ * @param path - File path inside the sandbox.
670
+ * @param options - Expiry and response header overrides.
671
+ * @returns The link and its expiry, if any.
672
+ *
673
+ * @example
674
+ * ```typescript
675
+ * const link = await client.generateDownloadURL("my-vm", "/tmp/report.pdf");
676
+ * console.log(link.download_url);
677
+ * ```
678
+ */
679
+ async generateDownloadURL(name, path, options = {}) {
680
+ const { expiresInSeconds, contentType, contentDisposition, signal } = options;
681
+ if (expiresInSeconds !== undefined && expiresInSeconds < 1) {
682
+ throw new LangSmithValidationError(`expiresInSeconds must be greater than 0 (got ${expiresInSeconds}); ` +
683
+ `omit it for a link that never expires`);
684
+ }
685
+ const url = this._boxUrl(name, "download-url");
686
+ const payload = { path };
687
+ if (expiresInSeconds !== undefined) {
688
+ payload.expires_in_seconds = expiresInSeconds;
689
+ }
690
+ if (contentType !== undefined) {
691
+ payload.content_type = contentType;
692
+ }
693
+ if (contentDisposition !== undefined) {
694
+ payload.content_disposition = contentDisposition;
695
+ }
696
+ const response = await this._postJson(url, payload, { signal });
697
+ return (await response.json());
698
+ }
651
699
  /**
652
700
  * Stop a running sandbox (preserves sandbox files for later restart).
653
701
  *
654
702
  * @param name - Sandbox name.
655
703
  */
656
704
  async stopSandbox(name) {
657
- const url = `${this._baseUrl}/boxes/${encodeURIComponent(name)}/stop`;
705
+ const url = this._boxUrl(name, "stop");
658
706
  await this._postJson(url, {});
659
707
  }
660
708
  // =========================================================================
@@ -695,13 +743,19 @@ export class SandboxClient {
695
743
  *
696
744
  * @param name - Snapshot name.
697
745
  * @param dockerfile - Local Dockerfile path, relative to context by default.
698
- * @param fsCapacityBytes - Filesystem capacity in bytes.
699
- * @param options - Build context, args, target, build log callback, builder
700
- * vCPUs/memory, timeout.
746
+ * @param fsCapacityBytesOrOptions - Optional filesystem capacity in bytes, or
747
+ * build options. When omitted, the server applies its default capacity.
748
+ * @param options - Build options when capacity is passed separately.
701
749
  * @returns Snapshot in "ready" status.
702
750
  */
703
- async createSnapshotFromDockerfile(name, dockerfile, fsCapacityBytes, options = {}) {
704
- const { context = ".", buildArgs, target, onBuildLog, vCpus, memBytes, timeout = 60, } = options;
751
+ async createSnapshotFromDockerfile(name, dockerfile, fsCapacityBytesOrOptions, options = {}) {
752
+ const fsCapacityBytes = typeof fsCapacityBytesOrOptions === "number"
753
+ ? fsCapacityBytesOrOptions
754
+ : undefined;
755
+ const resolvedOptions = typeof fsCapacityBytesOrOptions === "number"
756
+ ? options
757
+ : (fsCapacityBytesOrOptions ?? options);
758
+ const { context = ".", buildArgs, target, onBuildLog, vCpus, memBytes, timeout = 60, } = resolvedOptions;
705
759
  const { contextPath, dockerfileRel } = await resolveDockerfileContext(dockerfile, context);
706
760
  const builderName = `snapshot-builder-${uuidv4().replace(/-/g, "").slice(0, 12)}`;
707
761
  // Stage the build on the capacity-backed root filesystem, not /tmp.
@@ -769,7 +823,7 @@ export class SandboxClient {
769
823
  */
770
824
  async captureSnapshot(sandboxName, name, options = {}) {
771
825
  const { dockerImage, fsCapacityBytes, timeout = 60, signal } = options;
772
- const url = `${this._baseUrl}/boxes/${encodeURIComponent(sandboxName)}/snapshot`;
826
+ const url = this._boxUrl(sandboxName, "snapshot");
773
827
  const payload = { name };
774
828
  if (dockerImage !== undefined) {
775
829
  payload.docker_image = dockerImage;
@@ -7,7 +7,7 @@
7
7
  * properties for specific handling when needed.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.LangSmithSandboxServerReloadError = exports.LangSmithSandboxConnectTimeoutError = exports.LangSmithStreamEndedBeforeStartedError = exports.LangSmithCommandTimeoutError = exports.LangSmithSandboxOperationError = exports.LangSmithSandboxNotReadyError = exports.LangSmithDataplaneNotConfiguredError = exports.LangSmithSandboxCreationError = exports.LangSmithResourceCreationError = exports.LangSmithQuotaExceededError = exports.LangSmithValidationError = exports.LangSmithResourceNameConflictError = exports.LangSmithResourceAlreadyExistsError = exports.LangSmithResourceInUseError = exports.LangSmithResourceTimeoutError = exports.LangSmithResourceNotFoundError = exports.LangSmithSandboxConnectionError = exports.LangSmithSandboxAuthenticationError = exports.LangSmithSandboxAPIError = exports.LangSmithSandboxError = void 0;
10
+ exports.LangSmithSandboxServerReloadError = exports.LangSmithSandboxConnectTimeoutError = exports.LangSmithStreamEndedBeforeStartedError = exports.LangSmithCommandTimeoutError = exports.LangSmithSandboxOperationError = exports.LangSmithSandboxNotReadyError = exports.LangSmithDataplaneNotConfiguredError = exports.LangSmithSandboxCreationError = exports.LangSmithResourceCreationError = exports.LangSmithQuotaExceededError = exports.LangSmithValidationError = exports.LangSmithResourceNameConflictError = exports.LangSmithResourceAlreadyExistsError = exports.LangSmithResourceInUseError = exports.LangSmithResourceTimeoutError = exports.LangSmithResourceNotFoundError = exports.LangSmithSandboxRetryableConnectionError = exports.LangSmithSandboxConnectionError = exports.LangSmithSandboxAuthenticationError = exports.LangSmithSandboxAPIError = exports.LangSmithSandboxError = void 0;
11
11
  /**
12
12
  * Base exception for sandbox client errors.
13
13
  */
@@ -53,6 +53,19 @@ class LangSmithSandboxConnectionError extends LangSmithSandboxError {
53
53
  }
54
54
  }
55
55
  exports.LangSmithSandboxConnectionError = LangSmithSandboxConnectionError;
56
+ /**
57
+ * Raised when a transient connection failure occurs before a command starts.
58
+ *
59
+ * `run()` retries this error with the same command ID so the server can
60
+ * deduplicate an attempt whose outcome is unknown.
61
+ */
62
+ class LangSmithSandboxRetryableConnectionError extends LangSmithSandboxConnectionError {
63
+ constructor(message) {
64
+ super(message);
65
+ this.name = "LangSmithSandboxRetryableConnectionError";
66
+ }
67
+ }
68
+ exports.LangSmithSandboxRetryableConnectionError = LangSmithSandboxRetryableConnectionError;
56
69
  // =============================================================================
57
70
  // Resource Errors (type-based, with resourceType property)
58
71
  // =============================================================================
@@ -375,12 +388,10 @@ exports.LangSmithStreamEndedBeforeStartedError = LangSmithStreamEndedBeforeStart
375
388
  /**
376
389
  * Thrown when the socket fails or times out before the WebSocket handshake.
377
390
  *
378
- * Distinct from its parent because it is safely retryable: the execute frame
379
- * was never sent, so re-issuing the same command_id cannot double-run a
380
- * command. run() retries this with backoff; a plain connection error (a
381
- * rejected handshake) is permanent and propagates immediately.
391
+ * The execute frame was never sent, so re-issuing the same command ID cannot
392
+ * double-run a command.
382
393
  */
383
- class LangSmithSandboxConnectTimeoutError extends LangSmithSandboxConnectionError {
394
+ class LangSmithSandboxConnectTimeoutError extends LangSmithSandboxRetryableConnectionError {
384
395
  constructor(message) {
385
396
  super(message);
386
397
  this.name = "LangSmithSandboxConnectTimeoutError";
@@ -31,6 +31,15 @@ export declare class LangSmithSandboxAuthenticationError extends LangSmithSandbo
31
31
  export declare class LangSmithSandboxConnectionError extends LangSmithSandboxError {
32
32
  constructor(message: string);
33
33
  }
34
+ /**
35
+ * Raised when a transient connection failure occurs before a command starts.
36
+ *
37
+ * `run()` retries this error with the same command ID so the server can
38
+ * deduplicate an attempt whose outcome is unknown.
39
+ */
40
+ export declare class LangSmithSandboxRetryableConnectionError extends LangSmithSandboxConnectionError {
41
+ constructor(message: string);
42
+ }
34
43
  /**
35
44
  * Raised when a resource is not found.
36
45
  */
@@ -168,12 +177,10 @@ export declare class LangSmithStreamEndedBeforeStartedError extends LangSmithSan
168
177
  /**
169
178
  * Thrown when the socket fails or times out before the WebSocket handshake.
170
179
  *
171
- * Distinct from its parent because it is safely retryable: the execute frame
172
- * was never sent, so re-issuing the same command_id cannot double-run a
173
- * command. run() retries this with backoff; a plain connection error (a
174
- * rejected handshake) is permanent and propagates immediately.
180
+ * The execute frame was never sent, so re-issuing the same command ID cannot
181
+ * double-run a command.
175
182
  */
176
- export declare class LangSmithSandboxConnectTimeoutError extends LangSmithSandboxConnectionError {
183
+ export declare class LangSmithSandboxConnectTimeoutError extends LangSmithSandboxRetryableConnectionError {
177
184
  constructor(message: string);
178
185
  }
179
186
  /**
@@ -46,6 +46,18 @@ export class LangSmithSandboxConnectionError extends LangSmithSandboxError {
46
46
  this.name = "LangSmithSandboxConnectionError";
47
47
  }
48
48
  }
49
+ /**
50
+ * Raised when a transient connection failure occurs before a command starts.
51
+ *
52
+ * `run()` retries this error with the same command ID so the server can
53
+ * deduplicate an attempt whose outcome is unknown.
54
+ */
55
+ export class LangSmithSandboxRetryableConnectionError extends LangSmithSandboxConnectionError {
56
+ constructor(message) {
57
+ super(message);
58
+ this.name = "LangSmithSandboxRetryableConnectionError";
59
+ }
60
+ }
49
61
  // =============================================================================
50
62
  // Resource Errors (type-based, with resourceType property)
51
63
  // =============================================================================
@@ -354,12 +366,10 @@ export class LangSmithStreamEndedBeforeStartedError extends LangSmithSandboxOper
354
366
  /**
355
367
  * Thrown when the socket fails or times out before the WebSocket handshake.
356
368
  *
357
- * Distinct from its parent because it is safely retryable: the execute frame
358
- * was never sent, so re-issuing the same command_id cannot double-run a
359
- * command. run() retries this with backoff; a plain connection error (a
360
- * rejected handshake) is permanent and propagates immediately.
369
+ * The execute frame was never sent, so re-issuing the same command ID cannot
370
+ * double-run a command.
361
371
  */
362
- export class LangSmithSandboxConnectTimeoutError extends LangSmithSandboxConnectionError {
372
+ export class LangSmithSandboxConnectTimeoutError extends LangSmithSandboxRetryableConnectionError {
363
373
  constructor(message) {
364
374
  super(message);
365
375
  this.name = "LangSmithSandboxConnectTimeoutError";
@@ -29,7 +29,7 @@
29
29
  * @packageDocumentation
30
30
  */
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.LangSmithDataplaneNotConfiguredError = exports.LangSmithCommandTimeoutError = exports.LangSmithSandboxOperationError = exports.LangSmithSandboxNotReadyError = exports.LangSmithSandboxCreationError = exports.LangSmithResourceCreationError = exports.LangSmithQuotaExceededError = exports.LangSmithValidationError = exports.LangSmithResourceNameConflictError = exports.LangSmithResourceAlreadyExistsError = exports.LangSmithResourceInUseError = exports.LangSmithResourceTimeoutError = exports.LangSmithResourceNotFoundError = exports.LangSmithSandboxServerReloadError = exports.LangSmithSandboxConnectTimeoutError = exports.LangSmithSandboxConnectionError = exports.LangSmithSandboxAuthenticationError = exports.LangSmithSandboxAPIError = exports.LangSmithSandboxError = exports.s3Mount = exports.mountConfig = exports.gitMount = exports.gcsMount = exports.workspaceSecret = exports.proxyConfig = exports.opaqueSecret = exports.gcpAuth = exports.awsAuth = exports.CommandHandle = exports.Sandbox = exports.SandboxClient = void 0;
32
+ exports.LangSmithDataplaneNotConfiguredError = exports.LangSmithCommandTimeoutError = exports.LangSmithSandboxOperationError = exports.LangSmithSandboxNotReadyError = exports.LangSmithSandboxCreationError = exports.LangSmithResourceCreationError = exports.LangSmithQuotaExceededError = exports.LangSmithValidationError = exports.LangSmithResourceNameConflictError = exports.LangSmithResourceAlreadyExistsError = exports.LangSmithResourceInUseError = exports.LangSmithResourceTimeoutError = exports.LangSmithResourceNotFoundError = exports.LangSmithSandboxServerReloadError = exports.LangSmithSandboxConnectTimeoutError = exports.LangSmithSandboxRetryableConnectionError = exports.LangSmithSandboxConnectionError = exports.LangSmithSandboxAuthenticationError = exports.LangSmithSandboxAPIError = exports.LangSmithSandboxError = exports.s3Mount = exports.mountConfig = exports.gitMount = exports.gcsMount = exports.contextHubMount = exports.workspaceSecret = exports.proxyConfig = exports.opaqueSecret = exports.gcpAuth = exports.awsAuth = exports.CommandHandle = exports.Sandbox = exports.SandboxClient = void 0;
33
33
  // Main classes
34
34
  var client_js_1 = require("./client.cjs");
35
35
  Object.defineProperty(exports, "SandboxClient", { enumerable: true, get: function () { return client_js_1.SandboxClient; } });
@@ -44,6 +44,7 @@ Object.defineProperty(exports, "opaqueSecret", { enumerable: true, get: function
44
44
  Object.defineProperty(exports, "proxyConfig", { enumerable: true, get: function () { return proxy_config_js_1.proxyConfig; } });
45
45
  Object.defineProperty(exports, "workspaceSecret", { enumerable: true, get: function () { return proxy_config_js_1.workspaceSecret; } });
46
46
  var mounts_js_1 = require("./mounts.cjs");
47
+ Object.defineProperty(exports, "contextHubMount", { enumerable: true, get: function () { return mounts_js_1.contextHubMount; } });
47
48
  Object.defineProperty(exports, "gcsMount", { enumerable: true, get: function () { return mounts_js_1.gcsMount; } });
48
49
  Object.defineProperty(exports, "gitMount", { enumerable: true, get: function () { return mounts_js_1.gitMount; } });
49
50
  Object.defineProperty(exports, "mountConfig", { enumerable: true, get: function () { return mounts_js_1.mountConfig; } });
@@ -55,6 +56,7 @@ Object.defineProperty(exports, "LangSmithSandboxError", { enumerable: true, get:
55
56
  Object.defineProperty(exports, "LangSmithSandboxAPIError", { enumerable: true, get: function () { return errors_js_1.LangSmithSandboxAPIError; } });
56
57
  Object.defineProperty(exports, "LangSmithSandboxAuthenticationError", { enumerable: true, get: function () { return errors_js_1.LangSmithSandboxAuthenticationError; } });
57
58
  Object.defineProperty(exports, "LangSmithSandboxConnectionError", { enumerable: true, get: function () { return errors_js_1.LangSmithSandboxConnectionError; } });
59
+ Object.defineProperty(exports, "LangSmithSandboxRetryableConnectionError", { enumerable: true, get: function () { return errors_js_1.LangSmithSandboxRetryableConnectionError; } });
58
60
  Object.defineProperty(exports, "LangSmithSandboxConnectTimeoutError", { enumerable: true, get: function () { return errors_js_1.LangSmithSandboxConnectTimeoutError; } });
59
61
  Object.defineProperty(exports, "LangSmithSandboxServerReloadError", { enumerable: true, get: function () { return errors_js_1.LangSmithSandboxServerReloadError; } });
60
62
  // Resource errors (type-based with resourceType attribute)
@@ -31,6 +31,6 @@ export { SandboxClient } from "./client.js";
31
31
  export { Sandbox } from "./sandbox.js";
32
32
  export { CommandHandle } from "./command_handle.js";
33
33
  export { awsAuth, gcpAuth, opaqueSecret, proxyConfig, workspaceSecret, } from "./proxy_config.js";
34
- export { gcsMount, gitMount, mountConfig, s3Mount } from "./mounts.js";
35
- export type { ExecutionResult, OutputChunk, WsMessage, WsRunOptions, ResourceStatus, Snapshot, SandboxData, SandboxClientConfig, RunOptions, CreateSandboxOptions, SandboxAccessControl, SandboxAwsAuthRule, SandboxAwsMountAuthConfig, SandboxGcpAuthRule, SandboxGcpMountAuthConfig, SandboxMountAuth, SandboxMountAuthConfig, SandboxMountConfig, SandboxProxyConfig, SandboxProxyRule, SandboxProxySecret, SandboxMount, MountCacheConfig, GCSMountConfig, GCSMountSpec, GitMountConfig, GitMountRefSpec, GitMountSpec, S3MountConfig, S3MountSpec, CreateSnapshotOptions, CreateDockerfileSnapshotOptions, CaptureSnapshotOptions, ListSnapshotsOptions, WaitForSnapshotOptions, StartSandboxOptions, UpdateSandboxOptions, WaitForSandboxOptions, } from "./types.js";
36
- export { LangSmithSandboxError, LangSmithSandboxAPIError, LangSmithSandboxAuthenticationError, LangSmithSandboxConnectionError, LangSmithSandboxConnectTimeoutError, LangSmithSandboxServerReloadError, LangSmithResourceNotFoundError, LangSmithResourceTimeoutError, LangSmithResourceInUseError, LangSmithResourceAlreadyExistsError, LangSmithResourceNameConflictError, LangSmithValidationError, LangSmithQuotaExceededError, LangSmithResourceCreationError, LangSmithSandboxCreationError, LangSmithSandboxNotReadyError, LangSmithSandboxOperationError, LangSmithCommandTimeoutError, LangSmithDataplaneNotConfiguredError, } from "./errors.js";
34
+ export { contextHubMount, gcsMount, gitMount, mountConfig, s3Mount, } from "./mounts.js";
35
+ export type { ExecutionResult, OutputChunk, WsMessage, WsRunOptions, ResourceStatus, Snapshot, SandboxData, SandboxClientConfig, RunOptions, CreateSandboxOptions, SandboxAccessControl, SandboxAwsAuthRule, SandboxAwsMountAuthConfig, SandboxGcpAuthRule, SandboxGcpMountAuthConfig, SandboxMountAuth, SandboxMountAuthConfig, SandboxMountConfig, SandboxProxyConfig, SandboxProxyRule, SandboxProxySecret, SandboxMount, MountCacheConfig, ContextHubMountConfig, ContextHubMountSpec, GCSMountConfig, GCSMountSpec, GitMountConfig, GitMountRefSpec, GitMountSpec, S3MountConfig, S3MountSpec, CreateSnapshotOptions, CreateDockerfileSnapshotOptions, CaptureSnapshotOptions, DownloadContentDisposition, DownloadURL, GenerateDownloadURLOptions, ListSnapshotsOptions, WaitForSnapshotOptions, StartSandboxOptions, UpdateSandboxOptions, WaitForSandboxOptions, } from "./types.js";
36
+ export { LangSmithSandboxError, LangSmithSandboxAPIError, LangSmithSandboxAuthenticationError, LangSmithSandboxConnectionError, LangSmithSandboxRetryableConnectionError, LangSmithSandboxConnectTimeoutError, LangSmithSandboxServerReloadError, LangSmithResourceNotFoundError, LangSmithResourceTimeoutError, LangSmithResourceInUseError, LangSmithResourceAlreadyExistsError, LangSmithResourceNameConflictError, LangSmithValidationError, LangSmithQuotaExceededError, LangSmithResourceCreationError, LangSmithSandboxCreationError, LangSmithSandboxNotReadyError, LangSmithSandboxOperationError, LangSmithCommandTimeoutError, LangSmithDataplaneNotConfiguredError, } from "./errors.js";
@@ -32,11 +32,11 @@ export { SandboxClient } from "./client.js";
32
32
  export { Sandbox } from "./sandbox.js";
33
33
  export { CommandHandle } from "./command_handle.js";
34
34
  export { awsAuth, gcpAuth, opaqueSecret, proxyConfig, workspaceSecret, } from "./proxy_config.js";
35
- export { gcsMount, gitMount, mountConfig, s3Mount } from "./mounts.js";
35
+ export { contextHubMount, gcsMount, gitMount, mountConfig, s3Mount, } from "./mounts.js";
36
36
  // Errors
37
37
  export {
38
38
  // Base and connection errors
39
- LangSmithSandboxError, LangSmithSandboxAPIError, LangSmithSandboxAuthenticationError, LangSmithSandboxConnectionError, LangSmithSandboxConnectTimeoutError, LangSmithSandboxServerReloadError,
39
+ LangSmithSandboxError, LangSmithSandboxAPIError, LangSmithSandboxAuthenticationError, LangSmithSandboxConnectionError, LangSmithSandboxRetryableConnectionError, LangSmithSandboxConnectTimeoutError, LangSmithSandboxServerReloadError,
40
40
  // Resource errors (type-based with resourceType attribute)
41
41
  LangSmithResourceNotFoundError, LangSmithResourceTimeoutError, LangSmithResourceInUseError, LangSmithResourceAlreadyExistsError, LangSmithResourceNameConflictError,
42
42
  // Validation and quota errors
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.s3Mount = s3Mount;
4
4
  exports.gitMount = gitMount;
5
5
  exports.gcsMount = gcsMount;
6
+ exports.contextHubMount = contextHubMount;
6
7
  exports.mountConfig = mountConfig;
7
8
  exports.validateMountConfigProxyConfig = validateMountConfigProxyConfig;
8
9
  function requireNonEmptyString(value, field) {
@@ -132,6 +133,25 @@ function gcsMount({ id, mountPath, bucket, prefix, readOnly, cache, }) {
132
133
  }
133
134
  return mount;
134
135
  }
136
+ /**
137
+ * Build a read-only Context Hub mount. The sync is one-way: files written
138
+ * under the mount path inside the sandbox are never pushed back to the repo,
139
+ * and the next sync overwrites them.
140
+ */
141
+ function contextHubMount({ id, mountPath, repo, initialPullOnly, }) {
142
+ const mount = {
143
+ id: requireNonEmptyString(id, "id"),
144
+ type: "contexthub",
145
+ mount_path: requireNonEmptyString(mountPath, "mountPath"),
146
+ contexthub: {
147
+ repo: requireNonEmptyString(repo, "repo"),
148
+ },
149
+ };
150
+ if (initialPullOnly !== undefined) {
151
+ mount.contexthub.initial_pull_only = initialPullOnly;
152
+ }
153
+ return mount;
154
+ }
135
155
  function normalizeMounts(mounts) {
136
156
  if (!Array.isArray(mounts) || mounts.length === 0) {
137
157
  throw new Error("mounts must be a non-empty array of mount objects");
@@ -140,8 +160,11 @@ function normalizeMounts(mounts) {
140
160
  if (mount === null || typeof mount !== "object" || Array.isArray(mount)) {
141
161
  throw new Error("mounts must be a non-empty array of mount objects");
142
162
  }
143
- if (mount.type !== "s3" && mount.type !== "gcs" && mount.type !== "git") {
144
- throw new Error("mountConfig only supports s3, gcs, and git mounts");
163
+ if (mount.type !== "s3" &&
164
+ mount.type !== "gcs" &&
165
+ mount.type !== "git" &&
166
+ mount.type !== "contexthub") {
167
+ throw new Error("mountConfig only supports s3, gcs, git, and contexthub mounts");
145
168
  }
146
169
  rejectProviderCredentialsInMount(mount);
147
170
  return mount;
@@ -1,4 +1,4 @@
1
- import type { GCSMountSpec, GitMountRefSpec, GitMountSpec, MountCacheConfig, S3MountSpec, SandboxMount, SandboxMountAuth, SandboxMountConfig, SandboxProxyConfig } from "./types.js";
1
+ import type { ContextHubMountSpec, GCSMountSpec, GitMountRefSpec, GitMountSpec, MountCacheConfig, S3MountSpec, SandboxMount, SandboxMountAuth, SandboxMountConfig, SandboxProxyConfig } from "./types.js";
2
2
  export declare function s3Mount({ id, mountPath, bucket, region, prefix, endpointUrl, pathStyle, readOnly, cache, }: {
3
3
  id: string;
4
4
  mountPath: string;
@@ -25,6 +25,17 @@ export declare function gcsMount({ id, mountPath, bucket, prefix, readOnly, cach
25
25
  readOnly?: boolean;
26
26
  cache?: MountCacheConfig;
27
27
  }): GCSMountSpec;
28
+ /**
29
+ * Build a read-only Context Hub mount. The sync is one-way: files written
30
+ * under the mount path inside the sandbox are never pushed back to the repo,
31
+ * and the next sync overwrites them.
32
+ */
33
+ export declare function contextHubMount({ id, mountPath, repo, initialPullOnly, }: {
34
+ id: string;
35
+ mountPath: string;
36
+ repo: string;
37
+ initialPullOnly?: boolean;
38
+ }): ContextHubMountSpec;
28
39
  export declare function mountConfig({ auth, mounts, }: {
29
40
  auth?: SandboxMountAuth[];
30
41
  mounts: SandboxMount[];
@@ -125,6 +125,25 @@ export function gcsMount({ id, mountPath, bucket, prefix, readOnly, cache, }) {
125
125
  }
126
126
  return mount;
127
127
  }
128
+ /**
129
+ * Build a read-only Context Hub mount. The sync is one-way: files written
130
+ * under the mount path inside the sandbox are never pushed back to the repo,
131
+ * and the next sync overwrites them.
132
+ */
133
+ export function contextHubMount({ id, mountPath, repo, initialPullOnly, }) {
134
+ const mount = {
135
+ id: requireNonEmptyString(id, "id"),
136
+ type: "contexthub",
137
+ mount_path: requireNonEmptyString(mountPath, "mountPath"),
138
+ contexthub: {
139
+ repo: requireNonEmptyString(repo, "repo"),
140
+ },
141
+ };
142
+ if (initialPullOnly !== undefined) {
143
+ mount.contexthub.initial_pull_only = initialPullOnly;
144
+ }
145
+ return mount;
146
+ }
128
147
  function normalizeMounts(mounts) {
129
148
  if (!Array.isArray(mounts) || mounts.length === 0) {
130
149
  throw new Error("mounts must be a non-empty array of mount objects");
@@ -133,8 +152,11 @@ function normalizeMounts(mounts) {
133
152
  if (mount === null || typeof mount !== "object" || Array.isArray(mount)) {
134
153
  throw new Error("mounts must be a non-empty array of mount objects");
135
154
  }
136
- if (mount.type !== "s3" && mount.type !== "gcs" && mount.type !== "git") {
137
- throw new Error("mountConfig only supports s3, gcs, and git mounts");
155
+ if (mount.type !== "s3" &&
156
+ mount.type !== "gcs" &&
157
+ mount.type !== "git" &&
158
+ mount.type !== "contexthub") {
159
+ throw new Error("mountConfig only supports s3, gcs, git, and contexthub mounts");
138
160
  }
139
161
  rejectProviderCredentialsInMount(mount);
140
162
  return mount;
@@ -17,6 +17,22 @@ function requireNonEmptyStringArray(values, field) {
17
17
  }
18
18
  return values.map((value) => requireNonEmptyString(value, field));
19
19
  }
20
+ function requireEnvVars(envVars) {
21
+ if (envVars === null ||
22
+ typeof envVars !== "object" ||
23
+ Array.isArray(envVars)) {
24
+ throw new Error("envVars must be a non-empty object of names to values");
25
+ }
26
+ const entries = Object.entries(envVars);
27
+ if (entries.length === 0) {
28
+ throw new Error("envVars must be a non-empty object of names to values");
29
+ }
30
+ return Object.fromEntries(entries.map(([name, value]) => {
31
+ // Validated on the trimmed form, stored verbatim: whitespace can be significant.
32
+ requireNonEmptyString(value, `envVars[${name}]`);
33
+ return [requireNonEmptyString(name, "envVars name"), value];
34
+ }));
35
+ }
20
36
  function requireProxyRules(rules) {
21
37
  if (rules === undefined) {
22
38
  return [];
@@ -79,8 +95,8 @@ function proxyConfig({ rules, noProxy, accessControl, } = {}) {
79
95
  return config;
80
96
  }
81
97
  /** Build a sandbox proxy rule that signs AWS HTTPS requests with SigV4. */
82
- function awsAuth({ accessKeyId, secretAccessKey, name = "aws", enabled = true, }) {
83
- return {
98
+ function awsAuth({ accessKeyId, secretAccessKey, name = "aws", enabled = true, envVars, }) {
99
+ const rule = {
84
100
  name: requireNonEmptyString(name, "name"),
85
101
  type: "aws",
86
102
  enabled,
@@ -89,19 +105,27 @@ function awsAuth({ accessKeyId, secretAccessKey, name = "aws", enabled = true, }
89
105
  secret_access_key: secretAccessKey,
90
106
  },
91
107
  };
108
+ if (envVars !== undefined) {
109
+ rule.env_vars = requireEnvVars(envVars);
110
+ }
111
+ return rule;
92
112
  }
93
113
  /** Build a sandbox proxy rule that injects GCP OAuth bearer auth. */
94
- function gcpAuth({ serviceAccountJson, scopes, name = "gcp", enabled = true, }) {
114
+ function gcpAuth({ serviceAccountJson, scopes, name = "gcp", enabled = true, envVars, }) {
95
115
  const gcp = {
96
116
  service_account_json: serviceAccountJson,
97
117
  };
98
118
  if (scopes !== undefined) {
99
119
  gcp.scopes = requireNonEmptyStringArray(scopes, "scopes");
100
120
  }
101
- return {
121
+ const rule = {
102
122
  name: requireNonEmptyString(name, "name"),
103
123
  type: "gcp",
104
124
  enabled,
105
125
  gcp,
106
126
  };
127
+ if (envVars !== undefined) {
128
+ rule.env_vars = requireEnvVars(envVars);
129
+ }
130
+ return rule;
107
131
  }
@@ -10,16 +10,18 @@ export declare function proxyConfig({ rules, noProxy, accessControl, }?: {
10
10
  accessControl?: SandboxAccessControl;
11
11
  }): SandboxProxyConfig;
12
12
  /** Build a sandbox proxy rule that signs AWS HTTPS requests with SigV4. */
13
- export declare function awsAuth({ accessKeyId, secretAccessKey, name, enabled, }: {
13
+ export declare function awsAuth({ accessKeyId, secretAccessKey, name, enabled, envVars, }: {
14
14
  accessKeyId: SandboxProxySecret;
15
15
  secretAccessKey: SandboxProxySecret;
16
16
  name?: string;
17
17
  enabled?: boolean;
18
+ envVars?: Record<string, string>;
18
19
  }): SandboxAwsAuthRule;
19
20
  /** Build a sandbox proxy rule that injects GCP OAuth bearer auth. */
20
- export declare function gcpAuth({ serviceAccountJson, scopes, name, enabled, }: {
21
+ export declare function gcpAuth({ serviceAccountJson, scopes, name, enabled, envVars, }: {
21
22
  serviceAccountJson: SandboxProxySecret;
22
23
  scopes?: string[];
23
24
  name?: string;
24
25
  enabled?: boolean;
26
+ envVars?: Record<string, string>;
25
27
  }): SandboxGcpAuthRule;
@@ -10,6 +10,22 @@ function requireNonEmptyStringArray(values, field) {
10
10
  }
11
11
  return values.map((value) => requireNonEmptyString(value, field));
12
12
  }
13
+ function requireEnvVars(envVars) {
14
+ if (envVars === null ||
15
+ typeof envVars !== "object" ||
16
+ Array.isArray(envVars)) {
17
+ throw new Error("envVars must be a non-empty object of names to values");
18
+ }
19
+ const entries = Object.entries(envVars);
20
+ if (entries.length === 0) {
21
+ throw new Error("envVars must be a non-empty object of names to values");
22
+ }
23
+ return Object.fromEntries(entries.map(([name, value]) => {
24
+ // Validated on the trimmed form, stored verbatim: whitespace can be significant.
25
+ requireNonEmptyString(value, `envVars[${name}]`);
26
+ return [requireNonEmptyString(name, "envVars name"), value];
27
+ }));
28
+ }
13
29
  function requireProxyRules(rules) {
14
30
  if (rules === undefined) {
15
31
  return [];
@@ -72,8 +88,8 @@ export function proxyConfig({ rules, noProxy, accessControl, } = {}) {
72
88
  return config;
73
89
  }
74
90
  /** Build a sandbox proxy rule that signs AWS HTTPS requests with SigV4. */
75
- export function awsAuth({ accessKeyId, secretAccessKey, name = "aws", enabled = true, }) {
76
- return {
91
+ export function awsAuth({ accessKeyId, secretAccessKey, name = "aws", enabled = true, envVars, }) {
92
+ const rule = {
77
93
  name: requireNonEmptyString(name, "name"),
78
94
  type: "aws",
79
95
  enabled,
@@ -82,19 +98,27 @@ export function awsAuth({ accessKeyId, secretAccessKey, name = "aws", enabled =
82
98
  secret_access_key: secretAccessKey,
83
99
  },
84
100
  };
101
+ if (envVars !== undefined) {
102
+ rule.env_vars = requireEnvVars(envVars);
103
+ }
104
+ return rule;
85
105
  }
86
106
  /** Build a sandbox proxy rule that injects GCP OAuth bearer auth. */
87
- export function gcpAuth({ serviceAccountJson, scopes, name = "gcp", enabled = true, }) {
107
+ export function gcpAuth({ serviceAccountJson, scopes, name = "gcp", enabled = true, envVars, }) {
88
108
  const gcp = {
89
109
  service_account_json: serviceAccountJson,
90
110
  };
91
111
  if (scopes !== undefined) {
92
112
  gcp.scopes = requireNonEmptyStringArray(scopes, "scopes");
93
113
  }
94
- return {
114
+ const rule = {
95
115
  name: requireNonEmptyString(name, "name"),
96
116
  type: "gcp",
97
117
  enabled,
98
118
  gcp,
99
119
  };
120
+ if (envVars !== undefined) {
121
+ rule.env_vars = requireEnvVars(envVars);
122
+ }
123
+ return rule;
100
124
  }
@@ -264,7 +264,7 @@ class Sandbox {
264
264
  // Idempotent re-issue (same command_id): neither an early close nor a
265
265
  // failed connect can have started a second command.
266
266
  if (!(e instanceof errors_js_1.LangSmithStreamEndedBeforeStartedError) &&
267
- !(e instanceof errors_js_1.LangSmithSandboxConnectTimeoutError)) {
267
+ !(e instanceof errors_js_1.LangSmithSandboxRetryableConnectionError)) {
268
268
  throw e;
269
269
  }
270
270
  attempt++;
@@ -410,6 +410,32 @@ class Sandbox {
410
410
  const buffer = await response.arrayBuffer();
411
411
  return new Uint8Array(buffer);
412
412
  }
413
+ /**
414
+ * Create a link that downloads one file from this sandbox.
415
+ *
416
+ * The link carries its own token, so anyone holding the URL can fetch that
417
+ * one file without a LangSmith credential. Fetching wakes a stopped sandbox.
418
+ *
419
+ * Do not modify the file after minting a link for it. The link is pinned to
420
+ * a path, not to a snapshot of the contents, so a later write to that path
421
+ * may or may not be reflected in what the link serves. Write a new file and
422
+ * mint a new link when the contents change.
423
+ *
424
+ * @param path - File path inside the sandbox.
425
+ * @param options - Expiry and response header overrides.
426
+ * @returns The link and its expiry, if any.
427
+ *
428
+ * @example
429
+ * ```typescript
430
+ * const link = await sandbox.generateDownloadURL("/tmp/report.pdf", {
431
+ * expiresInSeconds: 3600,
432
+ * });
433
+ * console.log(link.download_url);
434
+ * ```
435
+ */
436
+ async generateDownloadURL(path, options = {}) {
437
+ return this._client.generateDownloadURL(this.name, path, options);
438
+ }
413
439
  /**
414
440
  * Delete this sandbox.
415
441
  *