langsmith 0.8.6 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -35,6 +35,6 @@ Object.defineProperty(exports, "UnprocessableEntityError", { enumerable: true, g
35
35
  Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return error_js_1.RateLimitError; } });
36
36
  Object.defineProperty(exports, "InternalServerError", { enumerable: true, get: function () { return error_js_1.InternalServerError; } });
37
37
  // Update using pnpm bump-version
38
- exports.__version__ = "0.8.6";
38
+ exports.__version__ = "0.8.7";
39
39
  // Metadata key to hide a traced run from LangSmith's Messages View.
40
40
  exports.LS_MESSAGE_VIEW_EXCLUDE = "ls_message_view_exclude";
package/dist/index.d.ts CHANGED
@@ -7,5 +7,5 @@ export { computeRunIdForSecondaryReplica, uuid7, uuid7FromTime, } from "./uuid.j
7
7
  export { isTracingEnabled } from "./utils/guard.js";
8
8
  export { Cache, PromptCache, type CacheConfig, type CacheMetrics, configureGlobalPromptCache, promptCacheSingleton, } from "./utils/prompt_cache/index.js";
9
9
  export { LangsmithError, APIError, APIUserAbortError, APIConnectionError, APIConnectionTimeoutError, BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, UnprocessableEntityError, RateLimitError, InternalServerError, } from "./_openapi_client/core/error.js";
10
- export declare const __version__ = "0.8.6";
10
+ export declare const __version__ = "0.8.7";
11
11
  export declare const LS_MESSAGE_VIEW_EXCLUDE: "ls_message_view_exclude";
package/dist/index.js CHANGED
@@ -7,6 +7,6 @@ export { isTracingEnabled } from "./utils/guard.js";
7
7
  export { Cache, PromptCache, configureGlobalPromptCache, promptCacheSingleton, } from "./utils/prompt_cache/index.js";
8
8
  export { LangsmithError, APIError, APIUserAbortError, APIConnectionError, APIConnectionTimeoutError, BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, UnprocessableEntityError, RateLimitError, InternalServerError, } from "./_openapi_client/core/error.js";
9
9
  // Update using pnpm bump-version
10
- export const __version__ = "0.8.6";
10
+ export const __version__ = "0.8.7";
11
11
  // Metadata key to hide a traced run from LangSmith's Messages View.
12
12
  export const LS_MESSAGE_VIEW_EXCLUDE = "ls_message_view_exclude";
@@ -199,8 +199,9 @@ class Sandbox {
199
199
  // wait=true with callbacks: drain stream and return result
200
200
  return handle.result;
201
201
  }
202
- // wait=true, no callbacks: try WS, fall back to HTTP
203
- try {
202
+ // wait=true, no callbacks: use WebSocket when the 'ws' package is
203
+ // available, otherwise the blocking HTTP endpoint. WS errors propagate.
204
+ if (await this._wsAvailable()) {
204
205
  const handle = await this._runWs(command, {
205
206
  ...restOptions,
206
207
  idleTimeout,
@@ -210,17 +211,14 @@ class Sandbox {
210
211
  });
211
212
  return await handle.result;
212
213
  }
213
- catch (e) {
214
- // Fall back to HTTP on connection errors or missing ws package
215
- const name = e != null && typeof e === "object" ? e.name : "";
216
- const message = e != null && typeof e === "object" ? (e.message ?? "") : "";
217
- if (name === "LangSmithSandboxConnectionError" ||
218
- name === "LangSmithSandboxServerReloadError" ||
219
- message.includes("'ws' package")) {
220
- return this._runHttp(command, restOptions);
221
- }
222
- throw e;
223
- }
214
+ return this._runHttp(command, restOptions);
215
+ }
216
+ /**
217
+ * Whether the optional `ws` package is importable (resolved once).
218
+ * @internal
219
+ */
220
+ _wsAvailable() {
221
+ return (0, ws_execute_js_1.isWsAvailable)();
224
222
  }
225
223
  /**
226
224
  * Execute a command via WebSocket streaming.
@@ -78,7 +78,8 @@ export declare class Sandbox {
78
78
  * Execute a command in the sandbox.
79
79
  *
80
80
  * When `wait` is true (default) and no streaming callbacks are provided,
81
- * tries WebSocket first and falls back to HTTP POST.
81
+ * uses WebSocket, falling back to HTTP POST only when the optional `ws`
82
+ * package isn't installed.
82
83
  *
83
84
  * When `wait` is false or streaming callbacks are provided, uses WebSocket
84
85
  * (required). Returns a CommandHandle for streaming output.
@@ -5,7 +5,7 @@ import { uuid7 } from "../uuid.js";
5
5
  import { LangSmithDataplaneNotConfiguredError, LangSmithStreamEndedBeforeStartedError, } from "./errors.js";
6
6
  import { handleSandboxHttpError } from "./helpers.js";
7
7
  import { CommandHandle } from "./command_handle.js";
8
- import { reconnectWsStream, runWsStream } from "./ws_execute.js";
8
+ import { isWsAvailable, reconnectWsStream, runWsStream } from "./ws_execute.js";
9
9
  /**
10
10
  * Represents an active sandbox for running commands and file operations.
11
11
  *
@@ -196,8 +196,9 @@ export class Sandbox {
196
196
  // wait=true with callbacks: drain stream and return result
197
197
  return handle.result;
198
198
  }
199
- // wait=true, no callbacks: try WS, fall back to HTTP
200
- try {
199
+ // wait=true, no callbacks: use WebSocket when the 'ws' package is
200
+ // available, otherwise the blocking HTTP endpoint. WS errors propagate.
201
+ if (await this._wsAvailable()) {
201
202
  const handle = await this._runWs(command, {
202
203
  ...restOptions,
203
204
  idleTimeout,
@@ -207,17 +208,14 @@ export class Sandbox {
207
208
  });
208
209
  return await handle.result;
209
210
  }
210
- catch (e) {
211
- // Fall back to HTTP on connection errors or missing ws package
212
- const name = e != null && typeof e === "object" ? e.name : "";
213
- const message = e != null && typeof e === "object" ? (e.message ?? "") : "";
214
- if (name === "LangSmithSandboxConnectionError" ||
215
- name === "LangSmithSandboxServerReloadError" ||
216
- message.includes("'ws' package")) {
217
- return this._runHttp(command, restOptions);
218
- }
219
- throw e;
220
- }
211
+ return this._runHttp(command, restOptions);
212
+ }
213
+ /**
214
+ * Whether the optional `ws` package is importable (resolved once).
215
+ * @internal
216
+ */
217
+ _wsAvailable() {
218
+ return isWsAvailable();
221
219
  }
222
220
  /**
223
221
  * Execute a command via WebSocket streaming.
@@ -7,21 +7,28 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.WSStreamControl = void 0;
10
+ exports.isWsAvailable = isWsAvailable;
10
11
  exports.buildWsUrl = buildWsUrl;
11
12
  exports.buildAuthHeaders = buildAuthHeaders;
12
13
  exports.raiseForWsError = raiseForWsError;
13
14
  exports.runWsStream = runWsStream;
14
15
  exports.reconnectWsStream = reconnectWsStream;
15
16
  const errors_js_1 = require("./errors.cjs");
17
+ // Load the optional 'ws' package once, at module load, instead of importing on
18
+ // every call. Resolves to the WebSocket constructor, or null if 'ws' isn't
19
+ // installed. run() reads isWsAvailable() to choose WS vs the HTTP fallback.
20
+ const wsWebSocketPromise = import("ws").then((ws) => ws.default || ws.WebSocket || ws, () => null);
21
+ /** Whether the optional `ws` package could be loaded (resolved once). */
22
+ async function isWsAvailable() {
23
+ return (await wsWebSocketPromise) !== null;
24
+ }
16
25
  async function ensureWs() {
17
- try {
18
- const ws = await import("ws");
19
- return { WebSocket: ws.default || ws.WebSocket || ws };
20
- }
21
- catch {
26
+ const WebSocket = await wsWebSocketPromise;
27
+ if (!WebSocket) {
22
28
  throw new Error("WebSocket-based execution requires the 'ws' package. " +
23
29
  "Install it with: npm install ws");
24
30
  }
31
+ return { WebSocket };
25
32
  }
26
33
  // =============================================================================
27
34
  // URL and Auth Helpers
@@ -6,6 +6,8 @@
6
6
  */
7
7
  import type { WsMessage, WsRunOptions } from "./types.js";
8
8
  type WsWebSocket = any;
9
+ /** Whether the optional `ws` package could be loaded (resolved once). */
10
+ export declare function isWsAvailable(): Promise<boolean>;
9
11
  /**
10
12
  * Convert a dataplane HTTP URL to a WebSocket URL for /execute/ws.
11
13
  */
@@ -5,15 +5,21 @@
5
5
  * Install with: npm install ws
6
6
  */
7
7
  import { LangSmithCommandTimeoutError, LangSmithSandboxConnectionError, LangSmithSandboxOperationError, LangSmithSandboxServerReloadError, } from "./errors.js";
8
+ // Load the optional 'ws' package once, at module load, instead of importing on
9
+ // every call. Resolves to the WebSocket constructor, or null if 'ws' isn't
10
+ // installed. run() reads isWsAvailable() to choose WS vs the HTTP fallback.
11
+ const wsWebSocketPromise = import("ws").then((ws) => ws.default || ws.WebSocket || ws, () => null);
12
+ /** Whether the optional `ws` package could be loaded (resolved once). */
13
+ export async function isWsAvailable() {
14
+ return (await wsWebSocketPromise) !== null;
15
+ }
8
16
  async function ensureWs() {
9
- try {
10
- const ws = await import("ws");
11
- return { WebSocket: ws.default || ws.WebSocket || ws };
12
- }
13
- catch {
17
+ const WebSocket = await wsWebSocketPromise;
18
+ if (!WebSocket) {
14
19
  throw new Error("WebSocket-based execution requires the 'ws' package. " +
15
20
  "Install it with: npm install ws");
16
21
  }
22
+ return { WebSocket };
17
23
  }
18
24
  // =============================================================================
19
25
  // URL and Auth Helpers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langsmith",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
4
4
  "description": "Client library to connect to the LangSmith Observability and Evaluation Platform.",
5
5
  "packageManager": "pnpm@10.33.0",
6
6
  "files": [