langsmith 0.5.19 → 0.6.0
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/client.cjs +460 -22
- package/dist/client.d.ts +165 -1
- package/dist/client.js +464 -26
- package/dist/evaluation/_runner.cjs +4 -7
- package/dist/evaluation/_runner.js +2 -5
- package/dist/evaluation/evaluate_comparative.cjs +10 -10
- package/dist/evaluation/evaluate_comparative.js +1 -1
- package/dist/evaluation/evaluator.cjs +2 -2
- package/dist/evaluation/evaluator.js +1 -1
- package/dist/experimental/anthropic/context.cjs +419 -49
- package/dist/experimental/anthropic/context.js +420 -50
- package/dist/experimental/anthropic/index.cjs +78 -10
- package/dist/experimental/anthropic/index.js +80 -12
- package/dist/experimental/anthropic/messages.cjs +53 -0
- package/dist/experimental/anthropic/messages.d.ts +6 -0
- package/dist/experimental/anthropic/messages.js +52 -0
- package/dist/experimental/anthropic/transcripts.cjs +144 -0
- package/dist/experimental/anthropic/transcripts.d.ts +22 -0
- package/dist/experimental/anthropic/transcripts.js +141 -0
- package/dist/experimental/anthropic/types.d.ts +1 -0
- package/dist/experimental/anthropic/usage.cjs +19 -20
- package/dist/experimental/anthropic/usage.d.ts +2 -1
- package/dist/experimental/anthropic/usage.js +18 -20
- package/dist/experimental/opencode/index.cjs +36 -0
- package/dist/experimental/opencode/index.d.ts +3 -0
- package/dist/experimental/opencode/index.js +32 -0
- package/dist/experimental/opencode/tracer.cjs +389 -0
- package/dist/experimental/opencode/tracer.d.ts +30 -0
- package/dist/experimental/opencode/tracer.js +385 -0
- package/dist/experimental/otel/setup.cjs +1 -1
- package/dist/experimental/otel/setup.js +1 -1
- package/dist/experimental/sandbox/client.cjs +308 -409
- package/dist/experimental/sandbox/client.d.ts +136 -157
- package/dist/experimental/sandbox/client.js +310 -411
- package/dist/experimental/sandbox/errors.cjs +1 -2
- package/dist/experimental/sandbox/errors.d.ts +1 -2
- package/dist/experimental/sandbox/errors.js +1 -2
- package/dist/experimental/sandbox/helpers.cjs +8 -98
- package/dist/experimental/sandbox/helpers.d.ts +0 -29
- package/dist/experimental/sandbox/helpers.js +9 -95
- package/dist/experimental/sandbox/index.cjs +6 -1
- package/dist/experimental/sandbox/index.d.ts +7 -2
- package/dist/experimental/sandbox/index.js +6 -1
- package/dist/experimental/sandbox/sandbox.cjs +71 -13
- package/dist/experimental/sandbox/sandbox.d.ts +39 -9
- package/dist/experimental/sandbox/sandbox.js +71 -13
- package/dist/experimental/sandbox/types.d.ts +147 -137
- package/dist/experimental/vercel/index.cjs +1 -1
- package/dist/experimental/vercel/index.js +1 -1
- package/dist/experimental/vercel/middleware.cjs +2 -1
- package/dist/experimental/vercel/middleware.js +2 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/run_trees.cjs +8 -7
- package/dist/run_trees.d.ts +7 -0
- package/dist/run_trees.js +7 -6
- package/dist/schemas.d.ts +58 -0
- package/dist/singletons/otel.cjs +3 -2
- package/dist/singletons/otel.js +4 -3
- package/dist/singletons/traceable.cjs +1 -3
- package/dist/singletons/traceable.js +1 -3
- package/dist/traceable.cjs +2 -5
- package/dist/traceable.js +2 -5
- package/dist/utils/_git.cjs +2 -2
- package/dist/utils/_git.js +2 -2
- package/dist/utils/_uuid.cjs +2 -2
- package/dist/utils/_uuid.js +1 -1
- package/dist/utils/env.cjs +35 -2
- package/dist/utils/env.d.ts +9 -0
- package/dist/utils/env.js +34 -2
- package/dist/utils/error.cjs +9 -2
- package/dist/utils/error.d.ts +1 -0
- package/dist/utils/error.js +8 -2
- package/dist/utils/fast-safe-stringify/index.cjs +203 -0
- package/dist/utils/fast-safe-stringify/index.d.ts +46 -0
- package/dist/utils/fast-safe-stringify/index.js +202 -0
- package/dist/utils/jestlike/index.cjs +5 -5
- package/dist/utils/jestlike/index.js +1 -1
- package/dist/utils/jestlike/reporter.cjs +1 -1
- package/dist/utils/jestlike/reporter.js +1 -1
- package/dist/utils/jestlike/vendor/chain.cjs +2 -3
- package/dist/utils/jestlike/vendor/chain.js +2 -3
- package/dist/utils/jestlike/vendor/evaluatedBy.cjs +3 -3
- package/dist/utils/jestlike/vendor/evaluatedBy.js +1 -1
- package/dist/utils/prompts.cjs +7 -2
- package/dist/utils/prompts.d.ts +6 -1
- package/dist/utils/prompts.js +6 -1
- package/dist/utils/serialize_worker.cjs +388 -0
- package/dist/utils/serialize_worker.d.ts +66 -0
- package/dist/utils/serialize_worker.js +382 -0
- package/dist/utils/uuid/src/index.cjs +24 -0
- package/dist/utils/uuid/src/index.d.ts +10 -0
- package/dist/utils/uuid/src/index.js +9 -0
- package/dist/utils/uuid/src/max.cjs +3 -0
- package/dist/utils/uuid/src/max.d.ts +2 -0
- package/dist/utils/uuid/src/max.js +1 -0
- package/dist/utils/uuid/src/nil.cjs +3 -0
- package/dist/utils/uuid/src/nil.d.ts +2 -0
- package/dist/utils/uuid/src/nil.js +1 -0
- package/dist/utils/uuid/src/parse.cjs +23 -0
- package/dist/utils/uuid/src/parse.d.ts +3 -0
- package/dist/utils/uuid/src/parse.js +18 -0
- package/dist/utils/uuid/src/regex.cjs +3 -0
- package/dist/utils/uuid/src/regex.d.ts +2 -0
- package/dist/utils/uuid/src/regex.js +1 -0
- package/dist/utils/uuid/src/rng.cjs +10 -0
- package/dist/utils/uuid/src/rng.d.ts +1 -0
- package/dist/utils/uuid/src/rng.js +7 -0
- package/dist/utils/uuid/src/sha1.cjs +75 -0
- package/dist/utils/uuid/src/sha1.d.ts +2 -0
- package/dist/utils/uuid/src/sha1.js +73 -0
- package/dist/utils/uuid/src/stringify.cjs +55 -0
- package/dist/utils/uuid/src/stringify.d.ts +3 -0
- package/dist/utils/uuid/src/stringify.js +49 -0
- package/dist/utils/uuid/src/types.cjs +2 -0
- package/dist/utils/uuid/src/types.d.ts +22 -0
- package/dist/utils/uuid/src/types.js +1 -0
- package/dist/utils/uuid/src/v35.cjs +52 -0
- package/dist/utils/uuid/src/v35.d.ts +7 -0
- package/dist/utils/uuid/src/v35.js +44 -0
- package/dist/utils/uuid/src/v4.cjs +40 -0
- package/dist/utils/uuid/src/v4.d.ts +4 -0
- package/dist/utils/uuid/src/v4.js +35 -0
- package/dist/utils/uuid/src/v5.cjs +50 -0
- package/dist/utils/uuid/src/v5.d.ts +9 -0
- package/dist/utils/uuid/src/v5.js +9 -0
- package/dist/utils/uuid/src/v7.cjs +88 -0
- package/dist/utils/uuid/src/v7.d.ts +9 -0
- package/dist/utils/uuid/src/v7.js +82 -0
- package/dist/utils/uuid/src/validate.cjs +10 -0
- package/dist/utils/uuid/src/validate.d.ts +2 -0
- package/dist/utils/uuid/src/validate.js +5 -0
- package/dist/utils/uuid/src/version.cjs +13 -0
- package/dist/utils/uuid/src/version.d.ts +2 -0
- package/dist/utils/uuid/src/version.js +8 -0
- package/dist/utils/worker_threads.browser.cjs +16 -0
- package/dist/utils/worker_threads.browser.d.ts +14 -0
- package/dist/utils/worker_threads.browser.js +13 -0
- package/dist/utils/worker_threads.cjs +16 -0
- package/dist/utils/worker_threads.d.ts +13 -0
- package/dist/utils/worker_threads.js +13 -0
- package/dist/uuid.cjs +2 -2
- package/dist/uuid.js +1 -1
- package/dist/vitest/utils/esm.mjs +4 -4
- package/dist/wrappers/gemini.cjs +1 -1
- package/dist/wrappers/gemini.js +1 -1
- package/dist/wrappers/openai.cjs +2 -6
- package/dist/wrappers/openai.js +2 -6
- package/dist/wrappers/openai_agents.cjs +849 -0
- package/dist/wrappers/openai_agents.d.ts +92 -0
- package/dist/wrappers/openai_agents.js +845 -0
- package/experimental/opencode.cjs +1 -0
- package/experimental/opencode.d.cts +1 -0
- package/experimental/opencode.d.ts +1 -0
- package/experimental/opencode.js +1 -0
- package/package.json +47 -25
- package/wrappers/openai_agents.cjs +1 -0
- package/wrappers/openai_agents.d.cts +1 -0
- package/wrappers/openai_agents.d.ts +1 -0
- package/wrappers/openai_agents.js +1 -0
|
@@ -165,7 +165,6 @@ exports.LangSmithResourceNameConflictError = LangSmithResourceNameConflictError;
|
|
|
165
165
|
* - Resource values exceeding server-defined limits (CPU, memory, storage)
|
|
166
166
|
* - Invalid resource units
|
|
167
167
|
* - Invalid name formats
|
|
168
|
-
* - Pool validation failures (e.g., template has volumes)
|
|
169
168
|
*/
|
|
170
169
|
class LangSmithValidationError extends LangSmithSandboxError {
|
|
171
170
|
constructor(message, field, details, errorType) {
|
|
@@ -224,7 +223,7 @@ class LangSmithResourceCreationError extends LangSmithSandboxError {
|
|
|
224
223
|
constructor(message, resourceType, errorType) {
|
|
225
224
|
super(message);
|
|
226
225
|
/**
|
|
227
|
-
* Type of resource that failed (e.g., "sandbox", "
|
|
226
|
+
* Type of resource that failed (e.g., "sandbox", "snapshot").
|
|
228
227
|
*/
|
|
229
228
|
Object.defineProperty(this, "resourceType", {
|
|
230
229
|
enumerable: true,
|
|
@@ -75,7 +75,6 @@ export declare class LangSmithResourceNameConflictError extends LangSmithSandbox
|
|
|
75
75
|
* - Resource values exceeding server-defined limits (CPU, memory, storage)
|
|
76
76
|
* - Invalid resource units
|
|
77
77
|
* - Invalid name formats
|
|
78
|
-
* - Pool validation failures (e.g., template has volumes)
|
|
79
78
|
*/
|
|
80
79
|
export declare class LangSmithValidationError extends LangSmithSandboxError {
|
|
81
80
|
field?: string;
|
|
@@ -97,7 +96,7 @@ export declare class LangSmithQuotaExceededError extends LangSmithSandboxError {
|
|
|
97
96
|
*/
|
|
98
97
|
export declare class LangSmithResourceCreationError extends LangSmithSandboxError {
|
|
99
98
|
/**
|
|
100
|
-
* Type of resource that failed (e.g., "sandbox", "
|
|
99
|
+
* Type of resource that failed (e.g., "sandbox", "snapshot").
|
|
101
100
|
*/
|
|
102
101
|
resourceType?: string;
|
|
103
102
|
/**
|
|
@@ -153,7 +153,6 @@ export class LangSmithResourceNameConflictError extends LangSmithSandboxError {
|
|
|
153
153
|
* - Resource values exceeding server-defined limits (CPU, memory, storage)
|
|
154
154
|
* - Invalid resource units
|
|
155
155
|
* - Invalid name formats
|
|
156
|
-
* - Pool validation failures (e.g., template has volumes)
|
|
157
156
|
*/
|
|
158
157
|
export class LangSmithValidationError extends LangSmithSandboxError {
|
|
159
158
|
constructor(message, field, details, errorType) {
|
|
@@ -210,7 +209,7 @@ export class LangSmithResourceCreationError extends LangSmithSandboxError {
|
|
|
210
209
|
constructor(message, resourceType, errorType) {
|
|
211
210
|
super(message);
|
|
212
211
|
/**
|
|
213
|
-
* Type of resource that failed (e.g., "sandbox", "
|
|
212
|
+
* Type of resource that failed (e.g., "sandbox", "snapshot").
|
|
214
213
|
*/
|
|
215
214
|
Object.defineProperty(this, "resourceType", {
|
|
216
215
|
enumerable: true,
|
|
@@ -11,12 +11,8 @@ exports.parseErrorResponse = parseErrorResponse;
|
|
|
11
11
|
exports.parseValidationError = parseValidationError;
|
|
12
12
|
exports.extractQuotaType = extractQuotaType;
|
|
13
13
|
exports.handleSandboxCreationError = handleSandboxCreationError;
|
|
14
|
-
exports.handleVolumeCreationError = handleVolumeCreationError;
|
|
15
|
-
exports.handlePoolError = handlePoolError;
|
|
16
14
|
exports.handleClientHttpError = handleClientHttpError;
|
|
17
15
|
exports.handleSandboxHttpError = handleSandboxHttpError;
|
|
18
|
-
exports.handleConflictError = handleConflictError;
|
|
19
|
-
exports.handleResourceInUseError = handleResourceInUseError;
|
|
20
16
|
const errors_js_1 = require("./errors.cjs");
|
|
21
17
|
// =============================================================================
|
|
22
18
|
// Input validation
|
|
@@ -115,11 +111,6 @@ function extractQuotaType(message) {
|
|
|
115
111
|
else if (messageLower.includes("memory")) {
|
|
116
112
|
return "memory";
|
|
117
113
|
}
|
|
118
|
-
// Check for volume count quota
|
|
119
|
-
else if (messageLower.includes("volume") &&
|
|
120
|
-
(messageLower.includes("count") || messageLower.includes("limit"))) {
|
|
121
|
-
return "volume_count";
|
|
122
|
-
}
|
|
123
114
|
else if (messageLower.includes("storage")) {
|
|
124
115
|
return "storage";
|
|
125
116
|
}
|
|
@@ -140,6 +131,7 @@ function extractQuotaType(message) {
|
|
|
140
131
|
*/
|
|
141
132
|
async function handleSandboxCreationError(response) {
|
|
142
133
|
const status = response.status;
|
|
134
|
+
const clonedResponse = response.clone();
|
|
143
135
|
const data = await parseErrorResponse(response);
|
|
144
136
|
if (status === 408) {
|
|
145
137
|
// Timeout - include the message which contains last known status
|
|
@@ -147,7 +139,6 @@ async function handleSandboxCreationError(response) {
|
|
|
147
139
|
}
|
|
148
140
|
else if (status === 422) {
|
|
149
141
|
// Check if this is a Pydantic validation error (bad input) vs creation error
|
|
150
|
-
const clonedResponse = response.clone();
|
|
151
142
|
const details = await parseValidationError(clonedResponse);
|
|
152
143
|
if (details.length > 0 && details.some((d) => d.type === "value_error")) {
|
|
153
144
|
// Pydantic validation error (bad input - exceeds server limits)
|
|
@@ -168,86 +159,20 @@ async function handleSandboxCreationError(response) {
|
|
|
168
159
|
// Service Unavailable - scheduling failed
|
|
169
160
|
throw new errors_js_1.LangSmithSandboxCreationError(data.message, data.errorType || "Unschedulable");
|
|
170
161
|
}
|
|
171
|
-
// Fall through to generic handling
|
|
172
|
-
return handleClientHttpError(
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Handle HTTP errors specific to volume creation.
|
|
176
|
-
*
|
|
177
|
-
* Maps API error responses to specific exception types:
|
|
178
|
-
* - 429: LangSmithQuotaExceededError (org limits exceeded)
|
|
179
|
-
* - 503: LangSmithSandboxCreationError (provisioning failed)
|
|
180
|
-
* - 504: LangSmithResourceTimeoutError (volume didn't become ready in time)
|
|
181
|
-
* - Other: Falls through to generic error handling
|
|
182
|
-
*/
|
|
183
|
-
async function handleVolumeCreationError(response) {
|
|
184
|
-
const status = response.status;
|
|
185
|
-
const data = await parseErrorResponse(response);
|
|
186
|
-
if (status === 429) {
|
|
187
|
-
// Organization quota exceeded - extract type or default to volume_count
|
|
188
|
-
const quotaType = extractQuotaType(data.message) ?? "unknown";
|
|
189
|
-
throw new errors_js_1.LangSmithQuotaExceededError(data.message, quotaType);
|
|
190
|
-
}
|
|
191
|
-
else if (status === 503) {
|
|
192
|
-
// Provisioning failed (invalid storage class, quota exceeded)
|
|
193
|
-
throw new errors_js_1.LangSmithSandboxCreationError(data.message, "VolumeProvisioning");
|
|
194
|
-
}
|
|
195
|
-
else if (status === 504) {
|
|
196
|
-
// Timeout - volume didn't become ready in time
|
|
197
|
-
throw new errors_js_1.LangSmithResourceTimeoutError(data.message, "volume");
|
|
198
|
-
}
|
|
199
|
-
// Fall through to generic handling
|
|
200
|
-
return handleClientHttpError(response);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Handle HTTP errors specific to pool creation/update.
|
|
204
|
-
*
|
|
205
|
-
* Maps API error responses to specific exception types:
|
|
206
|
-
* - 400: LangSmithResourceNotFoundError or LangSmithValidationError (template has volumes)
|
|
207
|
-
* - 409: LangSmithResourceAlreadyExistsError
|
|
208
|
-
* - 429: LangSmithQuotaExceededError (org limits exceeded)
|
|
209
|
-
* - 504: LangSmithResourceTimeoutError (timeout waiting for ready replicas)
|
|
210
|
-
* - Other: Falls through to generic error handling
|
|
211
|
-
*/
|
|
212
|
-
async function handlePoolError(response) {
|
|
213
|
-
const status = response.status;
|
|
214
|
-
const data = await parseErrorResponse(response);
|
|
215
|
-
const errorType = data.errorType;
|
|
216
|
-
if (status === 400) {
|
|
217
|
-
// Check the error type to determine the specific exception
|
|
218
|
-
if (errorType === "TemplateNotFound") {
|
|
219
|
-
throw new errors_js_1.LangSmithResourceNotFoundError(data.message, "template");
|
|
220
|
-
}
|
|
221
|
-
else if (errorType === "LangSmithValidationError") {
|
|
222
|
-
// Template has volumes attached
|
|
223
|
-
throw new errors_js_1.LangSmithValidationError(data.message, undefined, undefined, errorType);
|
|
224
|
-
}
|
|
225
|
-
// Generic bad request - fall through to generic handling
|
|
226
|
-
}
|
|
227
|
-
else if (status === 409) {
|
|
228
|
-
// Pool already exists
|
|
229
|
-
throw new errors_js_1.LangSmithResourceAlreadyExistsError(data.message, "pool");
|
|
230
|
-
}
|
|
231
|
-
else if (status === 429) {
|
|
232
|
-
// Organization quota exceeded - extract type or default to pool_count
|
|
233
|
-
const quotaType = extractQuotaType(data.message) ?? "unknown";
|
|
234
|
-
throw new errors_js_1.LangSmithQuotaExceededError(data.message, quotaType);
|
|
235
|
-
}
|
|
236
|
-
else if (status === 504) {
|
|
237
|
-
// Timeout waiting for pool to be ready
|
|
238
|
-
throw new errors_js_1.LangSmithResourceTimeoutError(data.message, "pool");
|
|
239
|
-
}
|
|
240
|
-
// Fall through to generic handling
|
|
241
|
-
return handleClientHttpError(response);
|
|
162
|
+
// Fall through to generic handling — pass clone since body is already consumed
|
|
163
|
+
return handleClientHttpError(clonedResponse);
|
|
242
164
|
}
|
|
243
165
|
/**
|
|
244
166
|
* Handle HTTP errors and raise appropriate exceptions (for client operations).
|
|
245
167
|
*/
|
|
246
168
|
async function handleClientHttpError(response) {
|
|
169
|
+
const status = response.status;
|
|
170
|
+
// Only clone when we need to read the body twice (status 422 reads it again
|
|
171
|
+
// for structured validation details after parseErrorResponse consumes it).
|
|
172
|
+
const clonedResponse = status === 422 ? response.clone() : null;
|
|
247
173
|
const data = await parseErrorResponse(response);
|
|
248
174
|
const message = data.message;
|
|
249
175
|
const errorType = data.errorType;
|
|
250
|
-
const status = response.status;
|
|
251
176
|
if (status === 401 || status === 403) {
|
|
252
177
|
throw new errors_js_1.LangSmithSandboxAuthenticationError(message);
|
|
253
178
|
}
|
|
@@ -255,8 +180,7 @@ async function handleClientHttpError(response) {
|
|
|
255
180
|
throw new errors_js_1.LangSmithResourceNotFoundError(message);
|
|
256
181
|
}
|
|
257
182
|
// Handle validation errors (invalid resource values, formats, etc.)
|
|
258
|
-
if (status === 422) {
|
|
259
|
-
const clonedResponse = response.clone();
|
|
183
|
+
if (status === 422 && clonedResponse) {
|
|
260
184
|
const details = await parseValidationError(clonedResponse);
|
|
261
185
|
const field = details[0]?.loc?.slice(-1)[0];
|
|
262
186
|
throw new errors_js_1.LangSmithValidationError(message, field, details);
|
|
@@ -321,17 +245,3 @@ async function handleSandboxHttpError(response) {
|
|
|
321
245
|
}
|
|
322
246
|
throw new errors_js_1.LangSmithSandboxError(message);
|
|
323
247
|
}
|
|
324
|
-
/**
|
|
325
|
-
* Handle 409 Conflict errors for resource name conflicts.
|
|
326
|
-
*/
|
|
327
|
-
async function handleConflictError(response, resourceType) {
|
|
328
|
-
const data = await parseErrorResponse(response);
|
|
329
|
-
throw new errors_js_1.LangSmithResourceNameConflictError(data.message, resourceType);
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Handle 409 Conflict errors for resources in use.
|
|
333
|
-
*/
|
|
334
|
-
async function handleResourceInUseError(response, resourceType) {
|
|
335
|
-
const data = await parseErrorResponse(response);
|
|
336
|
-
throw new errors_js_1.LangSmithResourceInUseError(data.message, resourceType);
|
|
337
|
-
}
|
|
@@ -49,27 +49,6 @@ export declare function extractQuotaType(message: string): string | undefined;
|
|
|
49
49
|
* - Other: Falls through to generic error handling
|
|
50
50
|
*/
|
|
51
51
|
export declare function handleSandboxCreationError(response: Response): Promise<never>;
|
|
52
|
-
/**
|
|
53
|
-
* Handle HTTP errors specific to volume creation.
|
|
54
|
-
*
|
|
55
|
-
* Maps API error responses to specific exception types:
|
|
56
|
-
* - 429: LangSmithQuotaExceededError (org limits exceeded)
|
|
57
|
-
* - 503: LangSmithSandboxCreationError (provisioning failed)
|
|
58
|
-
* - 504: LangSmithResourceTimeoutError (volume didn't become ready in time)
|
|
59
|
-
* - Other: Falls through to generic error handling
|
|
60
|
-
*/
|
|
61
|
-
export declare function handleVolumeCreationError(response: Response): Promise<never>;
|
|
62
|
-
/**
|
|
63
|
-
* Handle HTTP errors specific to pool creation/update.
|
|
64
|
-
*
|
|
65
|
-
* Maps API error responses to specific exception types:
|
|
66
|
-
* - 400: LangSmithResourceNotFoundError or LangSmithValidationError (template has volumes)
|
|
67
|
-
* - 409: LangSmithResourceAlreadyExistsError
|
|
68
|
-
* - 429: LangSmithQuotaExceededError (org limits exceeded)
|
|
69
|
-
* - 504: LangSmithResourceTimeoutError (timeout waiting for ready replicas)
|
|
70
|
-
* - Other: Falls through to generic error handling
|
|
71
|
-
*/
|
|
72
|
-
export declare function handlePoolError(response: Response): Promise<never>;
|
|
73
52
|
/**
|
|
74
53
|
* Handle HTTP errors and raise appropriate exceptions (for client operations).
|
|
75
54
|
*/
|
|
@@ -87,12 +66,4 @@ export declare function handleClientHttpError(response: Response): Promise<never
|
|
|
87
66
|
* - 403 -> LangSmithSandboxOperationError (permission denied)
|
|
88
67
|
*/
|
|
89
68
|
export declare function handleSandboxHttpError(response: Response): Promise<never>;
|
|
90
|
-
/**
|
|
91
|
-
* Handle 409 Conflict errors for resource name conflicts.
|
|
92
|
-
*/
|
|
93
|
-
export declare function handleConflictError(response: Response, resourceType: string): Promise<never>;
|
|
94
|
-
/**
|
|
95
|
-
* Handle 409 Conflict errors for resources in use.
|
|
96
|
-
*/
|
|
97
|
-
export declare function handleResourceInUseError(response: Response, resourceType: string): Promise<never>;
|
|
98
69
|
export {};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* These functions are used to parse error responses and raise appropriate
|
|
5
5
|
* exceptions. They contain no I/O operations.
|
|
6
6
|
*/
|
|
7
|
-
import { LangSmithQuotaExceededError,
|
|
7
|
+
import { LangSmithQuotaExceededError, LangSmithResourceNotFoundError, LangSmithResourceTimeoutError, LangSmithSandboxAPIError, LangSmithSandboxAuthenticationError, LangSmithSandboxError, LangSmithSandboxConnectionError, LangSmithSandboxCreationError, LangSmithSandboxNotReadyError, LangSmithSandboxOperationError, LangSmithValidationError, } from "./errors.js";
|
|
8
8
|
// =============================================================================
|
|
9
9
|
// Input validation
|
|
10
10
|
// =============================================================================
|
|
@@ -102,11 +102,6 @@ export function extractQuotaType(message) {
|
|
|
102
102
|
else if (messageLower.includes("memory")) {
|
|
103
103
|
return "memory";
|
|
104
104
|
}
|
|
105
|
-
// Check for volume count quota
|
|
106
|
-
else if (messageLower.includes("volume") &&
|
|
107
|
-
(messageLower.includes("count") || messageLower.includes("limit"))) {
|
|
108
|
-
return "volume_count";
|
|
109
|
-
}
|
|
110
105
|
else if (messageLower.includes("storage")) {
|
|
111
106
|
return "storage";
|
|
112
107
|
}
|
|
@@ -127,6 +122,7 @@ export function extractQuotaType(message) {
|
|
|
127
122
|
*/
|
|
128
123
|
export async function handleSandboxCreationError(response) {
|
|
129
124
|
const status = response.status;
|
|
125
|
+
const clonedResponse = response.clone();
|
|
130
126
|
const data = await parseErrorResponse(response);
|
|
131
127
|
if (status === 408) {
|
|
132
128
|
// Timeout - include the message which contains last known status
|
|
@@ -134,7 +130,6 @@ export async function handleSandboxCreationError(response) {
|
|
|
134
130
|
}
|
|
135
131
|
else if (status === 422) {
|
|
136
132
|
// Check if this is a Pydantic validation error (bad input) vs creation error
|
|
137
|
-
const clonedResponse = response.clone();
|
|
138
133
|
const details = await parseValidationError(clonedResponse);
|
|
139
134
|
if (details.length > 0 && details.some((d) => d.type === "value_error")) {
|
|
140
135
|
// Pydantic validation error (bad input - exceeds server limits)
|
|
@@ -155,86 +150,20 @@ export async function handleSandboxCreationError(response) {
|
|
|
155
150
|
// Service Unavailable - scheduling failed
|
|
156
151
|
throw new LangSmithSandboxCreationError(data.message, data.errorType || "Unschedulable");
|
|
157
152
|
}
|
|
158
|
-
// Fall through to generic handling
|
|
159
|
-
return handleClientHttpError(
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Handle HTTP errors specific to volume creation.
|
|
163
|
-
*
|
|
164
|
-
* Maps API error responses to specific exception types:
|
|
165
|
-
* - 429: LangSmithQuotaExceededError (org limits exceeded)
|
|
166
|
-
* - 503: LangSmithSandboxCreationError (provisioning failed)
|
|
167
|
-
* - 504: LangSmithResourceTimeoutError (volume didn't become ready in time)
|
|
168
|
-
* - Other: Falls through to generic error handling
|
|
169
|
-
*/
|
|
170
|
-
export async function handleVolumeCreationError(response) {
|
|
171
|
-
const status = response.status;
|
|
172
|
-
const data = await parseErrorResponse(response);
|
|
173
|
-
if (status === 429) {
|
|
174
|
-
// Organization quota exceeded - extract type or default to volume_count
|
|
175
|
-
const quotaType = extractQuotaType(data.message) ?? "unknown";
|
|
176
|
-
throw new LangSmithQuotaExceededError(data.message, quotaType);
|
|
177
|
-
}
|
|
178
|
-
else if (status === 503) {
|
|
179
|
-
// Provisioning failed (invalid storage class, quota exceeded)
|
|
180
|
-
throw new LangSmithSandboxCreationError(data.message, "VolumeProvisioning");
|
|
181
|
-
}
|
|
182
|
-
else if (status === 504) {
|
|
183
|
-
// Timeout - volume didn't become ready in time
|
|
184
|
-
throw new LangSmithResourceTimeoutError(data.message, "volume");
|
|
185
|
-
}
|
|
186
|
-
// Fall through to generic handling
|
|
187
|
-
return handleClientHttpError(response);
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Handle HTTP errors specific to pool creation/update.
|
|
191
|
-
*
|
|
192
|
-
* Maps API error responses to specific exception types:
|
|
193
|
-
* - 400: LangSmithResourceNotFoundError or LangSmithValidationError (template has volumes)
|
|
194
|
-
* - 409: LangSmithResourceAlreadyExistsError
|
|
195
|
-
* - 429: LangSmithQuotaExceededError (org limits exceeded)
|
|
196
|
-
* - 504: LangSmithResourceTimeoutError (timeout waiting for ready replicas)
|
|
197
|
-
* - Other: Falls through to generic error handling
|
|
198
|
-
*/
|
|
199
|
-
export async function handlePoolError(response) {
|
|
200
|
-
const status = response.status;
|
|
201
|
-
const data = await parseErrorResponse(response);
|
|
202
|
-
const errorType = data.errorType;
|
|
203
|
-
if (status === 400) {
|
|
204
|
-
// Check the error type to determine the specific exception
|
|
205
|
-
if (errorType === "TemplateNotFound") {
|
|
206
|
-
throw new LangSmithResourceNotFoundError(data.message, "template");
|
|
207
|
-
}
|
|
208
|
-
else if (errorType === "LangSmithValidationError") {
|
|
209
|
-
// Template has volumes attached
|
|
210
|
-
throw new LangSmithValidationError(data.message, undefined, undefined, errorType);
|
|
211
|
-
}
|
|
212
|
-
// Generic bad request - fall through to generic handling
|
|
213
|
-
}
|
|
214
|
-
else if (status === 409) {
|
|
215
|
-
// Pool already exists
|
|
216
|
-
throw new LangSmithResourceAlreadyExistsError(data.message, "pool");
|
|
217
|
-
}
|
|
218
|
-
else if (status === 429) {
|
|
219
|
-
// Organization quota exceeded - extract type or default to pool_count
|
|
220
|
-
const quotaType = extractQuotaType(data.message) ?? "unknown";
|
|
221
|
-
throw new LangSmithQuotaExceededError(data.message, quotaType);
|
|
222
|
-
}
|
|
223
|
-
else if (status === 504) {
|
|
224
|
-
// Timeout waiting for pool to be ready
|
|
225
|
-
throw new LangSmithResourceTimeoutError(data.message, "pool");
|
|
226
|
-
}
|
|
227
|
-
// Fall through to generic handling
|
|
228
|
-
return handleClientHttpError(response);
|
|
153
|
+
// Fall through to generic handling — pass clone since body is already consumed
|
|
154
|
+
return handleClientHttpError(clonedResponse);
|
|
229
155
|
}
|
|
230
156
|
/**
|
|
231
157
|
* Handle HTTP errors and raise appropriate exceptions (for client operations).
|
|
232
158
|
*/
|
|
233
159
|
export async function handleClientHttpError(response) {
|
|
160
|
+
const status = response.status;
|
|
161
|
+
// Only clone when we need to read the body twice (status 422 reads it again
|
|
162
|
+
// for structured validation details after parseErrorResponse consumes it).
|
|
163
|
+
const clonedResponse = status === 422 ? response.clone() : null;
|
|
234
164
|
const data = await parseErrorResponse(response);
|
|
235
165
|
const message = data.message;
|
|
236
166
|
const errorType = data.errorType;
|
|
237
|
-
const status = response.status;
|
|
238
167
|
if (status === 401 || status === 403) {
|
|
239
168
|
throw new LangSmithSandboxAuthenticationError(message);
|
|
240
169
|
}
|
|
@@ -242,8 +171,7 @@ export async function handleClientHttpError(response) {
|
|
|
242
171
|
throw new LangSmithResourceNotFoundError(message);
|
|
243
172
|
}
|
|
244
173
|
// Handle validation errors (invalid resource values, formats, etc.)
|
|
245
|
-
if (status === 422) {
|
|
246
|
-
const clonedResponse = response.clone();
|
|
174
|
+
if (status === 422 && clonedResponse) {
|
|
247
175
|
const details = await parseValidationError(clonedResponse);
|
|
248
176
|
const field = details[0]?.loc?.slice(-1)[0];
|
|
249
177
|
throw new LangSmithValidationError(message, field, details);
|
|
@@ -308,17 +236,3 @@ export async function handleSandboxHttpError(response) {
|
|
|
308
236
|
}
|
|
309
237
|
throw new LangSmithSandboxError(message);
|
|
310
238
|
}
|
|
311
|
-
/**
|
|
312
|
-
* Handle 409 Conflict errors for resource name conflicts.
|
|
313
|
-
*/
|
|
314
|
-
export async function handleConflictError(response, resourceType) {
|
|
315
|
-
const data = await parseErrorResponse(response);
|
|
316
|
-
throw new LangSmithResourceNameConflictError(data.message, resourceType);
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Handle 409 Conflict errors for resources in use.
|
|
320
|
-
*/
|
|
321
|
-
export async function handleResourceInUseError(response, resourceType) {
|
|
322
|
-
const data = await parseErrorResponse(response);
|
|
323
|
-
throw new LangSmithResourceInUseError(data.message, resourceType);
|
|
324
|
-
}
|
|
@@ -12,7 +12,12 @@
|
|
|
12
12
|
* // Uses LANGSMITH_ENDPOINT and LANGSMITH_API_KEY from environment
|
|
13
13
|
* const client = new SandboxClient();
|
|
14
14
|
*
|
|
15
|
-
* const
|
|
15
|
+
* const snapshot = await client.createSnapshot(
|
|
16
|
+
* "python",
|
|
17
|
+
* "python:3.12-slim",
|
|
18
|
+
* 1_073_741_824
|
|
19
|
+
* );
|
|
20
|
+
* const sandbox = await client.createSandbox(snapshot.id);
|
|
16
21
|
* try {
|
|
17
22
|
* const result = await sandbox.run("python --version");
|
|
18
23
|
* console.log(result.stdout);
|
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
* // Uses LANGSMITH_ENDPOINT and LANGSMITH_API_KEY from environment
|
|
12
12
|
* const client = new SandboxClient();
|
|
13
13
|
*
|
|
14
|
-
* const
|
|
14
|
+
* const snapshot = await client.createSnapshot(
|
|
15
|
+
* "python",
|
|
16
|
+
* "python:3.12-slim",
|
|
17
|
+
* 1_073_741_824
|
|
18
|
+
* );
|
|
19
|
+
* const sandbox = await client.createSandbox(snapshot.id);
|
|
15
20
|
* try {
|
|
16
21
|
* const result = await sandbox.run("python --version");
|
|
17
22
|
* console.log(result.stdout);
|
|
@@ -25,5 +30,5 @@
|
|
|
25
30
|
export { SandboxClient } from "./client.js";
|
|
26
31
|
export { Sandbox } from "./sandbox.js";
|
|
27
32
|
export { CommandHandle } from "./command_handle.js";
|
|
28
|
-
export type { ExecutionResult, OutputChunk, WsMessage, WsRunOptions,
|
|
33
|
+
export type { ExecutionResult, OutputChunk, WsMessage, WsRunOptions, ResourceStatus, Snapshot, SandboxData, SandboxClientConfig, RunOptions, CreateSandboxOptions, SandboxAccessControl, SandboxProxyConfig, CreateSnapshotOptions, CaptureSnapshotOptions, ListSnapshotsOptions, WaitForSnapshotOptions, StartSandboxOptions, UpdateSandboxOptions, WaitForSandboxOptions, } from "./types.js";
|
|
29
34
|
export { LangSmithSandboxError, LangSmithSandboxAPIError, LangSmithSandboxAuthenticationError, LangSmithSandboxConnectionError, LangSmithSandboxServerReloadError, LangSmithResourceNotFoundError, LangSmithResourceTimeoutError, LangSmithResourceInUseError, LangSmithResourceAlreadyExistsError, LangSmithResourceNameConflictError, LangSmithValidationError, LangSmithQuotaExceededError, LangSmithResourceCreationError, LangSmithSandboxCreationError, LangSmithSandboxNotReadyError, LangSmithSandboxOperationError, LangSmithCommandTimeoutError, LangSmithDataplaneNotConfiguredError, } from "./errors.js";
|
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
* // Uses LANGSMITH_ENDPOINT and LANGSMITH_API_KEY from environment
|
|
12
12
|
* const client = new SandboxClient();
|
|
13
13
|
*
|
|
14
|
-
* const
|
|
14
|
+
* const snapshot = await client.createSnapshot(
|
|
15
|
+
* "python",
|
|
16
|
+
* "python:3.12-slim",
|
|
17
|
+
* 1_073_741_824
|
|
18
|
+
* );
|
|
19
|
+
* const sandbox = await client.createSandbox(snapshot.id);
|
|
15
20
|
* try {
|
|
16
21
|
* const result = await sandbox.run("python --version");
|
|
17
22
|
* console.log(result.stdout);
|
|
@@ -17,7 +17,7 @@ const ws_execute_js_1 = require("./ws_execute.cjs");
|
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
19
|
* ```typescript
|
|
20
|
-
* const sandbox = await client.createSandbox(
|
|
20
|
+
* const sandbox = await client.createSandbox(snapshot.id);
|
|
21
21
|
* try {
|
|
22
22
|
* const result = await sandbox.run("python --version");
|
|
23
23
|
* console.log(result.stdout);
|
|
@@ -38,13 +38,6 @@ class Sandbox {
|
|
|
38
38
|
writable: true,
|
|
39
39
|
value: void 0
|
|
40
40
|
});
|
|
41
|
-
/** Name of the template used to create this sandbox. */
|
|
42
|
-
Object.defineProperty(this, "template_name", {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
configurable: true,
|
|
45
|
-
writable: true,
|
|
46
|
-
value: void 0
|
|
47
|
-
});
|
|
48
41
|
/** URL for data plane operations (file I/O, command execution). */
|
|
49
42
|
Object.defineProperty(this, "dataplane_url", {
|
|
50
43
|
enumerable: true,
|
|
@@ -52,7 +45,7 @@ class Sandbox {
|
|
|
52
45
|
writable: true,
|
|
53
46
|
value: void 0
|
|
54
47
|
});
|
|
55
|
-
/** Provisioning status ("provisioning", "ready", "failed"). */
|
|
48
|
+
/** Provisioning status ("provisioning", "ready", "failed", "stopped"). */
|
|
56
49
|
Object.defineProperty(this, "status", {
|
|
57
50
|
enumerable: true,
|
|
58
51
|
configurable: true,
|
|
@@ -94,7 +87,11 @@ class Sandbox {
|
|
|
94
87
|
writable: true,
|
|
95
88
|
value: void 0
|
|
96
89
|
});
|
|
97
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* Idle timeout TTL in seconds (`0` means disabled).
|
|
92
|
+
* New sandboxes receive a server-side default of `600` seconds (10 minutes)
|
|
93
|
+
* when the caller did not set `idleTtlSeconds` explicitly.
|
|
94
|
+
*/
|
|
98
95
|
Object.defineProperty(this, "idle_ttl_seconds", {
|
|
99
96
|
enumerable: true,
|
|
100
97
|
configurable: true,
|
|
@@ -108,6 +105,34 @@ class Sandbox {
|
|
|
108
105
|
writable: true,
|
|
109
106
|
value: void 0
|
|
110
107
|
});
|
|
108
|
+
/** Snapshot ID used to create this sandbox. */
|
|
109
|
+
Object.defineProperty(this, "snapshot_id", {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
configurable: true,
|
|
112
|
+
writable: true,
|
|
113
|
+
value: void 0
|
|
114
|
+
});
|
|
115
|
+
/** Number of vCPUs allocated. */
|
|
116
|
+
Object.defineProperty(this, "vCpus", {
|
|
117
|
+
enumerable: true,
|
|
118
|
+
configurable: true,
|
|
119
|
+
writable: true,
|
|
120
|
+
value: void 0
|
|
121
|
+
});
|
|
122
|
+
/** Memory allocation in bytes. */
|
|
123
|
+
Object.defineProperty(this, "mem_bytes", {
|
|
124
|
+
enumerable: true,
|
|
125
|
+
configurable: true,
|
|
126
|
+
writable: true,
|
|
127
|
+
value: void 0
|
|
128
|
+
});
|
|
129
|
+
/** Root filesystem capacity in bytes. */
|
|
130
|
+
Object.defineProperty(this, "fs_capacity_bytes", {
|
|
131
|
+
enumerable: true,
|
|
132
|
+
configurable: true,
|
|
133
|
+
writable: true,
|
|
134
|
+
value: void 0
|
|
135
|
+
});
|
|
111
136
|
Object.defineProperty(this, "_client", {
|
|
112
137
|
enumerable: true,
|
|
113
138
|
configurable: true,
|
|
@@ -115,7 +140,6 @@ class Sandbox {
|
|
|
115
140
|
value: void 0
|
|
116
141
|
});
|
|
117
142
|
this.name = data.name;
|
|
118
|
-
this.template_name = data.template_name;
|
|
119
143
|
this.dataplane_url = data.dataplane_url;
|
|
120
144
|
this.status = data.status;
|
|
121
145
|
this.status_message = data.status_message;
|
|
@@ -125,6 +149,10 @@ class Sandbox {
|
|
|
125
149
|
this.ttl_seconds = data.ttl_seconds;
|
|
126
150
|
this.idle_ttl_seconds = data.idle_ttl_seconds;
|
|
127
151
|
this.expires_at = data.expires_at;
|
|
152
|
+
this.snapshot_id = data.snapshot_id;
|
|
153
|
+
this.vCpus = data.vcpus;
|
|
154
|
+
this.mem_bytes = data.mem_bytes;
|
|
155
|
+
this.fs_capacity_bytes = data.fs_capacity_bytes;
|
|
128
156
|
this._client = client;
|
|
129
157
|
}
|
|
130
158
|
/**
|
|
@@ -177,7 +205,7 @@ class Sandbox {
|
|
|
177
205
|
catch (e) {
|
|
178
206
|
// Fall back to HTTP on connection errors or missing ws package
|
|
179
207
|
const name = e != null && typeof e === "object" ? e.name : "";
|
|
180
|
-
const message = e != null && typeof e === "object" ? e.message ?? "" : "";
|
|
208
|
+
const message = e != null && typeof e === "object" ? (e.message ?? "") : "";
|
|
181
209
|
if (name === "LangSmithSandboxConnectionError" ||
|
|
182
210
|
name === "LangSmithSandboxServerReloadError" ||
|
|
183
211
|
message.includes("'ws' package")) {
|
|
@@ -328,7 +356,7 @@ class Sandbox {
|
|
|
328
356
|
*
|
|
329
357
|
* @example
|
|
330
358
|
* ```typescript
|
|
331
|
-
* const sandbox = await client.createSandbox(
|
|
359
|
+
* const sandbox = await client.createSandbox(snapshot.id);
|
|
332
360
|
* try {
|
|
333
361
|
* await sandbox.run("echo hello");
|
|
334
362
|
* } finally {
|
|
@@ -339,5 +367,35 @@ class Sandbox {
|
|
|
339
367
|
async delete() {
|
|
340
368
|
await this._client.deleteSandbox(this.name);
|
|
341
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Start a stopped sandbox and wait until ready.
|
|
372
|
+
*
|
|
373
|
+
* Updates this sandbox's status and dataplane_url in place.
|
|
374
|
+
*
|
|
375
|
+
* @param timeout - Timeout in seconds when waiting for ready. Default: 120.
|
|
376
|
+
*/
|
|
377
|
+
async start(options = {}) {
|
|
378
|
+
const refreshed = await this._client.startSandbox(this.name, options);
|
|
379
|
+
this.status = refreshed.status;
|
|
380
|
+
this.dataplane_url = refreshed.dataplane_url;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Stop a running sandbox (preserves sandbox files for later restart).
|
|
384
|
+
*/
|
|
385
|
+
async stop() {
|
|
386
|
+
await this._client.stopSandbox(this.name);
|
|
387
|
+
this.status = "stopped";
|
|
388
|
+
this.dataplane_url = undefined;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Capture a snapshot from this sandbox.
|
|
392
|
+
*
|
|
393
|
+
* @param name - Snapshot name.
|
|
394
|
+
* @param options - Capture options (timeout).
|
|
395
|
+
* @returns Snapshot in "ready" status.
|
|
396
|
+
*/
|
|
397
|
+
async captureSnapshot(name, options = {}) {
|
|
398
|
+
return this._client.captureSnapshot(this.name, name, options);
|
|
399
|
+
}
|
|
342
400
|
}
|
|
343
401
|
exports.Sandbox = Sandbox;
|