@pstdio/pocketcoder-sdk 0.5.0 → 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/index.d.ts +370 -190
- package/dist/index.js +497 -372
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,220 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { isIP } from "node:net";
|
|
3
|
-
//#region ../contracts/src/
|
|
3
|
+
//#region ../contracts/src/attachments/attachment.ts
|
|
4
|
+
const ATTACHMENT_MAX_FILE_BYTES = 26214400;
|
|
5
|
+
const ATTACHMENT_CHUNK_BYTES = 524288;
|
|
6
|
+
const AttachmentMediaTypeSchema = z.string().regex(/^[\w.+-]+\/[\w.+-]+$/).max(255);
|
|
7
|
+
const AttachmentDescriptorSchema = z.object({
|
|
8
|
+
id: z.uuid(),
|
|
9
|
+
name: z.string().min(1).max(255),
|
|
10
|
+
path: z.string().min(1),
|
|
11
|
+
media_type: AttachmentMediaTypeSchema,
|
|
12
|
+
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES),
|
|
13
|
+
sha256: z.string().regex(/^[0-9a-f]{64}$/)
|
|
14
|
+
});
|
|
15
|
+
z.looseObject({
|
|
16
|
+
type: z.literal("user"),
|
|
17
|
+
content: z.string(),
|
|
18
|
+
attachment_ids: z.array(z.uuid()).min(1).max(10).refine((ids) => new Set(ids).size === ids.length, "attachment_ids must be unique").optional()
|
|
19
|
+
});
|
|
20
|
+
const MANIFEST_OPEN = "<pocketcoder-attachments>";
|
|
21
|
+
const MANIFEST_CLOSE = "</pocketcoder-attachments>";
|
|
22
|
+
function splitAttachmentManifest(content) {
|
|
23
|
+
const open = content.lastIndexOf(MANIFEST_OPEN);
|
|
24
|
+
if (open < 0 || !content.trimEnd().endsWith(MANIFEST_CLOSE)) return {
|
|
25
|
+
text: content,
|
|
26
|
+
attachments: null
|
|
27
|
+
};
|
|
28
|
+
const close = content.lastIndexOf(MANIFEST_CLOSE);
|
|
29
|
+
const parsed = z.array(AttachmentDescriptorSchema).safeParse(safeJson(content.slice(open + 25, close)));
|
|
30
|
+
if (!parsed.success) return {
|
|
31
|
+
text: content,
|
|
32
|
+
attachments: null
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
text: content.slice(0, open).trimEnd(),
|
|
36
|
+
attachments: parsed.data
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function safeJson(value) {
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(value);
|
|
42
|
+
} catch {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const AttachmentStartPayload = z.object({
|
|
47
|
+
operation_id: z.uuid(),
|
|
48
|
+
attachment_id: z.uuid(),
|
|
49
|
+
name: z.string().min(1).max(255),
|
|
50
|
+
media_type: AttachmentMediaTypeSchema,
|
|
51
|
+
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES)
|
|
52
|
+
});
|
|
53
|
+
const AttachmentChunkPayload = z.object({
|
|
54
|
+
operation_id: z.uuid(),
|
|
55
|
+
seq: z.number().int().nonnegative(),
|
|
56
|
+
content_b64: z.string().max(Math.ceil(ATTACHMENT_CHUNK_BYTES / 3) * 4 + 4)
|
|
57
|
+
});
|
|
58
|
+
const AttachmentFinishPayload = z.object({ operation_id: z.uuid() });
|
|
59
|
+
const AttachmentAbortPayload = z.object({
|
|
60
|
+
operation_id: z.uuid(),
|
|
61
|
+
reason: z.string().max(512)
|
|
62
|
+
});
|
|
63
|
+
const AttachmentResolvePayload = z.object({
|
|
64
|
+
operation_id: z.uuid(),
|
|
65
|
+
attachment_ids: z.array(z.uuid()).min(1).max(10)
|
|
66
|
+
});
|
|
67
|
+
const AttachmentAckPayload = z.object({
|
|
68
|
+
operation_id: z.uuid(),
|
|
69
|
+
seq: z.number().int().nonnegative(),
|
|
70
|
+
received_bytes: z.number().int().nonnegative()
|
|
71
|
+
});
|
|
72
|
+
const AttachmentResultPayload = z.object({
|
|
73
|
+
operation_id: z.uuid(),
|
|
74
|
+
status: z.enum([
|
|
75
|
+
"created",
|
|
76
|
+
"existing",
|
|
77
|
+
"conflict",
|
|
78
|
+
"failed"
|
|
79
|
+
]),
|
|
80
|
+
descriptor: AttachmentDescriptorSchema.optional(),
|
|
81
|
+
failure_code: z.enum([
|
|
82
|
+
"invalid",
|
|
83
|
+
"too_large",
|
|
84
|
+
"sequence",
|
|
85
|
+
"io",
|
|
86
|
+
"interrupted"
|
|
87
|
+
]).optional(),
|
|
88
|
+
detail: z.string().max(512).optional()
|
|
89
|
+
});
|
|
90
|
+
const AttachmentResolvedPayload = z.object({
|
|
91
|
+
operation_id: z.uuid(),
|
|
92
|
+
descriptors: z.array(AttachmentDescriptorSchema).optional(),
|
|
93
|
+
missing_id: z.uuid().optional()
|
|
94
|
+
});
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region ../contracts/src/common/scopes.ts
|
|
97
|
+
const SCOPES = [
|
|
98
|
+
"templates:read",
|
|
99
|
+
"workspaces:create",
|
|
100
|
+
"workspaces:read",
|
|
101
|
+
"workspaces:cancel",
|
|
102
|
+
"workspaces:purge",
|
|
103
|
+
"workspaces:recover",
|
|
104
|
+
"keys:read",
|
|
105
|
+
"keys:write",
|
|
106
|
+
"workspaces:preserve",
|
|
107
|
+
"workspaces:restore",
|
|
108
|
+
"checkpoints:read",
|
|
109
|
+
"checkpoints:delete",
|
|
110
|
+
"outputs:read",
|
|
111
|
+
"conversations:read",
|
|
112
|
+
"conversations:delete",
|
|
113
|
+
"services:relay",
|
|
114
|
+
"attachments:write",
|
|
115
|
+
"logs:read",
|
|
116
|
+
"network:read",
|
|
117
|
+
"terminal:attach",
|
|
118
|
+
"terminal:read",
|
|
119
|
+
"admin"
|
|
120
|
+
];
|
|
121
|
+
z.strictObject({
|
|
122
|
+
request_id: z.string().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/),
|
|
123
|
+
scopes: z.array(z.enum(SCOPES)).min(1).max(SCOPES.length),
|
|
124
|
+
expires_at: z.iso.datetime()
|
|
125
|
+
});
|
|
126
|
+
const KeyResourceSchema = z.object({
|
|
127
|
+
id: z.uuid(),
|
|
128
|
+
principal_id: z.uuid(),
|
|
129
|
+
scopes: z.array(z.string()),
|
|
130
|
+
effective_scopes: z.array(z.string()),
|
|
131
|
+
managed_principal_ids: z.array(z.uuid()),
|
|
132
|
+
issuance_request_id: z.string().nullable(),
|
|
133
|
+
created_at: z.iso.datetime(),
|
|
134
|
+
expires_at: z.iso.datetime().nullable(),
|
|
135
|
+
revoked_at: z.iso.datetime().nullable(),
|
|
136
|
+
last_used_at: z.iso.datetime().nullable()
|
|
137
|
+
});
|
|
138
|
+
const KeyIssueResponseSchema = z.object({
|
|
139
|
+
key: KeyResourceSchema,
|
|
140
|
+
token: z.string().nullable()
|
|
141
|
+
});
|
|
142
|
+
const KeyListResponseSchema = z.object({
|
|
143
|
+
items: z.array(KeyResourceSchema),
|
|
144
|
+
next_cursor: z.uuid().nullable()
|
|
145
|
+
});
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region ../contracts/src/common/duration.ts
|
|
148
|
+
const DURATION_RE = /^(\d+)(ms|s|m|h)$/;
|
|
149
|
+
function isDuration(value) {
|
|
150
|
+
return DURATION_RE.test(value);
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region ../contracts/src/common/errors.ts
|
|
154
|
+
const ERROR_CODES = {
|
|
155
|
+
"auth.invalid_key": 401,
|
|
156
|
+
"auth.missing_scope": 403,
|
|
157
|
+
"auth.disabled_principal": 403,
|
|
158
|
+
"principal.not_found": 404,
|
|
159
|
+
"key.not_found": 404,
|
|
160
|
+
"validation.invalid": 400,
|
|
161
|
+
"idempotency.conflict": 409,
|
|
162
|
+
"capacity.queue_full": 429,
|
|
163
|
+
"capacity.waiters_full": 429,
|
|
164
|
+
"template.not_found": 404,
|
|
165
|
+
"template.version_not_found": 404,
|
|
166
|
+
"template.not_authorized": 403,
|
|
167
|
+
"workspace.not_found": 404,
|
|
168
|
+
"workspace.external_id_conflict": 409,
|
|
169
|
+
"workspace.not_ready": 409,
|
|
170
|
+
"workspace.terminal": 410,
|
|
171
|
+
"workspace.disconnected": 503,
|
|
172
|
+
"terminal.not_declared": 422,
|
|
173
|
+
"terminal.session_limit": 409,
|
|
174
|
+
"terminal.session_not_found": 404,
|
|
175
|
+
"terminal.session_closed": 409,
|
|
176
|
+
"terminal.protocol_unsupported": 426,
|
|
177
|
+
"workspace.persistence_not_enabled": 409,
|
|
178
|
+
"workspace.preserving": 409,
|
|
179
|
+
"checkpoint.not_found": 404,
|
|
180
|
+
"checkpoint.not_ready": 409,
|
|
181
|
+
"checkpoint.none_ready": 409,
|
|
182
|
+
"checkpoint.corrupt": 409,
|
|
183
|
+
"checkpoint.quota_exceeded": 413,
|
|
184
|
+
"checkpoint.in_use": 409,
|
|
185
|
+
"restore.template_not_authorized": 403,
|
|
186
|
+
"restore.image_unavailable": 409,
|
|
187
|
+
"restore.incompatible": 409,
|
|
188
|
+
"resume.unsupported": 409,
|
|
189
|
+
"conversation.expired": 410,
|
|
190
|
+
"conversation.deleted": 410,
|
|
191
|
+
"operation.conflict": 409,
|
|
192
|
+
"source.not_allowed": 422,
|
|
193
|
+
"source.invalid_revision": 422,
|
|
194
|
+
"secret.unavailable": 503,
|
|
195
|
+
"storage.capacity_exhausted": 507,
|
|
196
|
+
"relay.body_too_large": 413,
|
|
197
|
+
"relay.route_not_allowed": 422,
|
|
198
|
+
"relay.streaming_unsupported": 409,
|
|
199
|
+
"relay.deadline_exceeded": 504,
|
|
200
|
+
"relay.upstream_error": 502,
|
|
201
|
+
"attachment.invalid": 400,
|
|
202
|
+
"attachment.too_large": 413,
|
|
203
|
+
"attachment.not_found": 404,
|
|
204
|
+
"attachment.conflict": 409,
|
|
205
|
+
"attachment.unsupported": 409,
|
|
206
|
+
"attachment.interrupted": 503,
|
|
207
|
+
"internal.error": 500
|
|
208
|
+
};
|
|
209
|
+
const errorCodes = Object.keys(ERROR_CODES);
|
|
210
|
+
const ErrorEnvelopeSchema = z.object({ error: z.object({
|
|
211
|
+
code: z.enum(errorCodes),
|
|
212
|
+
message: z.string().min(1),
|
|
213
|
+
request_id: z.string().min(1),
|
|
214
|
+
details: z.record(z.string(), z.unknown()).optional()
|
|
215
|
+
}) });
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region ../contracts/src/common/pagination.ts
|
|
4
218
|
const CursorSchema = z.string().min(1).max(2048);
|
|
5
219
|
function CursorPageSchema(item) {
|
|
6
220
|
return z.object({
|
|
@@ -15,7 +229,7 @@ function CursorQuerySchema(maxLimit, defaultLimit) {
|
|
|
15
229
|
});
|
|
16
230
|
}
|
|
17
231
|
//#endregion
|
|
18
|
-
//#region ../contracts/src/conversation.ts
|
|
232
|
+
//#region ../contracts/src/conversations/conversation.ts
|
|
19
233
|
const CONVERSATION_ROLES = [
|
|
20
234
|
"user",
|
|
21
235
|
"assistant",
|
|
@@ -43,13 +257,61 @@ const ConversationResumeOutcomeSchema = z.object({
|
|
|
43
257
|
checkpoint_id: z.uuid()
|
|
44
258
|
});
|
|
45
259
|
//#endregion
|
|
46
|
-
//#region ../contracts/src/
|
|
47
|
-
const
|
|
48
|
-
function
|
|
49
|
-
|
|
260
|
+
//#region ../contracts/src/network/network.ts
|
|
261
|
+
const DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
262
|
+
function isDomain(value) {
|
|
263
|
+
const domain = value.startsWith("*.") ? value.slice(2) : value;
|
|
264
|
+
return domain.length <= 253 && !domain.endsWith(".") && isIP(domain) === 0 && domain.split(".").length >= 2 && domain.split(".").every((label) => DOMAIN_LABEL.test(label));
|
|
50
265
|
}
|
|
266
|
+
const NetworkRuleSchema = z.object({
|
|
267
|
+
domain: z.string().refine(isDomain, "expected a lowercase ASCII domain or leading *. wildcard"),
|
|
268
|
+
ports: z.array(z.number().int().min(1).max(65535)).min(1).max(32).default([80, 443]),
|
|
269
|
+
allowPrivate: z.boolean().default(false)
|
|
270
|
+
}).superRefine((rule, ctx) => {
|
|
271
|
+
if (new Set(rule.ports).size !== rule.ports.length) ctx.addIssue({
|
|
272
|
+
code: "custom",
|
|
273
|
+
path: ["ports"],
|
|
274
|
+
message: "ports must be unique"
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
const UnrestrictedNetworkPolicySchema = z.object({ mode: z.literal("unrestricted") });
|
|
278
|
+
const RestrictedNetworkPolicySchema = z.object({
|
|
279
|
+
mode: z.literal("restricted"),
|
|
280
|
+
allow: z.array(NetworkRuleSchema).max(256).default([])
|
|
281
|
+
});
|
|
282
|
+
const NetworkPolicySchema = z.preprocess((value) => value ?? { mode: "unrestricted" }, z.discriminatedUnion("mode", [UnrestrictedNetworkPolicySchema, RestrictedNetworkPolicySchema]));
|
|
283
|
+
const NETWORK_STATES = [
|
|
284
|
+
"disabled",
|
|
285
|
+
"starting",
|
|
286
|
+
"ready",
|
|
287
|
+
"degraded"
|
|
288
|
+
];
|
|
289
|
+
const NetworkEventInputSchema = z.object({
|
|
290
|
+
source_seq: z.number().int().positive(),
|
|
291
|
+
occurred_at: z.iso.datetime(),
|
|
292
|
+
decision: z.enum(["allow", "deny"]),
|
|
293
|
+
transport: z.enum(["http", "https"]),
|
|
294
|
+
host: z.string().min(1).max(253),
|
|
295
|
+
port: z.number().int().min(1).max(65535),
|
|
296
|
+
method: z.string().max(32).nullable().default(null),
|
|
297
|
+
path: z.string().max(2048).refine((path) => !path.includes("?") && !path.includes("#"), "path cannot contain query or fragment").nullable().default(null),
|
|
298
|
+
matched_rule: z.string().max(512).nullable().default(null),
|
|
299
|
+
reason: z.string().min(1).max(128)
|
|
300
|
+
});
|
|
301
|
+
z.object({
|
|
302
|
+
source_session_id: z.uuid(),
|
|
303
|
+
events: z.array(NetworkEventInputSchema).min(1).max(100)
|
|
304
|
+
});
|
|
305
|
+
const NetworkEventSchema = NetworkEventInputSchema.omit({ source_seq: true }).extend({
|
|
306
|
+
seq: z.number().int().positive(),
|
|
307
|
+
workspace_id: z.uuid(),
|
|
308
|
+
source_session_id: z.uuid(),
|
|
309
|
+
source_seq: z.number().int().positive()
|
|
310
|
+
});
|
|
311
|
+
CursorQuerySchema(200, 100);
|
|
312
|
+
const NetworkEventPageSchema = CursorPageSchema(NetworkEventSchema);
|
|
51
313
|
//#endregion
|
|
52
|
-
//#region ../contracts/src/persistence.ts
|
|
314
|
+
//#region ../contracts/src/persistence/persistence.ts
|
|
53
315
|
const DurationValueSchema = z.string().refine(isDuration, { message: "expected a duration like 15s, 20m, or 2h" });
|
|
54
316
|
const LAUNCH_MODES = ["create", "restore"];
|
|
55
317
|
const CONVERSATION_RESTORE_CAPABILITIES = [
|
|
@@ -117,7 +379,8 @@ const OPERATION_KINDS = [
|
|
|
117
379
|
"preserve",
|
|
118
380
|
"restore",
|
|
119
381
|
"verify",
|
|
120
|
-
"delete"
|
|
382
|
+
"delete",
|
|
383
|
+
"purge"
|
|
121
384
|
];
|
|
122
385
|
const OPERATION_STATES = [
|
|
123
386
|
"pending",
|
|
@@ -194,61 +457,7 @@ z.object({
|
|
|
194
457
|
file_count: z.number().int().nonnegative()
|
|
195
458
|
});
|
|
196
459
|
//#endregion
|
|
197
|
-
//#region ../contracts/src/
|
|
198
|
-
const DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
199
|
-
function isDomain(value) {
|
|
200
|
-
const domain = value.startsWith("*.") ? value.slice(2) : value;
|
|
201
|
-
return domain.length <= 253 && !domain.endsWith(".") && isIP(domain) === 0 && domain.split(".").length >= 2 && domain.split(".").every((label) => DOMAIN_LABEL.test(label));
|
|
202
|
-
}
|
|
203
|
-
const NetworkRuleSchema = z.object({
|
|
204
|
-
domain: z.string().refine(isDomain, "expected a lowercase ASCII domain or leading *. wildcard"),
|
|
205
|
-
ports: z.array(z.number().int().min(1).max(65535)).min(1).max(32).default([80, 443]),
|
|
206
|
-
allowPrivate: z.boolean().default(false)
|
|
207
|
-
}).superRefine((rule, ctx) => {
|
|
208
|
-
if (new Set(rule.ports).size !== rule.ports.length) ctx.addIssue({
|
|
209
|
-
code: "custom",
|
|
210
|
-
path: ["ports"],
|
|
211
|
-
message: "ports must be unique"
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
const UnrestrictedNetworkPolicySchema = z.object({ mode: z.literal("unrestricted") });
|
|
215
|
-
const RestrictedNetworkPolicySchema = z.object({
|
|
216
|
-
mode: z.literal("restricted"),
|
|
217
|
-
allow: z.array(NetworkRuleSchema).max(256).default([])
|
|
218
|
-
});
|
|
219
|
-
const NetworkPolicySchema = z.preprocess((value) => value ?? { mode: "unrestricted" }, z.discriminatedUnion("mode", [UnrestrictedNetworkPolicySchema, RestrictedNetworkPolicySchema]));
|
|
220
|
-
const NETWORK_STATES = [
|
|
221
|
-
"disabled",
|
|
222
|
-
"starting",
|
|
223
|
-
"ready",
|
|
224
|
-
"degraded"
|
|
225
|
-
];
|
|
226
|
-
const NetworkEventInputSchema = z.object({
|
|
227
|
-
source_seq: z.number().int().positive(),
|
|
228
|
-
occurred_at: z.iso.datetime(),
|
|
229
|
-
decision: z.enum(["allow", "deny"]),
|
|
230
|
-
transport: z.enum(["http", "https"]),
|
|
231
|
-
host: z.string().min(1).max(253),
|
|
232
|
-
port: z.number().int().min(1).max(65535),
|
|
233
|
-
method: z.string().max(32).nullable().default(null),
|
|
234
|
-
path: z.string().max(2048).refine((path) => !path.includes("?") && !path.includes("#"), "path cannot contain query or fragment").nullable().default(null),
|
|
235
|
-
matched_rule: z.string().max(512).nullable().default(null),
|
|
236
|
-
reason: z.string().min(1).max(128)
|
|
237
|
-
});
|
|
238
|
-
z.object({
|
|
239
|
-
source_session_id: z.uuid(),
|
|
240
|
-
events: z.array(NetworkEventInputSchema).min(1).max(100)
|
|
241
|
-
});
|
|
242
|
-
const NetworkEventSchema = NetworkEventInputSchema.omit({ source_seq: true }).extend({
|
|
243
|
-
seq: z.number().int().positive(),
|
|
244
|
-
workspace_id: z.uuid(),
|
|
245
|
-
source_session_id: z.uuid(),
|
|
246
|
-
source_seq: z.number().int().positive()
|
|
247
|
-
});
|
|
248
|
-
CursorQuerySchema(200, 100);
|
|
249
|
-
const NetworkEventPageSchema = CursorPageSchema(NetworkEventSchema);
|
|
250
|
-
//#endregion
|
|
251
|
-
//#region ../contracts/src/workspace.ts
|
|
460
|
+
//#region ../contracts/src/workspaces/workspace.ts
|
|
252
461
|
const WORKSPACE_STATES = [
|
|
253
462
|
"queued",
|
|
254
463
|
"provisioning",
|
|
@@ -377,7 +586,7 @@ z.object({
|
|
|
377
586
|
cursor: z.string().optional()
|
|
378
587
|
});
|
|
379
588
|
//#endregion
|
|
380
|
-
//#region ../contracts/src/api.ts
|
|
589
|
+
//#region ../contracts/src/protocol/api.ts
|
|
381
590
|
const TemplatePageSchema = CursorPageSchema(z.object({
|
|
382
591
|
name: z.string(),
|
|
383
592
|
version: z.string(),
|
|
@@ -438,161 +647,6 @@ const StoragePruneResultSchema = z.object({
|
|
|
438
647
|
skipped: z.number().int().nonnegative(),
|
|
439
648
|
transcripts_deleted: z.number().int().nonnegative()
|
|
440
649
|
});
|
|
441
|
-
//#endregion
|
|
442
|
-
//#region ../contracts/src/attachment.ts
|
|
443
|
-
const ATTACHMENT_MAX_FILE_BYTES = 26214400;
|
|
444
|
-
const ATTACHMENT_CHUNK_BYTES = 524288;
|
|
445
|
-
const AttachmentMediaTypeSchema = z.string().regex(/^[\w.+-]+\/[\w.+-]+$/).max(255);
|
|
446
|
-
const AttachmentDescriptorSchema = z.object({
|
|
447
|
-
id: z.uuid(),
|
|
448
|
-
name: z.string().min(1).max(255),
|
|
449
|
-
path: z.string().min(1),
|
|
450
|
-
media_type: AttachmentMediaTypeSchema,
|
|
451
|
-
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES),
|
|
452
|
-
sha256: z.string().regex(/^[0-9a-f]{64}$/)
|
|
453
|
-
});
|
|
454
|
-
z.looseObject({
|
|
455
|
-
type: z.literal("user"),
|
|
456
|
-
content: z.string(),
|
|
457
|
-
attachment_ids: z.array(z.uuid()).min(1).max(10).refine((ids) => new Set(ids).size === ids.length, "attachment_ids must be unique").optional()
|
|
458
|
-
});
|
|
459
|
-
const MANIFEST_OPEN = "<pocketcoder-attachments>";
|
|
460
|
-
const MANIFEST_CLOSE = "</pocketcoder-attachments>";
|
|
461
|
-
function splitAttachmentManifest(content) {
|
|
462
|
-
const open = content.lastIndexOf(MANIFEST_OPEN);
|
|
463
|
-
if (open < 0 || !content.trimEnd().endsWith(MANIFEST_CLOSE)) return {
|
|
464
|
-
text: content,
|
|
465
|
-
attachments: null
|
|
466
|
-
};
|
|
467
|
-
const close = content.lastIndexOf(MANIFEST_CLOSE);
|
|
468
|
-
const parsed = z.array(AttachmentDescriptorSchema).safeParse(safeJson(content.slice(open + 25, close)));
|
|
469
|
-
if (!parsed.success) return {
|
|
470
|
-
text: content,
|
|
471
|
-
attachments: null
|
|
472
|
-
};
|
|
473
|
-
return {
|
|
474
|
-
text: content.slice(0, open).trimEnd(),
|
|
475
|
-
attachments: parsed.data
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
function safeJson(value) {
|
|
479
|
-
try {
|
|
480
|
-
return JSON.parse(value);
|
|
481
|
-
} catch {
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
const AttachmentStartPayload = z.object({
|
|
486
|
-
operation_id: z.uuid(),
|
|
487
|
-
attachment_id: z.uuid(),
|
|
488
|
-
name: z.string().min(1).max(255),
|
|
489
|
-
media_type: AttachmentMediaTypeSchema,
|
|
490
|
-
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES)
|
|
491
|
-
});
|
|
492
|
-
const AttachmentChunkPayload = z.object({
|
|
493
|
-
operation_id: z.uuid(),
|
|
494
|
-
seq: z.number().int().nonnegative(),
|
|
495
|
-
content_b64: z.string().max(Math.ceil(ATTACHMENT_CHUNK_BYTES / 3) * 4 + 4)
|
|
496
|
-
});
|
|
497
|
-
const AttachmentFinishPayload = z.object({ operation_id: z.uuid() });
|
|
498
|
-
const AttachmentAbortPayload = z.object({
|
|
499
|
-
operation_id: z.uuid(),
|
|
500
|
-
reason: z.string().max(512)
|
|
501
|
-
});
|
|
502
|
-
const AttachmentResolvePayload = z.object({
|
|
503
|
-
operation_id: z.uuid(),
|
|
504
|
-
attachment_ids: z.array(z.uuid()).min(1).max(10)
|
|
505
|
-
});
|
|
506
|
-
const AttachmentAckPayload = z.object({
|
|
507
|
-
operation_id: z.uuid(),
|
|
508
|
-
seq: z.number().int().nonnegative(),
|
|
509
|
-
received_bytes: z.number().int().nonnegative()
|
|
510
|
-
});
|
|
511
|
-
const AttachmentResultPayload = z.object({
|
|
512
|
-
operation_id: z.uuid(),
|
|
513
|
-
status: z.enum([
|
|
514
|
-
"created",
|
|
515
|
-
"existing",
|
|
516
|
-
"conflict",
|
|
517
|
-
"failed"
|
|
518
|
-
]),
|
|
519
|
-
descriptor: AttachmentDescriptorSchema.optional(),
|
|
520
|
-
failure_code: z.enum([
|
|
521
|
-
"invalid",
|
|
522
|
-
"too_large",
|
|
523
|
-
"sequence",
|
|
524
|
-
"io",
|
|
525
|
-
"interrupted"
|
|
526
|
-
]).optional(),
|
|
527
|
-
detail: z.string().max(512).optional()
|
|
528
|
-
});
|
|
529
|
-
const AttachmentResolvedPayload = z.object({
|
|
530
|
-
operation_id: z.uuid(),
|
|
531
|
-
descriptors: z.array(AttachmentDescriptorSchema).optional(),
|
|
532
|
-
missing_id: z.uuid().optional()
|
|
533
|
-
});
|
|
534
|
-
//#endregion
|
|
535
|
-
//#region ../contracts/src/errors.ts
|
|
536
|
-
const ERROR_CODES = {
|
|
537
|
-
"auth.invalid_key": 401,
|
|
538
|
-
"auth.missing_scope": 403,
|
|
539
|
-
"auth.disabled_principal": 403,
|
|
540
|
-
"validation.invalid": 400,
|
|
541
|
-
"idempotency.conflict": 409,
|
|
542
|
-
"capacity.queue_full": 429,
|
|
543
|
-
"capacity.waiters_full": 429,
|
|
544
|
-
"template.not_found": 404,
|
|
545
|
-
"template.version_not_found": 404,
|
|
546
|
-
"template.not_authorized": 403,
|
|
547
|
-
"workspace.not_found": 404,
|
|
548
|
-
"workspace.external_id_conflict": 409,
|
|
549
|
-
"workspace.not_ready": 409,
|
|
550
|
-
"workspace.terminal": 410,
|
|
551
|
-
"workspace.disconnected": 503,
|
|
552
|
-
"terminal.not_declared": 422,
|
|
553
|
-
"terminal.session_limit": 409,
|
|
554
|
-
"terminal.session_not_found": 404,
|
|
555
|
-
"terminal.session_closed": 409,
|
|
556
|
-
"terminal.protocol_unsupported": 426,
|
|
557
|
-
"workspace.persistence_not_enabled": 409,
|
|
558
|
-
"workspace.preserving": 409,
|
|
559
|
-
"checkpoint.not_found": 404,
|
|
560
|
-
"checkpoint.not_ready": 409,
|
|
561
|
-
"checkpoint.none_ready": 409,
|
|
562
|
-
"checkpoint.corrupt": 409,
|
|
563
|
-
"checkpoint.quota_exceeded": 413,
|
|
564
|
-
"checkpoint.in_use": 409,
|
|
565
|
-
"restore.template_not_authorized": 403,
|
|
566
|
-
"restore.image_unavailable": 409,
|
|
567
|
-
"restore.incompatible": 409,
|
|
568
|
-
"resume.unsupported": 409,
|
|
569
|
-
"conversation.expired": 410,
|
|
570
|
-
"conversation.deleted": 410,
|
|
571
|
-
"operation.conflict": 409,
|
|
572
|
-
"source.not_allowed": 422,
|
|
573
|
-
"source.invalid_revision": 422,
|
|
574
|
-
"secret.unavailable": 503,
|
|
575
|
-
"storage.capacity_exhausted": 507,
|
|
576
|
-
"relay.body_too_large": 413,
|
|
577
|
-
"relay.route_not_allowed": 422,
|
|
578
|
-
"relay.streaming_unsupported": 409,
|
|
579
|
-
"relay.deadline_exceeded": 504,
|
|
580
|
-
"relay.upstream_error": 502,
|
|
581
|
-
"attachment.invalid": 400,
|
|
582
|
-
"attachment.too_large": 413,
|
|
583
|
-
"attachment.not_found": 404,
|
|
584
|
-
"attachment.conflict": 409,
|
|
585
|
-
"attachment.unsupported": 409,
|
|
586
|
-
"attachment.interrupted": 503,
|
|
587
|
-
"internal.error": 500
|
|
588
|
-
};
|
|
589
|
-
const errorCodes = Object.keys(ERROR_CODES);
|
|
590
|
-
const ErrorEnvelopeSchema = z.object({ error: z.object({
|
|
591
|
-
code: z.enum(errorCodes),
|
|
592
|
-
message: z.string().min(1),
|
|
593
|
-
request_id: z.string().min(1),
|
|
594
|
-
details: z.record(z.string(), z.unknown()).optional()
|
|
595
|
-
}) });
|
|
596
650
|
WORKSPACE_STATES.map((s) => `workspace.${s}`);
|
|
597
651
|
z.object({
|
|
598
652
|
id: z.uuid(),
|
|
@@ -624,7 +678,7 @@ z.object({
|
|
|
624
678
|
})
|
|
625
679
|
});
|
|
626
680
|
//#endregion
|
|
627
|
-
//#region ../contracts/src/logs.ts
|
|
681
|
+
//#region ../contracts/src/protocol/logs.ts
|
|
628
682
|
const LogChunkSchema = z.object({
|
|
629
683
|
seq: z.number().int().positive(),
|
|
630
684
|
stream: z.string(),
|
|
@@ -634,47 +688,14 @@ const LogChunkSchema = z.object({
|
|
|
634
688
|
CursorQuerySchema(1e3, 200);
|
|
635
689
|
const LogPageSchema = CursorPageSchema(LogChunkSchema);
|
|
636
690
|
//#endregion
|
|
637
|
-
//#region ../contracts/src/
|
|
638
|
-
const ProxyStreamStartPayload = z.object({
|
|
639
|
-
request_id: z.uuid(),
|
|
640
|
-
status: z.number().int().min(100).max(599),
|
|
641
|
-
headers: z.record(z.string(), z.string())
|
|
642
|
-
});
|
|
643
|
-
const ProxyStreamChunkPayload = z.object({
|
|
644
|
-
request_id: z.uuid(),
|
|
645
|
-
seq: z.number().int().nonnegative(),
|
|
646
|
-
content_b64: z.string().max(87400)
|
|
647
|
-
});
|
|
648
|
-
const ProxyStreamEndPayload = z.object({
|
|
649
|
-
request_id: z.uuid(),
|
|
650
|
-
error_code: z.enum([
|
|
651
|
-
"unreachable",
|
|
652
|
-
"deadline",
|
|
653
|
-
"too_large"
|
|
654
|
-
]).optional()
|
|
655
|
-
});
|
|
656
|
-
const ProxyStreamAckPayload = z.object({
|
|
657
|
-
request_id: z.uuid(),
|
|
658
|
-
seq: z.number().int().nonnegative()
|
|
659
|
-
});
|
|
660
|
-
const ProxyStreamCancelPayload = z.object({
|
|
661
|
-
request_id: z.uuid(),
|
|
662
|
-
reason: z.enum([
|
|
663
|
-
"downstream_closed",
|
|
664
|
-
"deadline",
|
|
665
|
-
"too_large",
|
|
666
|
-
"workspace_disconnected"
|
|
667
|
-
])
|
|
668
|
-
});
|
|
669
|
-
//#endregion
|
|
670
|
-
//#region ../contracts/src/template-constants.ts
|
|
691
|
+
//#region ../contracts/src/templates/template-constants.ts
|
|
671
692
|
function isAbsolutePath(value) {
|
|
672
693
|
return value.startsWith("/") && ![...value].some((character) => character.codePointAt(0) === 0);
|
|
673
694
|
}
|
|
674
695
|
const SECRET_ENV_PATTERN = /(SECRET|TOKEN|PASSWORD|PASSWD|API_?KEY|PRIVATE_?KEY|CREDENTIAL)/i;
|
|
675
696
|
const SECRET_REFERENCE_PREFIX = "secretRef:";
|
|
676
697
|
//#endregion
|
|
677
|
-
//#region ../contracts/src/template-schema.ts
|
|
698
|
+
//#region ../contracts/src/templates/template-schema.ts
|
|
678
699
|
const NAME_RE = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
679
700
|
const SEMVER_RE = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;
|
|
680
701
|
const IMAGE_DIGEST_RE = /^[^\s@]+@sha256:[0-9a-f]{64}$/;
|
|
@@ -864,7 +885,7 @@ const TemplateManifestBaseSchema = z.object({
|
|
|
864
885
|
spec: TemplateSpecSchema
|
|
865
886
|
});
|
|
866
887
|
//#endregion
|
|
867
|
-
//#region ../contracts/src/template-runtime.ts
|
|
888
|
+
//#region ../contracts/src/templates/template-runtime.ts
|
|
868
889
|
const LEGACY_AGENTAPI_SERVICE = ServiceSchema.parse({
|
|
869
890
|
baseUrl: "http://127.0.0.1:3284",
|
|
870
891
|
routes: [
|
|
@@ -920,7 +941,7 @@ function templateServices(spec) {
|
|
|
920
941
|
return isAgentApiNative(spec) ? { agent: AGENTAPI_SERVICE } : spec.services;
|
|
921
942
|
}
|
|
922
943
|
//#endregion
|
|
923
|
-
//#region ../contracts/src/template-validation.ts
|
|
944
|
+
//#region ../contracts/src/templates/template-validation.ts
|
|
924
945
|
function envSources(spec) {
|
|
925
946
|
const sources = [[["spec", "env"], spec.env], [isAgentApiNative(spec) ? [
|
|
926
947
|
"spec",
|
|
@@ -1259,12 +1280,14 @@ TemplateManifestBaseSchema.superRefine((manifest, ctx) => {
|
|
|
1259
1280
|
validateTemplateSpec(manifest.spec, ctx);
|
|
1260
1281
|
});
|
|
1261
1282
|
//#endregion
|
|
1262
|
-
//#region ../contracts/src/terminal.ts
|
|
1283
|
+
//#region ../contracts/src/terminals/terminal.ts
|
|
1263
1284
|
const TERMINAL_CHUNK_BYTES = 32768;
|
|
1264
1285
|
const TERMINAL_REPLAY_BUFFER_BYTES = 65536;
|
|
1265
1286
|
function base64Schema(maxBytes) {
|
|
1266
1287
|
return z.string().regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/).refine((value) => {
|
|
1267
|
-
|
|
1288
|
+
let padding = 0;
|
|
1289
|
+
if (value.endsWith("==")) padding = 2;
|
|
1290
|
+
else if (value.endsWith("=")) padding = 1;
|
|
1268
1291
|
return value.length / 4 * 3 - padding <= maxBytes;
|
|
1269
1292
|
}, `decoded payload must not exceed ${maxBytes} bytes`);
|
|
1270
1293
|
}
|
|
@@ -1368,8 +1391,41 @@ const TerminalSessionSchema = z.object({
|
|
|
1368
1391
|
bytes_in: z.number().int().nonnegative(),
|
|
1369
1392
|
bytes_out: z.number().int().nonnegative()
|
|
1370
1393
|
});
|
|
1371
|
-
CursorQuerySchema(200, 50);
|
|
1372
|
-
const TerminalSessionPageSchema = CursorPageSchema(TerminalSessionSchema);
|
|
1394
|
+
CursorQuerySchema(200, 50);
|
|
1395
|
+
const TerminalSessionPageSchema = CursorPageSchema(TerminalSessionSchema);
|
|
1396
|
+
//#endregion
|
|
1397
|
+
//#region ../contracts/src/protocol/protocol-stream.ts
|
|
1398
|
+
const ProxyStreamStartPayload = z.object({
|
|
1399
|
+
request_id: z.uuid(),
|
|
1400
|
+
status: z.number().int().min(100).max(599),
|
|
1401
|
+
headers: z.record(z.string(), z.string())
|
|
1402
|
+
});
|
|
1403
|
+
const ProxyStreamChunkPayload = z.object({
|
|
1404
|
+
request_id: z.uuid(),
|
|
1405
|
+
seq: z.number().int().nonnegative(),
|
|
1406
|
+
content_b64: z.string().max(87400)
|
|
1407
|
+
});
|
|
1408
|
+
const ProxyStreamEndPayload = z.object({
|
|
1409
|
+
request_id: z.uuid(),
|
|
1410
|
+
error_code: z.enum([
|
|
1411
|
+
"unreachable",
|
|
1412
|
+
"deadline",
|
|
1413
|
+
"too_large"
|
|
1414
|
+
]).optional()
|
|
1415
|
+
});
|
|
1416
|
+
const ProxyStreamAckPayload = z.object({
|
|
1417
|
+
request_id: z.uuid(),
|
|
1418
|
+
seq: z.number().int().nonnegative()
|
|
1419
|
+
});
|
|
1420
|
+
const ProxyStreamCancelPayload = z.object({
|
|
1421
|
+
request_id: z.uuid(),
|
|
1422
|
+
reason: z.enum([
|
|
1423
|
+
"downstream_closed",
|
|
1424
|
+
"deadline",
|
|
1425
|
+
"too_large",
|
|
1426
|
+
"workspace_disconnected"
|
|
1427
|
+
])
|
|
1428
|
+
});
|
|
1373
1429
|
const ProviderInputSchema = z.object({
|
|
1374
1430
|
workspace_id: z.uuid(),
|
|
1375
1431
|
server_url: z.string(),
|
|
@@ -1779,7 +1835,7 @@ z.discriminatedUnion("type", [
|
|
|
1779
1835
|
})
|
|
1780
1836
|
]);
|
|
1781
1837
|
//#endregion
|
|
1782
|
-
//#region src/admin.ts
|
|
1838
|
+
//#region src/resources/admin/admin.ts
|
|
1783
1839
|
var AdministrationApi = class {
|
|
1784
1840
|
transport;
|
|
1785
1841
|
constructor(transport) {
|
|
@@ -1799,7 +1855,7 @@ var AdministrationApi = class {
|
|
|
1799
1855
|
}
|
|
1800
1856
|
};
|
|
1801
1857
|
//#endregion
|
|
1802
|
-
//#region src/errors.ts
|
|
1858
|
+
//#region src/transport/errors.ts
|
|
1803
1859
|
z.enum(["client.non_json_response", "client.invalid_response"]);
|
|
1804
1860
|
var PocketCoderError = class extends Error {
|
|
1805
1861
|
code;
|
|
@@ -1856,7 +1912,7 @@ function responseError(response, body) {
|
|
|
1856
1912
|
});
|
|
1857
1913
|
}
|
|
1858
1914
|
//#endregion
|
|
1859
|
-
//#region src/attachments.ts
|
|
1915
|
+
//#region src/resources/attachments/attachments.ts
|
|
1860
1916
|
const DEFAULT_READY_TIMEOUT_MS = 12e4;
|
|
1861
1917
|
function contentDisposition(name) {
|
|
1862
1918
|
const clean = name.replace(/[\r\n]/g, "");
|
|
@@ -1929,7 +1985,7 @@ var AgentApi = class {
|
|
|
1929
1985
|
}
|
|
1930
1986
|
};
|
|
1931
1987
|
//#endregion
|
|
1932
|
-
//#region src/common.ts
|
|
1988
|
+
//#region src/transport/common.ts
|
|
1933
1989
|
function queryString(values) {
|
|
1934
1990
|
const params = new URLSearchParams();
|
|
1935
1991
|
for (const [key, value] of Object.entries(values)) if (value !== void 0) params.set(key, String(value));
|
|
@@ -1942,7 +1998,7 @@ function page(body) {
|
|
|
1942
1998
|
};
|
|
1943
1999
|
}
|
|
1944
2000
|
//#endregion
|
|
1945
|
-
//#region src/checkpoints.ts
|
|
2001
|
+
//#region src/resources/checkpoints/checkpoints.ts
|
|
1946
2002
|
var CheckpointsApi = class {
|
|
1947
2003
|
transport;
|
|
1948
2004
|
constructor(transport) {
|
|
@@ -1990,7 +2046,7 @@ var OperationsApi = class {
|
|
|
1990
2046
|
}
|
|
1991
2047
|
};
|
|
1992
2048
|
//#endregion
|
|
1993
|
-
//#region src/conversations.ts
|
|
2049
|
+
//#region src/resources/conversations/conversations.ts
|
|
1994
2050
|
var ConversationsApi = class {
|
|
1995
2051
|
transport;
|
|
1996
2052
|
constructor(transport) {
|
|
@@ -2004,7 +2060,7 @@ var ConversationsApi = class {
|
|
|
2004
2060
|
}
|
|
2005
2061
|
};
|
|
2006
2062
|
//#endregion
|
|
2007
|
-
//#region src/diagnostics.ts
|
|
2063
|
+
//#region src/resources/diagnostics/diagnostics.ts
|
|
2008
2064
|
var WorkspaceCursorApi = class {
|
|
2009
2065
|
transport;
|
|
2010
2066
|
resource;
|
|
@@ -2037,7 +2093,69 @@ var OutputsApi = class extends WorkspaceCursorApi {
|
|
|
2037
2093
|
}
|
|
2038
2094
|
};
|
|
2039
2095
|
//#endregion
|
|
2040
|
-
//#region src/
|
|
2096
|
+
//#region src/resources/keys/keys.ts
|
|
2097
|
+
var KeysApi = class {
|
|
2098
|
+
transport;
|
|
2099
|
+
constructor(transport) {
|
|
2100
|
+
this.transport = transport;
|
|
2101
|
+
}
|
|
2102
|
+
list(principalId, query = {}, options = {}) {
|
|
2103
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys?${queryString({
|
|
2104
|
+
limit: query.limit,
|
|
2105
|
+
cursor: query.cursor,
|
|
2106
|
+
request_id: query.requestId
|
|
2107
|
+
})}`, KeyListResponseSchema, options);
|
|
2108
|
+
}
|
|
2109
|
+
async *all(principalId, query = {}, options = {}) {
|
|
2110
|
+
let cursor;
|
|
2111
|
+
do {
|
|
2112
|
+
const page = await this.list(principalId, {
|
|
2113
|
+
...query,
|
|
2114
|
+
cursor
|
|
2115
|
+
}, options);
|
|
2116
|
+
yield* page.items;
|
|
2117
|
+
cursor = page.next_cursor ?? void 0;
|
|
2118
|
+
} while (cursor);
|
|
2119
|
+
}
|
|
2120
|
+
issue(principalId, input, options = {}) {
|
|
2121
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys`, KeyIssueResponseSchema, {
|
|
2122
|
+
method: "POST",
|
|
2123
|
+
body: JSON.stringify(input),
|
|
2124
|
+
signal: options.signal
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
revoke(principalId, keyId, options = {}) {
|
|
2128
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys/${encodeURIComponent(keyId)}`, z.object({ revoked: z.literal(true) }), {
|
|
2129
|
+
method: "DELETE",
|
|
2130
|
+
signal: options.signal
|
|
2131
|
+
});
|
|
2132
|
+
}
|
|
2133
|
+
revokeAll(principalId, options = {}) {
|
|
2134
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/keys`, z.object({ revoked: z.literal(true) }), {
|
|
2135
|
+
method: "DELETE",
|
|
2136
|
+
signal: options.signal
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
};
|
|
2140
|
+
var RecoveryApi = class {
|
|
2141
|
+
transport;
|
|
2142
|
+
constructor(transport) {
|
|
2143
|
+
this.transport = transport;
|
|
2144
|
+
}
|
|
2145
|
+
purge(principalId, workspaceId, executionKey, options = {}) {
|
|
2146
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/workspaces/${encodeURIComponent(workspaceId)}/purge`, OperationResourceSchema, {
|
|
2147
|
+
method: "POST",
|
|
2148
|
+
headers: { "Idempotency-Key": executionKey },
|
|
2149
|
+
body: "{}",
|
|
2150
|
+
signal: options.signal
|
|
2151
|
+
});
|
|
2152
|
+
}
|
|
2153
|
+
operation(principalId, operationId, options = {}) {
|
|
2154
|
+
return this.transport.request(`/v1/principals/${encodeURIComponent(principalId)}/operations/${encodeURIComponent(operationId)}`, OperationResourceSchema, options);
|
|
2155
|
+
}
|
|
2156
|
+
};
|
|
2157
|
+
//#endregion
|
|
2158
|
+
//#region src/resources/templates/templates.ts
|
|
2041
2159
|
var TemplatesApi = class {
|
|
2042
2160
|
transport;
|
|
2043
2161
|
constructor(transport) {
|
|
@@ -2054,7 +2172,7 @@ var TemplatesApi = class {
|
|
|
2054
2172
|
}
|
|
2055
2173
|
};
|
|
2056
2174
|
//#endregion
|
|
2057
|
-
//#region src/terminals.ts
|
|
2175
|
+
//#region src/resources/terminals/terminals.ts
|
|
2058
2176
|
var TerminalConnection = class {
|
|
2059
2177
|
socket;
|
|
2060
2178
|
messageListeners = /* @__PURE__ */ new Set();
|
|
@@ -2156,7 +2274,109 @@ var TerminalsApi = class {
|
|
|
2156
2274
|
}
|
|
2157
2275
|
};
|
|
2158
2276
|
//#endregion
|
|
2159
|
-
//#region src/
|
|
2277
|
+
//#region src/resources/workspaces/workspaces.ts
|
|
2278
|
+
const TERMINAL_WORKSPACE_STATES = new Set(TERMINAL_STATES);
|
|
2279
|
+
var WorkspacesApi = class {
|
|
2280
|
+
transport;
|
|
2281
|
+
constructor(transport) {
|
|
2282
|
+
this.transport = transport;
|
|
2283
|
+
}
|
|
2284
|
+
async list(query = {}, options = {}) {
|
|
2285
|
+
return page(await this.transport.request(`/v1/workspaces?${queryString({
|
|
2286
|
+
state: query.state,
|
|
2287
|
+
template: query.template,
|
|
2288
|
+
external_id: query.externalId,
|
|
2289
|
+
limit: query.limit ?? 50,
|
|
2290
|
+
cursor: query.cursor
|
|
2291
|
+
})}`, WorkspacePageSchema, options));
|
|
2292
|
+
}
|
|
2293
|
+
async *all(query = {}, options = {}) {
|
|
2294
|
+
let cursor;
|
|
2295
|
+
do {
|
|
2296
|
+
const current = await this.list({
|
|
2297
|
+
...query,
|
|
2298
|
+
cursor
|
|
2299
|
+
}, options);
|
|
2300
|
+
for (const workspace of current.items) yield workspace;
|
|
2301
|
+
cursor = current.nextCursor ?? void 0;
|
|
2302
|
+
} while (cursor);
|
|
2303
|
+
}
|
|
2304
|
+
get(id, options = {}) {
|
|
2305
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}`, WorkspaceResourceSchema, options);
|
|
2306
|
+
}
|
|
2307
|
+
create(input, options = {}) {
|
|
2308
|
+
const body = {
|
|
2309
|
+
external_id: input.externalId,
|
|
2310
|
+
template: {
|
|
2311
|
+
name: input.templateName,
|
|
2312
|
+
...input.templateVersion ? { version: input.templateVersion } : {}
|
|
2313
|
+
},
|
|
2314
|
+
...input.launchInput ? { launch_input: input.launchInput } : {},
|
|
2315
|
+
...input.metadata ? { metadata: input.metadata } : {},
|
|
2316
|
+
...input.source ? { source: input.source } : {}
|
|
2317
|
+
};
|
|
2318
|
+
return this.transport.request("/v1/workspaces", WorkspaceResourceSchema, {
|
|
2319
|
+
method: "POST",
|
|
2320
|
+
signal: options.signal,
|
|
2321
|
+
headers: { "Idempotency-Key": input.idempotencyKey ?? input.externalId },
|
|
2322
|
+
body: JSON.stringify(body)
|
|
2323
|
+
});
|
|
2324
|
+
}
|
|
2325
|
+
cancel(id, options = {}) {
|
|
2326
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/cancel`, WorkspaceResourceSchema, {
|
|
2327
|
+
method: "POST",
|
|
2328
|
+
signal: options.signal
|
|
2329
|
+
});
|
|
2330
|
+
}
|
|
2331
|
+
change(id, after, wait, options = {}) {
|
|
2332
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/changes?after=${after}&wait=${wait}`, WorkspaceChangeSchema, options);
|
|
2333
|
+
}
|
|
2334
|
+
async waitForReady(initial, timeoutMs, options = {}) {
|
|
2335
|
+
const deadline = Date.now() + timeoutMs;
|
|
2336
|
+
let workspace = initial;
|
|
2337
|
+
while (workspace.state !== "ready") {
|
|
2338
|
+
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2339
|
+
const remainingMs = deadline - Date.now();
|
|
2340
|
+
if (remainingMs <= 0) throw new Error(`workspace ${workspace.id} did not become ready within ${timeoutMs}ms`);
|
|
2341
|
+
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2342
|
+
options.onTick?.(workspace);
|
|
2343
|
+
}
|
|
2344
|
+
return workspace;
|
|
2345
|
+
}
|
|
2346
|
+
async waitForAgentInput(id, timeoutMs, options = {}) {
|
|
2347
|
+
const deadline = Date.now() + timeoutMs;
|
|
2348
|
+
let workspace = await this.get(id, options);
|
|
2349
|
+
while (workspace.agent_state !== "stable") {
|
|
2350
|
+
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2351
|
+
const remainingMs = deadline - Date.now();
|
|
2352
|
+
if (remainingMs <= 0) throw new AgentNotReadyError(workspace.id, workspace.agent_state, timeoutMs);
|
|
2353
|
+
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2354
|
+
}
|
|
2355
|
+
return workspace;
|
|
2356
|
+
}
|
|
2357
|
+
preserve(id, input, key, options = {}) {
|
|
2358
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/preserve`, input, key, PreserveResponseSchema, options);
|
|
2359
|
+
}
|
|
2360
|
+
purge(id, key, options = {}) {
|
|
2361
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/purge`, {}, key, OperationResourceSchema, options);
|
|
2362
|
+
}
|
|
2363
|
+
recreate(id, input, key, options = {}) {
|
|
2364
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/recreate`, input, key, RestoreResponseSchema, options);
|
|
2365
|
+
}
|
|
2366
|
+
resume(id, input, key, options = {}) {
|
|
2367
|
+
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/resume`, input, key, ResumeResponseSchema, options);
|
|
2368
|
+
}
|
|
2369
|
+
jsonOperation(path, input, key, schema, options) {
|
|
2370
|
+
return this.transport.request(path, schema, {
|
|
2371
|
+
method: "POST",
|
|
2372
|
+
signal: options.signal,
|
|
2373
|
+
headers: { "Idempotency-Key": key },
|
|
2374
|
+
body: JSON.stringify(input)
|
|
2375
|
+
});
|
|
2376
|
+
}
|
|
2377
|
+
};
|
|
2378
|
+
//#endregion
|
|
2379
|
+
//#region src/transport/transport.ts
|
|
2160
2380
|
function baseUrlOf(value) {
|
|
2161
2381
|
let url;
|
|
2162
2382
|
try {
|
|
@@ -2273,105 +2493,6 @@ async function delay(milliseconds, signal) {
|
|
|
2273
2493
|
});
|
|
2274
2494
|
}
|
|
2275
2495
|
//#endregion
|
|
2276
|
-
//#region src/workspaces.ts
|
|
2277
|
-
const TERMINAL_WORKSPACE_STATES = new Set(TERMINAL_STATES);
|
|
2278
|
-
var WorkspacesApi = class {
|
|
2279
|
-
transport;
|
|
2280
|
-
constructor(transport) {
|
|
2281
|
-
this.transport = transport;
|
|
2282
|
-
}
|
|
2283
|
-
async list(query = {}, options = {}) {
|
|
2284
|
-
return page(await this.transport.request(`/v1/workspaces?${queryString({
|
|
2285
|
-
state: query.state,
|
|
2286
|
-
template: query.template,
|
|
2287
|
-
external_id: query.externalId,
|
|
2288
|
-
limit: query.limit ?? 50,
|
|
2289
|
-
cursor: query.cursor
|
|
2290
|
-
})}`, WorkspacePageSchema, options));
|
|
2291
|
-
}
|
|
2292
|
-
async *all(query = {}, options = {}) {
|
|
2293
|
-
let cursor;
|
|
2294
|
-
do {
|
|
2295
|
-
const current = await this.list({
|
|
2296
|
-
...query,
|
|
2297
|
-
cursor
|
|
2298
|
-
}, options);
|
|
2299
|
-
for (const workspace of current.items) yield workspace;
|
|
2300
|
-
cursor = current.nextCursor ?? void 0;
|
|
2301
|
-
} while (cursor);
|
|
2302
|
-
}
|
|
2303
|
-
get(id, options = {}) {
|
|
2304
|
-
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}`, WorkspaceResourceSchema, options);
|
|
2305
|
-
}
|
|
2306
|
-
create(input, options = {}) {
|
|
2307
|
-
const body = {
|
|
2308
|
-
external_id: input.externalId,
|
|
2309
|
-
template: {
|
|
2310
|
-
name: input.templateName,
|
|
2311
|
-
...input.templateVersion ? { version: input.templateVersion } : {}
|
|
2312
|
-
},
|
|
2313
|
-
...input.launchInput ? { launch_input: input.launchInput } : {},
|
|
2314
|
-
...input.metadata ? { metadata: input.metadata } : {},
|
|
2315
|
-
...input.source ? { source: input.source } : {}
|
|
2316
|
-
};
|
|
2317
|
-
return this.transport.request("/v1/workspaces", WorkspaceResourceSchema, {
|
|
2318
|
-
method: "POST",
|
|
2319
|
-
signal: options.signal,
|
|
2320
|
-
headers: { "Idempotency-Key": input.idempotencyKey ?? input.externalId },
|
|
2321
|
-
body: JSON.stringify(body)
|
|
2322
|
-
});
|
|
2323
|
-
}
|
|
2324
|
-
cancel(id, options = {}) {
|
|
2325
|
-
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/cancel`, WorkspaceResourceSchema, {
|
|
2326
|
-
method: "POST",
|
|
2327
|
-
signal: options.signal
|
|
2328
|
-
});
|
|
2329
|
-
}
|
|
2330
|
-
change(id, after, wait, options = {}) {
|
|
2331
|
-
return this.transport.request(`/v1/workspaces/${encodeURIComponent(id)}/changes?after=${after}&wait=${wait}`, WorkspaceChangeSchema, options);
|
|
2332
|
-
}
|
|
2333
|
-
async waitForReady(initial, timeoutMs, options = {}) {
|
|
2334
|
-
const deadline = Date.now() + timeoutMs;
|
|
2335
|
-
let workspace = initial;
|
|
2336
|
-
while (workspace.state !== "ready") {
|
|
2337
|
-
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2338
|
-
const remainingMs = deadline - Date.now();
|
|
2339
|
-
if (remainingMs <= 0) throw new Error(`workspace ${workspace.id} did not become ready within ${timeoutMs}ms`);
|
|
2340
|
-
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2341
|
-
options.onTick?.(workspace);
|
|
2342
|
-
}
|
|
2343
|
-
return workspace;
|
|
2344
|
-
}
|
|
2345
|
-
async waitForAgentInput(id, timeoutMs, options = {}) {
|
|
2346
|
-
const deadline = Date.now() + timeoutMs;
|
|
2347
|
-
let workspace = await this.get(id, options);
|
|
2348
|
-
while (workspace.agent_state !== "stable") {
|
|
2349
|
-
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
2350
|
-
const remainingMs = deadline - Date.now();
|
|
2351
|
-
if (remainingMs <= 0) throw new AgentNotReadyError(workspace.id, workspace.agent_state, timeoutMs);
|
|
2352
|
-
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
2353
|
-
}
|
|
2354
|
-
return workspace;
|
|
2355
|
-
}
|
|
2356
|
-
preserve(id, input, key, options = {}) {
|
|
2357
|
-
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/preserve`, input, key, PreserveResponseSchema, options);
|
|
2358
|
-
}
|
|
2359
|
-
recreate(id, input, key, options = {}) {
|
|
2360
|
-
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/recreate`, input, key, RestoreResponseSchema, options);
|
|
2361
|
-
}
|
|
2362
|
-
resume(id, input, key, options = {}) {
|
|
2363
|
-
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/resume`, input, key, ResumeResponseSchema, options);
|
|
2364
|
-
}
|
|
2365
|
-
jsonOperation(path, input, key, schema, options) {
|
|
2366
|
-
return this.transport.request(path, schema, {
|
|
2367
|
-
method: "POST",
|
|
2368
|
-
signal: options.signal,
|
|
2369
|
-
headers: { "Idempotency-Key": key },
|
|
2370
|
-
body: JSON.stringify(input)
|
|
2371
|
-
});
|
|
2372
|
-
}
|
|
2373
|
-
};
|
|
2374
|
-
//#endregion
|
|
2375
2496
|
//#region src/client.ts
|
|
2376
2497
|
var PocketCoderClient = class {
|
|
2377
2498
|
transport;
|
|
@@ -2387,6 +2508,8 @@ var PocketCoderClient = class {
|
|
|
2387
2508
|
outputs;
|
|
2388
2509
|
administration;
|
|
2389
2510
|
terminals;
|
|
2511
|
+
keys;
|
|
2512
|
+
recovery;
|
|
2390
2513
|
constructor(config, fetchImpl = fetch) {
|
|
2391
2514
|
this.transport = new PocketCoderTransport(config, fetchImpl);
|
|
2392
2515
|
this.templates = new TemplatesApi(this.transport);
|
|
@@ -2401,13 +2524,15 @@ var PocketCoderClient = class {
|
|
|
2401
2524
|
this.outputs = new OutputsApi(this.transport);
|
|
2402
2525
|
this.administration = new AdministrationApi(this.transport);
|
|
2403
2526
|
this.terminals = new TerminalsApi(this.transport);
|
|
2527
|
+
this.keys = new KeysApi(this.transport);
|
|
2528
|
+
this.recovery = new RecoveryApi(this.transport);
|
|
2404
2529
|
}
|
|
2405
2530
|
raw(path, init = {}) {
|
|
2406
2531
|
return this.transport.raw(path, init);
|
|
2407
2532
|
}
|
|
2408
2533
|
};
|
|
2409
2534
|
//#endregion
|
|
2410
|
-
//#region src/workspace-turn-resolver.ts
|
|
2535
|
+
//#region src/resources/workspaces/workspace-turn-resolver.ts
|
|
2411
2536
|
const ERROR_MESSAGES = {
|
|
2412
2537
|
not_resumable: "workspace cannot be resumed",
|
|
2413
2538
|
resume_handler_missing: "workspace resume handler is not configured",
|
|
@@ -2551,4 +2676,4 @@ var WorkspaceTurnResolver = class {
|
|
|
2551
2676
|
}
|
|
2552
2677
|
};
|
|
2553
2678
|
//#endregion
|
|
2554
|
-
export { AdministrationApi, AgentApi, AgentNotReadyError, AttachmentsApi, CheckpointsApi, ConversationGoneError, ConversationsApi, LogsApi, NetworkEventsApi, OperationsApi, OutputsApi, PocketCoderClient, PocketCoderError, TERMINAL_WORKSPACE_STATES, TemplatesApi, TerminalConnection, TerminalsApi, WorkspaceTerminalError, WorkspaceTurnResolutionError, WorkspaceTurnResolver, WorkspacesApi, isPocketCoderErrorCode, splitAttachmentManifest };
|
|
2679
|
+
export { AdministrationApi, AgentApi, AgentNotReadyError, AttachmentsApi, CheckpointsApi, ConversationGoneError, ConversationsApi, KeysApi, LogsApi, NetworkEventsApi, OperationsApi, OutputsApi, PocketCoderClient, PocketCoderError, RecoveryApi, TERMINAL_WORKSPACE_STATES, TemplatesApi, TerminalConnection, TerminalsApi, WorkspaceTerminalError, WorkspaceTurnResolutionError, WorkspaceTurnResolver, WorkspacesApi, isPocketCoderErrorCode, splitAttachmentManifest };
|