@agentuity/server 0.1.10 → 0.1.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.
- package/dist/api/org/resources.d.ts +3 -0
- package/dist/api/org/resources.d.ts.map +1 -1
- package/dist/api/org/resources.js +1 -0
- package/dist/api/org/resources.js.map +1 -1
- package/dist/api/project/deploy.d.ts.map +1 -1
- package/dist/api/project/deploy.js +3 -1
- package/dist/api/project/deploy.js.map +1 -1
- package/dist/api/region/create.d.ts +18 -0
- package/dist/api/region/create.d.ts.map +1 -1
- package/dist/api/region/create.js +123 -0
- package/dist/api/region/create.js.map +1 -1
- package/dist/api/sandbox/create.d.ts.map +1 -1
- package/dist/api/sandbox/create.js +11 -0
- package/dist/api/sandbox/create.js.map +1 -1
- package/dist/api/sandbox/files.d.ts.map +1 -1
- package/dist/api/sandbox/files.js +9 -1
- package/dist/api/sandbox/files.js.map +1 -1
- package/dist/api/sandbox/get.d.ts.map +1 -1
- package/dist/api/sandbox/get.js +6 -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 +9 -0
- package/dist/api/sandbox/list.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 +144 -0
- package/dist/api/sandbox/snapshot.js.map +1 -1
- package/dist/api/sandbox/util.d.ts +4 -0
- package/dist/api/sandbox/util.d.ts.map +1 -1
- package/dist/api/sandbox/util.js.map +1 -1
- package/dist/api/session/get.d.ts +1 -1
- package/dist/api/session/get.js +1 -1
- package/dist/api/session/get.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/org/resources.ts +1 -0
- package/src/api/project/deploy.ts +3 -1
- package/src/api/region/create.ts +130 -1
- package/src/api/sandbox/create.ts +11 -0
- package/src/api/sandbox/files.ts +9 -1
- package/src/api/sandbox/get.ts +6 -0
- package/src/api/sandbox/index.ts +14 -1
- package/src/api/sandbox/list.ts +9 -0
- package/src/api/sandbox/snapshot-build.ts +62 -0
- package/src/api/sandbox/snapshot.ts +177 -48
- package/src/api/sandbox/util.ts +2 -0
- package/src/api/session/get.ts +1 -1
- package/src/config.ts +1 -1
package/dist/api/session/get.js
CHANGED
|
@@ -12,7 +12,7 @@ const EvalRunSchema = z.object({
|
|
|
12
12
|
pending: z.boolean().describe('pending status'),
|
|
13
13
|
success: z.boolean().describe('success status'),
|
|
14
14
|
error: z.string().nullable().describe('error message'),
|
|
15
|
-
result: z.string().nullable().describe('result
|
|
15
|
+
result: z.record(z.string(), z.unknown()).nullable().describe('result object'),
|
|
16
16
|
});
|
|
17
17
|
const SpanNodeSchema = z.lazy(() => z.object({
|
|
18
18
|
id: z.string().describe('span ID'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/api/session/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAa,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAE9C,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;CACzC,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;IACtC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACrD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;IAC7C,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC/C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;IACtD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/api/session/get.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe;IAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACd,mHAAmH,CACnH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC7C,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,GACjB,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,gBAAgB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAErF,OAAO;QACN,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,YAAY;QAC5D,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,gBAAgB,CAAC,cAAc,EAAE,SAAS,CAAC;QACvF,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,YAAY;QACxD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,YAAY;QAC5D,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC;QAChF,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,YAAY;KAC1D,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,MAAe;IACvC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe;IAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACd,mHAAmH,CACnH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC7C,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,GACjB,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,gBAAgB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAErF,OAAO;QACN,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,YAAY;QAC5D,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,gBAAgB,CAAC,cAAc,EAAE,SAAS,CAAC;QACvF,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,YAAY;QACxD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,YAAY;QAC5D,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC;QAChF,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,YAAY;KAC1D,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,MAAe;IACvC,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QAC1C,OAAO,cAAc,CAAC;IACvB,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAe,EAAE,QAAiB;IAC3D,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC/B,OAAO,WAAW,QAAQ,IAAI,MAAM,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,WAAW,QAAQ,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;AAClD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentuity/server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"author": "Agentuity employees and contributors",
|
|
6
6
|
"type": "module",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"prepublishOnly": "bun run clean && bun run build"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@agentuity/core": "0.1.
|
|
29
|
-
"@agentuity/schema": "0.1.
|
|
28
|
+
"@agentuity/core": "0.1.12",
|
|
29
|
+
"@agentuity/schema": "0.1.12",
|
|
30
30
|
"zod": "^4.3.5"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@agentuity/test-utils": "0.1.
|
|
33
|
+
"@agentuity/test-utils": "0.1.12",
|
|
34
34
|
"@types/bun": "latest",
|
|
35
35
|
"@types/node": "^22.0.0",
|
|
36
36
|
"bun-types": "latest",
|
package/src/api/org/resources.ts
CHANGED
|
@@ -13,6 +13,7 @@ const OrgS3Resource = z.object({
|
|
|
13
13
|
|
|
14
14
|
const OrgDBResource = z.object({
|
|
15
15
|
name: z.string().describe('the database name'),
|
|
16
|
+
description: z.string().nullable().optional().describe('optional description of the database'),
|
|
16
17
|
username: z.string().nullable().optional().describe('the database username'),
|
|
17
18
|
password: z.string().nullable().optional().describe('the database password'),
|
|
18
19
|
url: z.string().nullable().optional().describe('the full database connection URL'),
|
|
@@ -302,7 +302,9 @@ export async function projectDeploymentComplete(
|
|
|
302
302
|
if (resp.success) {
|
|
303
303
|
return resp.data;
|
|
304
304
|
}
|
|
305
|
-
throw new ProjectResponseError({
|
|
305
|
+
throw new ProjectResponseError({
|
|
306
|
+
message: resp.message || 'Deployment completion failed with unknown error',
|
|
307
|
+
});
|
|
306
308
|
}
|
|
307
309
|
|
|
308
310
|
/**
|
package/src/api/region/create.ts
CHANGED
|
@@ -2,9 +2,122 @@ import { z } from 'zod';
|
|
|
2
2
|
import { APIResponseSchema, APIClient } from '../api';
|
|
3
3
|
import { RegionResponseError } from './util';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Database name validation regex - must match catalyst server validation:
|
|
7
|
+
* - Must start with a letter or underscore
|
|
8
|
+
* - Can contain only lowercase letters, digits, and underscores
|
|
9
|
+
* - Must be lowercase
|
|
10
|
+
*/
|
|
11
|
+
const DATABASE_NAME_REGEX = /^[a-z_][a-z0-9_]*$/;
|
|
12
|
+
const MAX_DATABASE_NAME_LENGTH = 63;
|
|
13
|
+
const MIN_DATABASE_NAME_LENGTH = 1;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* S3 bucket name validation - must match catalyst server validation (AWS S3 rules):
|
|
17
|
+
* - Length [3, 63]
|
|
18
|
+
* - Only lowercase, numbers, dots, hyphens
|
|
19
|
+
* - No adjacent periods
|
|
20
|
+
* - Starts with lowercase or number
|
|
21
|
+
* - Ends with lowercase or number
|
|
22
|
+
* - No xn-- prefix
|
|
23
|
+
* - No -s3alias suffix
|
|
24
|
+
* - Not an IP address
|
|
25
|
+
*/
|
|
26
|
+
const BUCKET_NAME_REGEX = /^[a-z0-9.-]+$/;
|
|
27
|
+
const MAX_BUCKET_NAME_LENGTH = 63;
|
|
28
|
+
const MIN_BUCKET_NAME_LENGTH = 3;
|
|
29
|
+
const IPV4_REGEX = /^(\d{1,3}\.){3}\d{1,3}$/;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Validates a database name for PostgreSQL compatibility.
|
|
33
|
+
* Matches the server-side validation in catalyst.
|
|
34
|
+
*/
|
|
35
|
+
export function validateDatabaseName(name: string): { valid: boolean; error?: string } {
|
|
36
|
+
if (name.length < MIN_DATABASE_NAME_LENGTH) {
|
|
37
|
+
return { valid: false, error: 'database name is too short (minimum 1 character)' };
|
|
38
|
+
}
|
|
39
|
+
if (name.length > MAX_DATABASE_NAME_LENGTH) {
|
|
40
|
+
return {
|
|
41
|
+
valid: false,
|
|
42
|
+
error: `database name is too long (maximum ${MAX_DATABASE_NAME_LENGTH} characters)`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (name !== name.toLowerCase()) {
|
|
46
|
+
return { valid: false, error: 'database name must be lowercase' };
|
|
47
|
+
}
|
|
48
|
+
if (!DATABASE_NAME_REGEX.test(name)) {
|
|
49
|
+
return {
|
|
50
|
+
valid: false,
|
|
51
|
+
error: 'database name must start with a letter or underscore and contain only lowercase letters, digits, and underscores',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return { valid: true };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Validates an S3 bucket name according to AWS S3 naming rules.
|
|
59
|
+
* Matches the server-side validation in catalyst.
|
|
60
|
+
*/
|
|
61
|
+
export function validateBucketName(name: string): { valid: boolean; error?: string } {
|
|
62
|
+
if (name.length < MIN_BUCKET_NAME_LENGTH) {
|
|
63
|
+
return {
|
|
64
|
+
valid: false,
|
|
65
|
+
error: `bucket name is too short (minimum ${MIN_BUCKET_NAME_LENGTH} characters)`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (name.length > MAX_BUCKET_NAME_LENGTH) {
|
|
69
|
+
return {
|
|
70
|
+
valid: false,
|
|
71
|
+
error: `bucket name is too long (maximum ${MAX_BUCKET_NAME_LENGTH} characters)`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (!BUCKET_NAME_REGEX.test(name)) {
|
|
75
|
+
return {
|
|
76
|
+
valid: false,
|
|
77
|
+
error: 'bucket name can only contain lowercase letters, numbers, dots, and hyphens',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (name.includes('..')) {
|
|
81
|
+
return { valid: false, error: 'bucket name cannot contain adjacent periods' };
|
|
82
|
+
}
|
|
83
|
+
const firstChar = name[0];
|
|
84
|
+
if (!((firstChar >= 'a' && firstChar <= 'z') || (firstChar >= '0' && firstChar <= '9'))) {
|
|
85
|
+
return { valid: false, error: 'bucket name must start with a lowercase letter or number' };
|
|
86
|
+
}
|
|
87
|
+
const lastChar = name[name.length - 1];
|
|
88
|
+
if (!((lastChar >= 'a' && lastChar <= 'z') || (lastChar >= '0' && lastChar <= '9'))) {
|
|
89
|
+
return { valid: false, error: 'bucket name must end with a lowercase letter or number' };
|
|
90
|
+
}
|
|
91
|
+
if (name.startsWith('xn--')) {
|
|
92
|
+
return { valid: false, error: 'bucket name cannot start with xn--' };
|
|
93
|
+
}
|
|
94
|
+
if (name.endsWith('-s3alias')) {
|
|
95
|
+
return { valid: false, error: 'bucket name cannot end with -s3alias' };
|
|
96
|
+
}
|
|
97
|
+
if (isIPv4Address(name)) {
|
|
98
|
+
return { valid: false, error: 'bucket name cannot be an IP address' };
|
|
99
|
+
}
|
|
100
|
+
return { valid: true };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isIPv4Address(s: string): boolean {
|
|
104
|
+
if (!IPV4_REGEX.test(s)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const parts = s.split('.');
|
|
108
|
+
for (const part of parts) {
|
|
109
|
+
const num = parseInt(part, 10);
|
|
110
|
+
if (isNaN(num) || num < 0 || num > 255) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
5
117
|
const ResourceSpec = z.object({
|
|
6
118
|
type: z.enum(['db', 's3']).describe('the resource type'),
|
|
7
119
|
name: z.string().optional().describe('optional custom name for db'),
|
|
120
|
+
description: z.string().optional().describe('optional description for db'),
|
|
8
121
|
});
|
|
9
122
|
|
|
10
123
|
const CreateResourcesRequest = z.object({
|
|
@@ -41,8 +154,24 @@ export async function createResources(
|
|
|
41
154
|
client: APIClient,
|
|
42
155
|
orgId: string,
|
|
43
156
|
region: string,
|
|
44
|
-
resources: Array<{ type: 'db' | 's3'; name?: string }>
|
|
157
|
+
resources: Array<{ type: 'db' | 's3'; name?: string; description?: string }>
|
|
45
158
|
): Promise<CreatedResource[]> {
|
|
159
|
+
// Validate resource names before sending to server
|
|
160
|
+
for (const resource of resources) {
|
|
161
|
+
if (resource.type === 'db' && resource.name) {
|
|
162
|
+
const validation = validateDatabaseName(resource.name);
|
|
163
|
+
if (!validation.valid) {
|
|
164
|
+
throw new RegionResponseError({ message: validation.error! });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (resource.type === 's3' && resource.name) {
|
|
168
|
+
const validation = validateBucketName(resource.name);
|
|
169
|
+
if (!validation.valid) {
|
|
170
|
+
throw new RegionResponseError({ message: validation.error! });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
46
175
|
const resp = await client.request<CreateResourcesResponse, CreateResourcesRequest>(
|
|
47
176
|
'POST',
|
|
48
177
|
`/resource/2025-11-16/${orgId}/${region}`,
|
|
@@ -5,6 +5,7 @@ import type { SandboxCreateOptions, SandboxStatus } from '@agentuity/core';
|
|
|
5
5
|
|
|
6
6
|
const SandboxCreateRequestSchema = z
|
|
7
7
|
.object({
|
|
8
|
+
projectId: z.string().optional().describe('Project ID to associate the sandbox with'),
|
|
8
9
|
runtime: z.string().optional().describe('Runtime name (e.g., "bun:1", "python:3.14")'),
|
|
9
10
|
runtimeId: z.string().optional().describe('Runtime ID (e.g., "srt_xxx")'),
|
|
10
11
|
name: z.string().optional().describe('Optional sandbox name'),
|
|
@@ -24,6 +25,13 @@ const SandboxCreateRequestSchema = z
|
|
|
24
25
|
network: z
|
|
25
26
|
.object({
|
|
26
27
|
enabled: z.boolean().optional().describe('Whether network access is enabled'),
|
|
28
|
+
port: z
|
|
29
|
+
.number()
|
|
30
|
+
.int()
|
|
31
|
+
.min(1024)
|
|
32
|
+
.max(65535)
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('Port to expose from the sandbox (1024-65535)'),
|
|
27
35
|
})
|
|
28
36
|
.optional()
|
|
29
37
|
.describe('Network configuration for the sandbox'),
|
|
@@ -120,6 +128,9 @@ export async function sandboxCreate(
|
|
|
120
128
|
const { options = {}, orgId } = params;
|
|
121
129
|
const body: z.infer<typeof SandboxCreateRequestSchema> = {};
|
|
122
130
|
|
|
131
|
+
if (options.projectId) {
|
|
132
|
+
body.projectId = options.projectId;
|
|
133
|
+
}
|
|
123
134
|
if (options.runtime) {
|
|
124
135
|
body.runtime = options.runtime;
|
|
125
136
|
}
|
package/src/api/sandbox/files.ts
CHANGED
|
@@ -118,12 +118,14 @@ export async function sandboxReadFile(
|
|
|
118
118
|
const url = `/fs/${API_VERSION}/${sandboxId}?${queryString}`;
|
|
119
119
|
|
|
120
120
|
const response = await client.rawGet(url, signal);
|
|
121
|
+
const sessionId = response.headers.get('x-session-id');
|
|
121
122
|
|
|
122
123
|
if (!response.ok) {
|
|
123
124
|
const text = await response.text().catch(() => 'Unknown error');
|
|
124
125
|
throw new SandboxResponseError({
|
|
125
126
|
message: `Failed to read file: ${response.status} ${text}`,
|
|
126
127
|
sandboxId,
|
|
128
|
+
sessionId,
|
|
127
129
|
});
|
|
128
130
|
}
|
|
129
131
|
|
|
@@ -131,6 +133,7 @@ export async function sandboxReadFile(
|
|
|
131
133
|
throw new SandboxResponseError({
|
|
132
134
|
message: 'No response body',
|
|
133
135
|
sandboxId,
|
|
136
|
+
sessionId,
|
|
134
137
|
});
|
|
135
138
|
}
|
|
136
139
|
|
|
@@ -433,12 +436,14 @@ export async function sandboxDownloadArchive(
|
|
|
433
436
|
const url = `/fs/${API_VERSION}/download/${sandboxId}${queryString ? `?${queryString}` : ''}`;
|
|
434
437
|
|
|
435
438
|
const response = await client.rawGet(url, signal);
|
|
439
|
+
const sessionId = response.headers.get('x-session-id');
|
|
436
440
|
|
|
437
441
|
if (!response.ok) {
|
|
438
442
|
const text = await response.text().catch(() => 'Unknown error');
|
|
439
443
|
throw new SandboxResponseError({
|
|
440
444
|
message: `Failed to download archive: ${response.status} ${text}`,
|
|
441
445
|
sandboxId,
|
|
446
|
+
sessionId,
|
|
442
447
|
});
|
|
443
448
|
}
|
|
444
449
|
|
|
@@ -446,6 +451,7 @@ export async function sandboxDownloadArchive(
|
|
|
446
451
|
throw new SandboxResponseError({
|
|
447
452
|
message: 'No response body',
|
|
448
453
|
sandboxId,
|
|
454
|
+
sessionId,
|
|
449
455
|
});
|
|
450
456
|
}
|
|
451
457
|
|
|
@@ -498,12 +504,14 @@ export async function sandboxUploadArchive(
|
|
|
498
504
|
const url = `/fs/${API_VERSION}/upload/${sandboxId}${queryString ? `?${queryString}` : ''}`;
|
|
499
505
|
|
|
500
506
|
const response = await client.rawPost(url, archive, 'application/octet-stream', signal);
|
|
507
|
+
const sessionId = response.headers.get('x-session-id');
|
|
501
508
|
|
|
502
509
|
if (!response.ok) {
|
|
503
510
|
const text = await response.text().catch(() => 'Unknown error');
|
|
504
511
|
throw new SandboxResponseError({
|
|
505
512
|
message: `Failed to upload archive: ${response.status} ${text}`,
|
|
506
513
|
sandboxId,
|
|
514
|
+
sessionId,
|
|
507
515
|
});
|
|
508
516
|
}
|
|
509
517
|
|
|
@@ -511,7 +519,7 @@ export async function sandboxUploadArchive(
|
|
|
511
519
|
const result = UploadArchiveResponseSchema.parse(body);
|
|
512
520
|
|
|
513
521
|
if (!result.success) {
|
|
514
|
-
throw new SandboxResponseError({ message: result.message, sandboxId });
|
|
522
|
+
throw new SandboxResponseError({ message: result.message, sandboxId, sessionId });
|
|
515
523
|
}
|
|
516
524
|
}
|
|
517
525
|
|
package/src/api/sandbox/get.ts
CHANGED
|
@@ -43,6 +43,7 @@ const SandboxOrgInfoSchema = z
|
|
|
43
43
|
const SandboxInfoDataSchema = z
|
|
44
44
|
.object({
|
|
45
45
|
sandboxId: z.string().describe('Unique identifier for the sandbox'),
|
|
46
|
+
identifier: z.string().optional().describe('Short identifier for DNS hostname'),
|
|
46
47
|
name: z.string().optional().describe('Sandbox name'),
|
|
47
48
|
description: z.string().optional().describe('Sandbox description'),
|
|
48
49
|
status: z
|
|
@@ -72,6 +73,11 @@ const SandboxInfoDataSchema = z
|
|
|
72
73
|
memoryByteSec: z.number().optional().describe('Total memory usage in byte-seconds'),
|
|
73
74
|
networkEgressBytes: z.number().optional().describe('Total network egress in bytes'),
|
|
74
75
|
networkEnabled: z.boolean().optional().describe('Whether network access is enabled'),
|
|
76
|
+
networkPort: z.number().optional().describe('Network port exposed from the sandbox'),
|
|
77
|
+
url: z
|
|
78
|
+
.string()
|
|
79
|
+
.optional()
|
|
80
|
+
.describe('Public URL for the sandbox (only set if networkPort is configured)'),
|
|
75
81
|
user: SandboxUserInfoSchema.optional().describe('User who created the sandbox'),
|
|
76
82
|
agent: SandboxAgentInfoSchema.optional().describe('Agent associated with the sandbox'),
|
|
77
83
|
project: SandboxProjectInfoSchema.optional().describe('Project associated with the sandbox'),
|
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
|
@@ -13,6 +13,7 @@ const SandboxOrgInfoSchema = z
|
|
|
13
13
|
const SandboxInfoSchema = z
|
|
14
14
|
.object({
|
|
15
15
|
sandboxId: z.string().describe('Unique identifier for the sandbox'),
|
|
16
|
+
identifier: z.string().optional().describe('Short identifier for DNS hostname'),
|
|
16
17
|
name: z.string().optional().describe('Sandbox name'),
|
|
17
18
|
description: z.string().optional().describe('Sandbox description'),
|
|
18
19
|
status: z
|
|
@@ -30,6 +31,11 @@ const SandboxInfoSchema = z
|
|
|
30
31
|
stdoutStreamUrl: z.string().optional().describe('URL for streaming stdout output'),
|
|
31
32
|
stderrStreamUrl: z.string().optional().describe('URL for streaming stderr output'),
|
|
32
33
|
networkEnabled: z.boolean().optional().describe('Whether network access is enabled'),
|
|
34
|
+
networkPort: z.number().optional().describe('Network port exposed from the sandbox'),
|
|
35
|
+
url: z
|
|
36
|
+
.string()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Public URL for the sandbox (only set if networkPort is configured)'),
|
|
33
39
|
org: SandboxOrgInfoSchema.describe('Organization associated with the sandbox'),
|
|
34
40
|
})
|
|
35
41
|
.describe('Summary information about a sandbox');
|
|
@@ -74,6 +80,9 @@ export async function sandboxList(
|
|
|
74
80
|
if (params?.status) {
|
|
75
81
|
queryParams.set('status', params.status);
|
|
76
82
|
}
|
|
83
|
+
if (params?.live !== undefined) {
|
|
84
|
+
queryParams.set('live', params.live.toString());
|
|
85
|
+
}
|
|
77
86
|
if (params?.limit !== undefined) {
|
|
78
87
|
queryParams.set('limit', params.limit.toString());
|
|
79
88
|
}
|
|
@@ -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>;
|