@agentuity/server 0.1.9 → 0.1.11
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/api/api.d.ts +1 -1
- package/dist/api/api.d.ts.map +1 -1
- package/dist/api/api.js +7 -3
- package/dist/api/api.js.map +1 -1
- package/dist/api/org/resources.d.ts +10 -5
- package/dist/api/org/resources.d.ts.map +1 -1
- package/dist/api/org/resources.js +14 -6
- package/dist/api/org/resources.js.map +1 -1
- package/dist/api/project/deployment.d.ts +14 -0
- package/dist/api/project/deployment.d.ts.map +1 -1
- package/dist/api/project/deployment.js +20 -0
- package/dist/api/project/deployment.js.map +1 -1
- package/dist/api/sandbox/create.d.ts.map +1 -1
- package/dist/api/sandbox/create.js +1 -4
- package/dist/api/sandbox/create.js.map +1 -1
- package/dist/api/sandbox/execution.d.ts.map +1 -1
- package/dist/api/sandbox/execution.js +4 -1
- package/dist/api/sandbox/execution.js.map +1 -1
- package/dist/api/sandbox/get.d.ts.map +1 -1
- package/dist/api/sandbox/get.js +33 -0
- package/dist/api/sandbox/get.js.map +1 -1
- package/dist/api/sandbox/index.d.ts +4 -2
- package/dist/api/sandbox/index.d.ts.map +1 -1
- package/dist/api/sandbox/index.js +2 -1
- package/dist/api/sandbox/index.js.map +1 -1
- package/dist/api/sandbox/list.d.ts.map +1 -1
- package/dist/api/sandbox/list.js +8 -0
- package/dist/api/sandbox/list.js.map +1 -1
- package/dist/api/sandbox/runtime.d.ts.map +1 -1
- package/dist/api/sandbox/runtime.js.map +1 -1
- package/dist/api/sandbox/snapshot-build.d.ts +31 -0
- package/dist/api/sandbox/snapshot-build.d.ts.map +1 -0
- package/dist/api/sandbox/snapshot-build.js +48 -0
- package/dist/api/sandbox/snapshot-build.js.map +1 -0
- package/dist/api/sandbox/snapshot.d.ts +129 -47
- package/dist/api/sandbox/snapshot.d.ts.map +1 -1
- package/dist/api/sandbox/snapshot.js +159 -3
- package/dist/api/sandbox/snapshot.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/package.json +4 -4
- package/src/api/api.ts +17 -3
- package/src/api/org/resources.ts +21 -6
- package/src/api/project/deployment.ts +28 -0
- package/src/api/sandbox/create.ts +1 -4
- package/src/api/sandbox/execution.ts +4 -1
- package/src/api/sandbox/get.ts +37 -0
- package/src/api/sandbox/index.ts +14 -1
- package/src/api/sandbox/list.ts +9 -0
- package/src/api/sandbox/runtime.ts +10 -8
- package/src/api/sandbox/snapshot-build.ts +62 -0
- package/src/api/sandbox/snapshot.ts +194 -51
- package/src/config.ts +1 -1
package/src/api/api.ts
CHANGED
|
@@ -208,7 +208,8 @@ export class APIClient {
|
|
|
208
208
|
responseSchema?: z.ZodType<TResponse>,
|
|
209
209
|
body?: TBody,
|
|
210
210
|
bodySchema?: z.ZodType<TBody>,
|
|
211
|
-
signal?: AbortSignal
|
|
211
|
+
signal?: AbortSignal,
|
|
212
|
+
extraHeaders?: Record<string, string>
|
|
212
213
|
): Promise<TResponse> {
|
|
213
214
|
// Validate request body if schema provided
|
|
214
215
|
if (body !== undefined && bodySchema) {
|
|
@@ -221,7 +222,14 @@ export class APIClient {
|
|
|
221
222
|
}
|
|
222
223
|
}
|
|
223
224
|
|
|
224
|
-
const response = await this.#makeRequest(
|
|
225
|
+
const response = await this.#makeRequest(
|
|
226
|
+
method,
|
|
227
|
+
endpoint,
|
|
228
|
+
body,
|
|
229
|
+
signal,
|
|
230
|
+
undefined,
|
|
231
|
+
extraHeaders
|
|
232
|
+
);
|
|
225
233
|
|
|
226
234
|
// Handle empty responses (204 or zero-length body)
|
|
227
235
|
let data: unknown;
|
|
@@ -263,7 +271,8 @@ export class APIClient {
|
|
|
263
271
|
endpoint: string,
|
|
264
272
|
body?: unknown,
|
|
265
273
|
signal?: AbortSignal,
|
|
266
|
-
contentType?: string
|
|
274
|
+
contentType?: string,
|
|
275
|
+
extraHeaders?: Record<string, string>
|
|
267
276
|
): Promise<Response> {
|
|
268
277
|
this.#logger.trace('sending %s to %s%s', method, this.#baseUrl, endpoint);
|
|
269
278
|
|
|
@@ -294,6 +303,11 @@ export class APIClient {
|
|
|
294
303
|
);
|
|
295
304
|
}
|
|
296
305
|
|
|
306
|
+
// Apply per-request extra headers (e.g., x-agentuity-orgid for CLI auth)
|
|
307
|
+
if (extraHeaders) {
|
|
308
|
+
Object.keys(extraHeaders).forEach((key) => (headers[key] = extraHeaders[key]));
|
|
309
|
+
}
|
|
310
|
+
|
|
297
311
|
const canRetry = !(body instanceof ReadableStream); // we cannot safely retry a ReadableStream as body
|
|
298
312
|
|
|
299
313
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
package/src/api/org/resources.ts
CHANGED
|
@@ -34,27 +34,32 @@ export type OrgDBResource = z.infer<typeof OrgDBResource>;
|
|
|
34
34
|
export interface ListOrgResourcesOptions {
|
|
35
35
|
/** Filter by resource type (default: "all") */
|
|
36
36
|
type?: 'all' | 's3' | 'db';
|
|
37
|
+
/** Organization ID (required for CLI auth, extracted from context for SDK auth) */
|
|
38
|
+
orgId?: string;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
42
|
* List all resources for the authenticated organization (across all regions)
|
|
41
|
-
* Extracts orgId from authentication context (API key, SDK, or CLI token)
|
|
42
43
|
*
|
|
43
44
|
* @param client - Catalyst API client (must be authenticated)
|
|
44
|
-
* @param options - Optional filters
|
|
45
|
+
* @param options - Optional filters including orgId for CLI auth
|
|
45
46
|
* @returns List of S3 and DB resources with their cloud regions
|
|
46
47
|
*
|
|
47
48
|
* @example
|
|
48
|
-
* // Get all resources
|
|
49
|
+
* // Get all resources (SDK auth - orgId from context)
|
|
49
50
|
* const all = await listOrgResources(client);
|
|
50
51
|
*
|
|
51
52
|
* @example
|
|
53
|
+
* // Get all resources (CLI auth - orgId required)
|
|
54
|
+
* const all = await listOrgResources(client, { orgId: 'org_123' });
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
52
57
|
* // Get only S3 buckets
|
|
53
|
-
* const s3Only = await listOrgResources(client, { type: 's3' });
|
|
58
|
+
* const s3Only = await listOrgResources(client, { type: 's3', orgId: 'org_123' });
|
|
54
59
|
*
|
|
55
60
|
* @example
|
|
56
61
|
* // Get only DBs
|
|
57
|
-
* const dbsOnly = await listOrgResources(client, { type: 'db' });
|
|
62
|
+
* const dbsOnly = await listOrgResources(client, { type: 'db', orgId: 'org_123' });
|
|
58
63
|
*/
|
|
59
64
|
export async function listOrgResources(
|
|
60
65
|
client: APIClient,
|
|
@@ -68,10 +73,20 @@ export async function listOrgResources(
|
|
|
68
73
|
const query = params.toString();
|
|
69
74
|
const url = `/resource/2025-11-16${query ? `?${query}` : ''}`;
|
|
70
75
|
|
|
76
|
+
// Build headers - include orgId for CLI auth
|
|
77
|
+
const headers: Record<string, string> = {};
|
|
78
|
+
if (options?.orgId) {
|
|
79
|
+
headers['x-agentuity-orgid'] = options.orgId;
|
|
80
|
+
}
|
|
81
|
+
|
|
71
82
|
const resp = await client.request<OrgResourceListResponse>(
|
|
72
83
|
'GET',
|
|
73
84
|
url,
|
|
74
|
-
OrgResourceListResponseSchema
|
|
85
|
+
OrgResourceListResponseSchema,
|
|
86
|
+
undefined,
|
|
87
|
+
undefined,
|
|
88
|
+
undefined,
|
|
89
|
+
headers
|
|
75
90
|
);
|
|
76
91
|
if (resp.success) {
|
|
77
92
|
return resp.data;
|
|
@@ -90,6 +90,34 @@ export async function projectDeploymentGet(
|
|
|
90
90
|
throw new ProjectResponseError({ message: resp.message });
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
const DeploymentLookupSchema = z.object({
|
|
94
|
+
id: z.string(),
|
|
95
|
+
projectId: z.string(),
|
|
96
|
+
orgId: z.string(),
|
|
97
|
+
cloudRegion: z.string().nullable().optional(),
|
|
98
|
+
state: z.string().nullable().optional(),
|
|
99
|
+
active: z.boolean(),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const DeploymentLookupResponseSchema = APIResponseSchema(DeploymentLookupSchema);
|
|
103
|
+
|
|
104
|
+
export type DeploymentLookup = z.infer<typeof DeploymentLookupSchema>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get deployment info by ID only (without requiring project ID).
|
|
108
|
+
* Useful for looking up region/project info for a deployment.
|
|
109
|
+
*/
|
|
110
|
+
export async function deploymentGet(
|
|
111
|
+
client: APIClient,
|
|
112
|
+
deploymentId: string
|
|
113
|
+
): Promise<DeploymentLookup> {
|
|
114
|
+
const resp = await client.get(`/cli/deployment/${deploymentId}`, DeploymentLookupResponseSchema);
|
|
115
|
+
if (resp.success) {
|
|
116
|
+
return resp.data;
|
|
117
|
+
}
|
|
118
|
+
throw new ProjectResponseError({ message: resp.message });
|
|
119
|
+
}
|
|
120
|
+
|
|
93
121
|
export async function projectDeploymentDelete(
|
|
94
122
|
client: APIClient,
|
|
95
123
|
projectId: string,
|
|
@@ -5,10 +5,7 @@ import type { SandboxCreateOptions, SandboxStatus } from '@agentuity/core';
|
|
|
5
5
|
|
|
6
6
|
const SandboxCreateRequestSchema = z
|
|
7
7
|
.object({
|
|
8
|
-
runtime: z
|
|
9
|
-
.string()
|
|
10
|
-
.optional()
|
|
11
|
-
.describe('Runtime name (e.g., "bun:1", "python:3.14")'),
|
|
8
|
+
runtime: z.string().optional().describe('Runtime name (e.g., "bun:1", "python:3.14")'),
|
|
12
9
|
runtimeId: z.string().optional().describe('Runtime ID (e.g., "srt_xxx")'),
|
|
13
10
|
name: z.string().optional().describe('Optional sandbox name'),
|
|
14
11
|
description: z.string().optional().describe('Optional sandbox description'),
|
|
@@ -7,7 +7,10 @@ const ExecutionInfoSchema = z
|
|
|
7
7
|
.object({
|
|
8
8
|
executionId: z.string().describe('Unique identifier for the execution'),
|
|
9
9
|
sandboxId: z.string().describe('ID of the sandbox where the execution ran'),
|
|
10
|
-
type: z
|
|
10
|
+
type: z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('Type of execution (e.g., exec, write_files, read_file)'),
|
|
11
14
|
status: z
|
|
12
15
|
.enum(['queued', 'running', 'completed', 'failed', 'timeout', 'cancelled'])
|
|
13
16
|
.describe('Current status of the execution'),
|
package/src/api/sandbox/get.ts
CHANGED
|
@@ -11,6 +11,35 @@ const SandboxResourcesSchema = z
|
|
|
11
11
|
})
|
|
12
12
|
.describe('Resource limits for the sandbox');
|
|
13
13
|
|
|
14
|
+
const SandboxUserInfoSchema = z
|
|
15
|
+
.object({
|
|
16
|
+
id: z.string().describe('User ID'),
|
|
17
|
+
firstName: z.string().optional().describe("User's first name"),
|
|
18
|
+
lastName: z.string().optional().describe("User's last name"),
|
|
19
|
+
})
|
|
20
|
+
.describe('User who created the sandbox');
|
|
21
|
+
|
|
22
|
+
const SandboxAgentInfoSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
id: z.string().describe('Agent ID'),
|
|
25
|
+
name: z.string().describe('Agent name'),
|
|
26
|
+
})
|
|
27
|
+
.describe('Agent associated with the sandbox');
|
|
28
|
+
|
|
29
|
+
const SandboxProjectInfoSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
id: z.string().describe('Project ID'),
|
|
32
|
+
name: z.string().describe('Project name'),
|
|
33
|
+
})
|
|
34
|
+
.describe('Project associated with the sandbox');
|
|
35
|
+
|
|
36
|
+
const SandboxOrgInfoSchema = z
|
|
37
|
+
.object({
|
|
38
|
+
id: z.string().describe('Organization ID'),
|
|
39
|
+
name: z.string().describe('Organization name'),
|
|
40
|
+
})
|
|
41
|
+
.describe('Organization associated with the sandbox');
|
|
42
|
+
|
|
14
43
|
const SandboxInfoDataSchema = z
|
|
15
44
|
.object({
|
|
16
45
|
sandboxId: z.string().describe('Unique identifier for the sandbox'),
|
|
@@ -43,6 +72,10 @@ const SandboxInfoDataSchema = z
|
|
|
43
72
|
memoryByteSec: z.number().optional().describe('Total memory usage in byte-seconds'),
|
|
44
73
|
networkEgressBytes: z.number().optional().describe('Total network egress in bytes'),
|
|
45
74
|
networkEnabled: z.boolean().optional().describe('Whether network access is enabled'),
|
|
75
|
+
user: SandboxUserInfoSchema.optional().describe('User who created the sandbox'),
|
|
76
|
+
agent: SandboxAgentInfoSchema.optional().describe('Agent associated with the sandbox'),
|
|
77
|
+
project: SandboxProjectInfoSchema.optional().describe('Project associated with the sandbox'),
|
|
78
|
+
org: SandboxOrgInfoSchema.describe('Organization associated with the sandbox'),
|
|
46
79
|
})
|
|
47
80
|
.describe('Detailed information about a sandbox');
|
|
48
81
|
|
|
@@ -106,6 +139,10 @@ export async function sandboxGet(
|
|
|
106
139
|
memoryByteSec: resp.data.memoryByteSec,
|
|
107
140
|
networkEgressBytes: resp.data.networkEgressBytes,
|
|
108
141
|
networkEnabled: resp.data.networkEnabled,
|
|
142
|
+
user: resp.data.user,
|
|
143
|
+
agent: resp.data.agent,
|
|
144
|
+
project: resp.data.project,
|
|
145
|
+
org: resp.data.org,
|
|
109
146
|
};
|
|
110
147
|
}
|
|
111
148
|
|
package/src/api/sandbox/index.ts
CHANGED
|
@@ -49,7 +49,15 @@ export type {
|
|
|
49
49
|
SetEnvParams,
|
|
50
50
|
SetEnvResult,
|
|
51
51
|
} from './files';
|
|
52
|
-
export {
|
|
52
|
+
export {
|
|
53
|
+
snapshotCreate,
|
|
54
|
+
snapshotGet,
|
|
55
|
+
snapshotList,
|
|
56
|
+
snapshotDelete,
|
|
57
|
+
snapshotTag,
|
|
58
|
+
snapshotBuildInit,
|
|
59
|
+
snapshotBuildFinalize,
|
|
60
|
+
} from './snapshot';
|
|
53
61
|
export type {
|
|
54
62
|
SnapshotInfo,
|
|
55
63
|
SnapshotFileInfo,
|
|
@@ -59,4 +67,9 @@ export type {
|
|
|
59
67
|
SnapshotListResponse,
|
|
60
68
|
SnapshotDeleteParams,
|
|
61
69
|
SnapshotTagParams,
|
|
70
|
+
SnapshotBuildInitParams,
|
|
71
|
+
SnapshotBuildInitResponse,
|
|
72
|
+
SnapshotBuildFinalizeParams,
|
|
62
73
|
} from './snapshot';
|
|
74
|
+
export { SnapshotBuildFileSchema } from './snapshot-build';
|
|
75
|
+
export type { SnapshotBuildFile } from './snapshot-build';
|
package/src/api/sandbox/list.ts
CHANGED
|
@@ -3,6 +3,13 @@ import { APIClient, APIResponseSchema } from '../api';
|
|
|
3
3
|
import { SandboxResponseError, API_VERSION } from './util';
|
|
4
4
|
import type { ListSandboxesParams, ListSandboxesResponse, SandboxStatus } from '@agentuity/core';
|
|
5
5
|
|
|
6
|
+
const SandboxOrgInfoSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
id: z.string().describe('Organization ID'),
|
|
9
|
+
name: z.string().describe('Organization name'),
|
|
10
|
+
})
|
|
11
|
+
.describe('Organization associated with the sandbox');
|
|
12
|
+
|
|
6
13
|
const SandboxInfoSchema = z
|
|
7
14
|
.object({
|
|
8
15
|
sandboxId: z.string().describe('Unique identifier for the sandbox'),
|
|
@@ -23,6 +30,7 @@ const SandboxInfoSchema = z
|
|
|
23
30
|
stdoutStreamUrl: z.string().optional().describe('URL for streaming stdout output'),
|
|
24
31
|
stderrStreamUrl: z.string().optional().describe('URL for streaming stderr output'),
|
|
25
32
|
networkEnabled: z.boolean().optional().describe('Whether network access is enabled'),
|
|
33
|
+
org: SandboxOrgInfoSchema.describe('Organization associated with the sandbox'),
|
|
26
34
|
})
|
|
27
35
|
.describe('Summary information about a sandbox');
|
|
28
36
|
|
|
@@ -103,6 +111,7 @@ export async function sandboxList(
|
|
|
103
111
|
stdoutStreamUrl: s.stdoutStreamUrl,
|
|
104
112
|
stderrStreamUrl: s.stderrStreamUrl,
|
|
105
113
|
networkEnabled: s.networkEnabled,
|
|
114
|
+
org: s.org,
|
|
106
115
|
})),
|
|
107
116
|
total: resp.data.total,
|
|
108
117
|
};
|
|
@@ -61,14 +61,16 @@ export async function runtimeList(
|
|
|
61
61
|
|
|
62
62
|
if (resp.success) {
|
|
63
63
|
return {
|
|
64
|
-
runtimes: resp.data.runtimes.map(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
runtimes: resp.data.runtimes.map(
|
|
65
|
+
(r): SandboxRuntime => ({
|
|
66
|
+
id: r.id,
|
|
67
|
+
name: r.name,
|
|
68
|
+
description: r.description,
|
|
69
|
+
iconUrl: r.iconUrl,
|
|
70
|
+
url: r.url,
|
|
71
|
+
tags: r.tags,
|
|
72
|
+
})
|
|
73
|
+
),
|
|
72
74
|
total: resp.data.total,
|
|
73
75
|
};
|
|
74
76
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base schema for snapshot build configuration file (agentuity-snapshot.yaml)
|
|
5
|
+
* This is the canonical schema - used for JSON Schema generation.
|
|
6
|
+
*/
|
|
7
|
+
export const SnapshotBuildFileBaseSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
version: z.literal(1).describe('Schema version, must be 1'),
|
|
10
|
+
runtime: z
|
|
11
|
+
.string()
|
|
12
|
+
.describe('Runtime identifier (name:tag format, e.g., bun:1, node:20, python:3.12)'),
|
|
13
|
+
name: z
|
|
14
|
+
.string()
|
|
15
|
+
.regex(/^[a-zA-Z0-9_-]+$/)
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Snapshot name (alphanumeric, underscores, dashes only)'),
|
|
18
|
+
description: z.string().optional().describe('Human-readable description of the snapshot'),
|
|
19
|
+
dependencies: z
|
|
20
|
+
.array(z.string())
|
|
21
|
+
.optional()
|
|
22
|
+
.describe(
|
|
23
|
+
'List of apt packages to install. Supports version pinning: package=version or package=version* for prefix matching'
|
|
24
|
+
),
|
|
25
|
+
files: z
|
|
26
|
+
.array(z.string())
|
|
27
|
+
.optional()
|
|
28
|
+
.describe(
|
|
29
|
+
'Glob patterns for files to include from the build context. Supports negative patterns with ! prefix for exclusions'
|
|
30
|
+
),
|
|
31
|
+
env: z
|
|
32
|
+
.record(z.string(), z.string())
|
|
33
|
+
.optional()
|
|
34
|
+
.describe(
|
|
35
|
+
'Environment variables to set. Use ${VAR} syntax for build-time substitution via --env flag'
|
|
36
|
+
),
|
|
37
|
+
metadata: z
|
|
38
|
+
.record(z.string(), z.string())
|
|
39
|
+
.optional()
|
|
40
|
+
.describe(
|
|
41
|
+
'User-defined metadata key-value pairs. Use ${VAR} syntax for build-time substitution via --metadata flag'
|
|
42
|
+
),
|
|
43
|
+
})
|
|
44
|
+
.describe('Agentuity Snapshot Build File - defines a reproducible sandbox environment');
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Schema with validation refinement - use this for parsing/validation.
|
|
48
|
+
* Ensures at least one of dependencies, files, or env is specified.
|
|
49
|
+
*/
|
|
50
|
+
export const SnapshotBuildFileSchema = SnapshotBuildFileBaseSchema.refine(
|
|
51
|
+
(data) => {
|
|
52
|
+
const hasDependencies = data.dependencies && data.dependencies.length > 0;
|
|
53
|
+
const hasFiles = data.files && data.files.length > 0;
|
|
54
|
+
const hasEnv = data.env && Object.keys(data.env).length > 0;
|
|
55
|
+
return hasDependencies || hasFiles || hasEnv;
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
message: 'At least one of dependencies, files, or env must be specified',
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
export type SnapshotBuildFile = z.infer<typeof SnapshotBuildFileSchema>;
|
|
@@ -12,8 +12,16 @@ const SnapshotFileInfoSchema = z
|
|
|
12
12
|
const SnapshotInfoSchema = z
|
|
13
13
|
.object({
|
|
14
14
|
snapshotId: z.string().describe('Unique identifier for the snapshot'),
|
|
15
|
-
runtimeId: z
|
|
16
|
-
|
|
15
|
+
runtimeId: z
|
|
16
|
+
.string()
|
|
17
|
+
.nullable()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Runtime ID associated with this snapshot'),
|
|
20
|
+
name: z
|
|
21
|
+
.string()
|
|
22
|
+
.describe(
|
|
23
|
+
'Display name for the snapshot (URL-safe: letters, numbers, underscores, dashes)'
|
|
24
|
+
),
|
|
17
25
|
description: z.string().nullable().optional().describe('Description of the snapshot'),
|
|
18
26
|
tag: z.string().nullable().optional().describe('Tag for the snapshot (defaults to "latest")'),
|
|
19
27
|
sizeBytes: z.number().describe('Total size of the snapshot in bytes'),
|
|
@@ -25,7 +33,16 @@ const SnapshotInfoSchema = z
|
|
|
25
33
|
.describe('ID of the parent snapshot (for incremental snapshots)'),
|
|
26
34
|
createdAt: z.string().describe('ISO timestamp when the snapshot was created'),
|
|
27
35
|
downloadUrl: z.string().optional().describe('URL to download the snapshot archive'),
|
|
28
|
-
files: z
|
|
36
|
+
files: z
|
|
37
|
+
.array(SnapshotFileInfoSchema)
|
|
38
|
+
.nullable()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('List of files in the snapshot'),
|
|
41
|
+
userMetadata: z
|
|
42
|
+
.record(z.string(), z.string())
|
|
43
|
+
.nullable()
|
|
44
|
+
.optional()
|
|
45
|
+
.describe('User-defined metadata key-value pairs'),
|
|
29
46
|
})
|
|
30
47
|
.describe('Detailed information about a snapshot');
|
|
31
48
|
|
|
@@ -40,60 +57,56 @@ const SnapshotListDataSchema = z
|
|
|
40
57
|
const SnapshotListResponseSchema = APIResponseSchema(SnapshotListDataSchema);
|
|
41
58
|
const SnapshotDeleteResponseSchema = APIResponseSchemaNoData();
|
|
42
59
|
|
|
43
|
-
export
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface SnapshotInfo {
|
|
49
|
-
snapshotId: string;
|
|
50
|
-
runtimeId?: string | null;
|
|
51
|
-
name: string;
|
|
52
|
-
description?: string | null;
|
|
53
|
-
tag?: string | null;
|
|
54
|
-
sizeBytes: number;
|
|
55
|
-
fileCount: number;
|
|
56
|
-
parentSnapshotId?: string | null;
|
|
57
|
-
createdAt: string;
|
|
58
|
-
downloadUrl?: string;
|
|
59
|
-
files?: SnapshotFileInfo[] | null;
|
|
60
|
-
}
|
|
60
|
+
export type SnapshotFileInfo = z.infer<typeof SnapshotFileInfoSchema>;
|
|
61
|
+
export type SnapshotInfo = z.infer<typeof SnapshotInfoSchema>;
|
|
62
|
+
export type SnapshotListResponse = z.infer<typeof SnapshotListDataSchema>;
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
const _SnapshotCreateParamsSchema = z
|
|
65
|
+
.object({
|
|
66
|
+
sandboxId: z.string().describe('ID of the sandbox to snapshot'),
|
|
67
|
+
name: z.string().optional().describe('Display name for the snapshot'),
|
|
68
|
+
description: z.string().optional().describe('Description of the snapshot'),
|
|
69
|
+
tag: z.string().optional().describe('Tag for the snapshot'),
|
|
70
|
+
orgId: z.string().optional().describe('Organization ID'),
|
|
71
|
+
})
|
|
72
|
+
.describe('Parameters for creating a snapshot');
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
const _SnapshotGetParamsSchema = z
|
|
75
|
+
.object({
|
|
76
|
+
snapshotId: z.string().describe('ID of the snapshot to retrieve'),
|
|
77
|
+
orgId: z.string().optional().describe('Organization ID'),
|
|
78
|
+
})
|
|
79
|
+
.describe('Parameters for getting a snapshot');
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
const _SnapshotListParamsSchema = z
|
|
82
|
+
.object({
|
|
83
|
+
sandboxId: z.string().optional().describe('Filter by sandbox ID'),
|
|
84
|
+
limit: z.number().optional().describe('Maximum number of snapshots to return'),
|
|
85
|
+
offset: z.number().optional().describe('Number of snapshots to skip'),
|
|
86
|
+
orgId: z.string().optional().describe('Organization ID'),
|
|
87
|
+
})
|
|
88
|
+
.describe('Parameters for listing snapshots');
|
|
81
89
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
const _SnapshotDeleteParamsSchema = z
|
|
91
|
+
.object({
|
|
92
|
+
snapshotId: z.string().describe('ID of the snapshot to delete'),
|
|
93
|
+
orgId: z.string().optional().describe('Organization ID'),
|
|
94
|
+
})
|
|
95
|
+
.describe('Parameters for deleting a snapshot');
|
|
86
96
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
const _SnapshotTagParamsSchema = z
|
|
98
|
+
.object({
|
|
99
|
+
snapshotId: z.string().describe('ID of the snapshot to tag'),
|
|
100
|
+
tag: z.string().nullable().describe('New tag (or null to remove)'),
|
|
101
|
+
orgId: z.string().optional().describe('Organization ID'),
|
|
102
|
+
})
|
|
103
|
+
.describe('Parameters for tagging a snapshot');
|
|
91
104
|
|
|
92
|
-
export
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
export type SnapshotCreateParams = z.infer<typeof _SnapshotCreateParamsSchema>;
|
|
106
|
+
export type SnapshotGetParams = z.infer<typeof _SnapshotGetParamsSchema>;
|
|
107
|
+
export type SnapshotListParams = z.infer<typeof _SnapshotListParamsSchema>;
|
|
108
|
+
export type SnapshotDeleteParams = z.infer<typeof _SnapshotDeleteParamsSchema>;
|
|
109
|
+
export type SnapshotTagParams = z.infer<typeof _SnapshotTagParamsSchema>;
|
|
97
110
|
|
|
98
111
|
function buildQueryString(params: Record<string, string | number | undefined>): string {
|
|
99
112
|
const query = new URLSearchParams();
|
|
@@ -255,3 +268,133 @@ export async function snapshotTag(
|
|
|
255
268
|
|
|
256
269
|
throw new SandboxResponseError({ message: resp.message });
|
|
257
270
|
}
|
|
271
|
+
|
|
272
|
+
// ===== Snapshot Build API =====
|
|
273
|
+
|
|
274
|
+
const _SnapshotBuildInitParamsSchema = z
|
|
275
|
+
.object({
|
|
276
|
+
runtime: z.string().describe('Runtime identifier (name:tag or runtime ID)'),
|
|
277
|
+
name: z.string().optional().describe('Display name for the snapshot'),
|
|
278
|
+
tag: z.string().optional().describe('Tag for the snapshot'),
|
|
279
|
+
description: z.string().optional().describe('Description of the snapshot'),
|
|
280
|
+
contentHash: z.string().optional().describe('SHA-256 hash of snapshot content for change detection'),
|
|
281
|
+
force: z.boolean().optional().describe('Force rebuild even if content is unchanged'),
|
|
282
|
+
orgId: z.string().optional().describe('Organization ID'),
|
|
283
|
+
})
|
|
284
|
+
.describe('Parameters for initializing a snapshot build');
|
|
285
|
+
|
|
286
|
+
const SnapshotBuildInitResponseSchema = z
|
|
287
|
+
.object({
|
|
288
|
+
snapshotId: z.string().optional().describe('Unique identifier for the snapshot being built'),
|
|
289
|
+
uploadUrl: z.string().optional().describe('Pre-signed URL for uploading the snapshot archive'),
|
|
290
|
+
s3Key: z.string().optional().describe('S3 key where the snapshot will be stored'),
|
|
291
|
+
unchanged: z.boolean().optional().describe('True if snapshot content is unchanged'),
|
|
292
|
+
existingId: z.string().optional().describe('ID of existing unchanged snapshot'),
|
|
293
|
+
existingName: z.string().optional().describe('Name of existing unchanged snapshot'),
|
|
294
|
+
existingTag: z.string().optional().describe('Tag of existing unchanged snapshot'),
|
|
295
|
+
})
|
|
296
|
+
.describe('Response from snapshot build init API');
|
|
297
|
+
|
|
298
|
+
const SnapshotBuildInitAPIResponseSchema = APIResponseSchema(SnapshotBuildInitResponseSchema);
|
|
299
|
+
|
|
300
|
+
const _SnapshotBuildFinalizeParamsSchema = z
|
|
301
|
+
.object({
|
|
302
|
+
snapshotId: z.string().describe('Snapshot ID from init response'),
|
|
303
|
+
sizeBytes: z.number().describe('Total size of the snapshot in bytes'),
|
|
304
|
+
fileCount: z.number().describe('Number of files in the snapshot'),
|
|
305
|
+
files: z
|
|
306
|
+
.array(SnapshotFileInfoSchema)
|
|
307
|
+
.describe('List of files with path and size'),
|
|
308
|
+
dependencies: z
|
|
309
|
+
.array(z.string())
|
|
310
|
+
.optional()
|
|
311
|
+
.describe('List of apt packages to install'),
|
|
312
|
+
env: z
|
|
313
|
+
.record(z.string(), z.string())
|
|
314
|
+
.optional()
|
|
315
|
+
.describe('Environment variables to set'),
|
|
316
|
+
metadata: z
|
|
317
|
+
.record(z.string(), z.string())
|
|
318
|
+
.optional()
|
|
319
|
+
.describe('User-defined metadata key-value pairs'),
|
|
320
|
+
orgId: z.string().optional().describe('Organization ID'),
|
|
321
|
+
})
|
|
322
|
+
.describe('Parameters for finalizing a snapshot build');
|
|
323
|
+
|
|
324
|
+
export type SnapshotBuildInitParams = z.infer<typeof _SnapshotBuildInitParamsSchema>;
|
|
325
|
+
export type SnapshotBuildInitResponse = z.infer<typeof SnapshotBuildInitResponseSchema>;
|
|
326
|
+
export type SnapshotBuildFinalizeParams = z.infer<typeof _SnapshotBuildFinalizeParamsSchema>;
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Initialize a snapshot build by getting a presigned upload URL.
|
|
330
|
+
*
|
|
331
|
+
* @param client - The API client to use for the request
|
|
332
|
+
* @param params - Parameters including runtime and optional name/tag/description
|
|
333
|
+
* @returns Snapshot ID and presigned upload URL
|
|
334
|
+
* @throws {SandboxResponseError} If the initialization fails
|
|
335
|
+
*/
|
|
336
|
+
export async function snapshotBuildInit(
|
|
337
|
+
client: APIClient,
|
|
338
|
+
params: SnapshotBuildInitParams
|
|
339
|
+
): Promise<SnapshotBuildInitResponse> {
|
|
340
|
+
const { runtime, name, description, tag, contentHash, force, orgId } = params;
|
|
341
|
+
const queryString = buildQueryString({ orgId });
|
|
342
|
+
const url = `/sandbox/${API_VERSION}/snapshots/build${queryString}`;
|
|
343
|
+
|
|
344
|
+
const body: Record<string, string | boolean> = { runtime };
|
|
345
|
+
if (name) body.name = name;
|
|
346
|
+
if (description) body.description = description;
|
|
347
|
+
if (tag) body.tag = tag;
|
|
348
|
+
if (contentHash) body.contentHash = contentHash;
|
|
349
|
+
if (force) body.force = force;
|
|
350
|
+
|
|
351
|
+
const resp = await client.post<z.infer<typeof SnapshotBuildInitAPIResponseSchema>>(
|
|
352
|
+
url,
|
|
353
|
+
body,
|
|
354
|
+
SnapshotBuildInitAPIResponseSchema
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
if (resp.success) {
|
|
358
|
+
return resp.data;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
throw new SandboxResponseError({ message: resp.message });
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Finalize a snapshot build after uploading the archive.
|
|
366
|
+
*
|
|
367
|
+
* @param client - The API client to use for the request
|
|
368
|
+
* @param params - Parameters including snapshot details and file metadata
|
|
369
|
+
* @returns The created snapshot information
|
|
370
|
+
* @throws {SandboxResponseError} If the finalization fails
|
|
371
|
+
*/
|
|
372
|
+
export async function snapshotBuildFinalize(
|
|
373
|
+
client: APIClient,
|
|
374
|
+
params: SnapshotBuildFinalizeParams
|
|
375
|
+
): Promise<SnapshotInfo> {
|
|
376
|
+
const { snapshotId, sizeBytes, fileCount, files, dependencies, env, metadata, orgId } = params;
|
|
377
|
+
const queryString = buildQueryString({ orgId });
|
|
378
|
+
const url = `/sandbox/${API_VERSION}/snapshots/${snapshotId}/finalize${queryString}`;
|
|
379
|
+
|
|
380
|
+
const body: Record<string, unknown> = {
|
|
381
|
+
sizeBytes,
|
|
382
|
+
fileCount,
|
|
383
|
+
files,
|
|
384
|
+
};
|
|
385
|
+
if (dependencies) body.dependencies = dependencies;
|
|
386
|
+
if (env) body.env = env;
|
|
387
|
+
if (metadata) body.metadata = metadata;
|
|
388
|
+
|
|
389
|
+
const resp = await client.post<z.infer<typeof SnapshotGetResponseSchema>>(
|
|
390
|
+
url,
|
|
391
|
+
body,
|
|
392
|
+
SnapshotGetResponseSchema
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
if (resp.success) {
|
|
396
|
+
return resp.data;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
throw new SandboxResponseError({ message: resp.message });
|
|
400
|
+
}
|
package/src/config.ts
CHANGED