@pstdio/pocketcoder-sdk 0.8.0 → 0.10.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/README.md +43 -3
- package/dist/index.d.ts +5764 -2146
- package/dist/index.js +1260 -436
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { createHash } from "node:crypto";
|
|
3
4
|
import { posix } from "node:path";
|
|
@@ -14,37 +15,6 @@ const AttachmentDescriptorSchema = z.object({
|
|
|
14
15
|
size_bytes: z.number().int().min(0).max(ATTACHMENT_MAX_FILE_BYTES),
|
|
15
16
|
sha256: z.string().regex(/^[0-9a-f]{64}$/)
|
|
16
17
|
});
|
|
17
|
-
z.looseObject({
|
|
18
|
-
type: z.literal("user"),
|
|
19
|
-
content: z.string(),
|
|
20
|
-
attachment_ids: z.array(z.uuid()).min(1).max(10).refine((ids) => new Set(ids).size === ids.length, "attachment_ids must be unique").optional()
|
|
21
|
-
});
|
|
22
|
-
const MANIFEST_OPEN = "<pocketcoder-attachments>";
|
|
23
|
-
const MANIFEST_CLOSE = "</pocketcoder-attachments>";
|
|
24
|
-
function splitAttachmentManifest(content) {
|
|
25
|
-
const open = content.lastIndexOf(MANIFEST_OPEN);
|
|
26
|
-
if (open < 0 || !content.trimEnd().endsWith(MANIFEST_CLOSE)) return {
|
|
27
|
-
text: content,
|
|
28
|
-
attachments: null
|
|
29
|
-
};
|
|
30
|
-
const close = content.lastIndexOf(MANIFEST_CLOSE);
|
|
31
|
-
const parsed = z.array(AttachmentDescriptorSchema).safeParse(safeJson(content.slice(open + 25, close)));
|
|
32
|
-
if (!parsed.success) return {
|
|
33
|
-
text: content,
|
|
34
|
-
attachments: null
|
|
35
|
-
};
|
|
36
|
-
return {
|
|
37
|
-
text: content.slice(0, open).trimEnd(),
|
|
38
|
-
attachments: parsed.data
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
function safeJson(value) {
|
|
42
|
-
try {
|
|
43
|
-
return JSON.parse(value);
|
|
44
|
-
} catch {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
18
|
const AttachmentStartPayload = z.object({
|
|
49
19
|
operation_id: z.uuid(),
|
|
50
20
|
attachment_id: z.uuid(),
|
|
@@ -139,7 +109,8 @@ const WorkloadCapabilitySchema = z.enum([
|
|
|
139
109
|
"workspace-services",
|
|
140
110
|
"revocable-preview-grants",
|
|
141
111
|
"workspace-cancel",
|
|
142
|
-
"unknown-outcome"
|
|
112
|
+
"unknown-outcome",
|
|
113
|
+
"parallel-conversations"
|
|
143
114
|
]);
|
|
144
115
|
const WorkloadProfileSchema = z.enum([
|
|
145
116
|
"finite-process",
|
|
@@ -191,8 +162,7 @@ const InstalledWorkloadSchema = z.strictObject({
|
|
|
191
162
|
kind: z.enum([
|
|
192
163
|
"process",
|
|
193
164
|
"service",
|
|
194
|
-
"pi"
|
|
195
|
-
"agentapi"
|
|
165
|
+
"pi"
|
|
196
166
|
]),
|
|
197
167
|
digest: WorkloadDigestSchema,
|
|
198
168
|
protocol: z.string().min(1).max(128),
|
|
@@ -203,6 +173,7 @@ const InstalledWorkloadSchema = z.strictObject({
|
|
|
203
173
|
//#region ../contracts/src/attachments/input-reference.ts
|
|
204
174
|
const InputObjectReferenceSchema = z.strictObject({
|
|
205
175
|
workspaceId: z.uuid(),
|
|
176
|
+
storageOwnerId: z.uuid().optional(),
|
|
206
177
|
fileId: z.uuid(),
|
|
207
178
|
objectVersion: WorkloadDigestSchema,
|
|
208
179
|
name: z.string().min(1).max(255),
|
|
@@ -268,6 +239,10 @@ const SCOPES = [
|
|
|
268
239
|
"network:read",
|
|
269
240
|
"terminal:attach",
|
|
270
241
|
"terminal:read",
|
|
242
|
+
"sessions:read",
|
|
243
|
+
"sessions:write",
|
|
244
|
+
"budgets:read",
|
|
245
|
+
"budgets:admin",
|
|
271
246
|
"admin"
|
|
272
247
|
];
|
|
273
248
|
z.strictObject({
|
|
@@ -572,6 +547,7 @@ const ERROR_CODES = {
|
|
|
572
547
|
"principal.name_conflict": 409,
|
|
573
548
|
"key.not_found": 404,
|
|
574
549
|
"request.body_too_large": 413,
|
|
550
|
+
"request.not_found": 404,
|
|
575
551
|
"validation.invalid": 400,
|
|
576
552
|
"idempotency.conflict": 409,
|
|
577
553
|
"capacity.queue_full": 429,
|
|
@@ -635,6 +611,16 @@ const ERROR_CODES = {
|
|
|
635
611
|
"account.purge_pending": 503,
|
|
636
612
|
"recovery.required": 503,
|
|
637
613
|
"recovery.failed": 409,
|
|
614
|
+
"session.not_found": 404,
|
|
615
|
+
"session.closed": 409,
|
|
616
|
+
"profile.not_found": 404,
|
|
617
|
+
"budget.not_found": 404,
|
|
618
|
+
"budget.exhausted": 429,
|
|
619
|
+
"budget.conflict": 409,
|
|
620
|
+
"revision.stale": 412,
|
|
621
|
+
"events.cursor_invalid": 400,
|
|
622
|
+
"events.cursor_expired": 410,
|
|
623
|
+
"runtime.unavailable": 503,
|
|
638
624
|
"internal.error": 500
|
|
639
625
|
};
|
|
640
626
|
const errorCodes = Object.keys(ERROR_CODES);
|
|
@@ -734,6 +720,45 @@ const ConversationProtocolSupportSchema = z.object({
|
|
|
734
720
|
producer_capabilities: z.null()
|
|
735
721
|
});
|
|
736
722
|
//#endregion
|
|
723
|
+
//#region ../contracts/src/conversations/parts.ts
|
|
724
|
+
const text = z.string().max(262144);
|
|
725
|
+
const payload = JsonValueSchema.refine((value) => new TextEncoder().encode(JSON.stringify(value)).length <= 262144, "Session part payload exceeds 256 KiB");
|
|
726
|
+
const ConversationPartSchema = z.discriminatedUnion("type", [
|
|
727
|
+
z.strictObject({
|
|
728
|
+
type: z.literal("text"),
|
|
729
|
+
text
|
|
730
|
+
}),
|
|
731
|
+
z.strictObject({
|
|
732
|
+
type: z.literal("tool"),
|
|
733
|
+
call_id: z.string().min(1).max(256),
|
|
734
|
+
name: z.string().min(1).max(128),
|
|
735
|
+
status: z.enum([
|
|
736
|
+
"pending",
|
|
737
|
+
"running",
|
|
738
|
+
"completed",
|
|
739
|
+
"failed",
|
|
740
|
+
"canceled"
|
|
741
|
+
]),
|
|
742
|
+
input: payload,
|
|
743
|
+
output: payload.optional(),
|
|
744
|
+
output_text: text.optional(),
|
|
745
|
+
started_at: z.iso.datetime().nullable().optional(),
|
|
746
|
+
ended_at: z.iso.datetime().nullable().optional()
|
|
747
|
+
}),
|
|
748
|
+
z.strictObject({
|
|
749
|
+
type: z.literal("error"),
|
|
750
|
+
code: z.string().min(1).max(128),
|
|
751
|
+
message: text
|
|
752
|
+
}),
|
|
753
|
+
z.strictObject({
|
|
754
|
+
type: z.literal("file"),
|
|
755
|
+
file_id: z.uuid(),
|
|
756
|
+
name: z.string().min(1).max(512),
|
|
757
|
+
media_type: z.string().min(1).max(256),
|
|
758
|
+
size_bytes: z.number().int().nonnegative()
|
|
759
|
+
})
|
|
760
|
+
]);
|
|
761
|
+
//#endregion
|
|
737
762
|
//#region ../contracts/src/conversations/conversation.ts
|
|
738
763
|
const CONVERSATION_ROLES = [
|
|
739
764
|
"user",
|
|
@@ -746,6 +771,7 @@ const ConversationMessageInputSchema = z.object({
|
|
|
746
771
|
message_id: z.string().min(1).max(256),
|
|
747
772
|
role: z.enum(CONVERSATION_ROLES),
|
|
748
773
|
content: z.string().max(262144),
|
|
774
|
+
parts: z.array(ConversationPartSchema).max(256).optional(),
|
|
749
775
|
occurred_at: z.iso.datetime(),
|
|
750
776
|
metadata: ConversationMetadataSchema.default({}),
|
|
751
777
|
identity: ConversationMessageIdentitySchema.nullable().optional()
|
|
@@ -789,7 +815,7 @@ const ConversationActivitySchema = z.object({
|
|
|
789
815
|
ended_at: z.iso.datetime().nullable(),
|
|
790
816
|
outcome: z.string().nullable()
|
|
791
817
|
});
|
|
792
|
-
z.object({
|
|
818
|
+
const ConversationRecordDocumentSchema = z.object({
|
|
793
819
|
schema: z.literal("pocketcoder.conversation-record/v1"),
|
|
794
820
|
turn_id: z.uuid().nullable(),
|
|
795
821
|
request: ConversationRequestIdentitySchema.nullable(),
|
|
@@ -850,7 +876,10 @@ const ViewSessionSchema = z.discriminatedUnion("mode", [
|
|
|
850
876
|
parentOrigin: HttpsOriginSchema
|
|
851
877
|
})
|
|
852
878
|
]);
|
|
853
|
-
z.strictObject({
|
|
879
|
+
z.strictObject({
|
|
880
|
+
session: ViewSessionSchema.default({ mode: "local" }),
|
|
881
|
+
grantId: z.uuid().optional()
|
|
882
|
+
}).refine((input) => input.session.mode === "local" || !!input.grantId, "Cloud previews require a grant");
|
|
854
883
|
//#endregion
|
|
855
884
|
//#region ../contracts/src/displays/display.ts
|
|
856
885
|
const DisplaySchema = z.strictObject({ mode: z.enum(["desktop", "browser"]) });
|
|
@@ -1022,7 +1051,7 @@ const ExportObjectReferenceSchema = z.strictObject({
|
|
|
1022
1051
|
mediaType: AttachmentMediaTypeSchema,
|
|
1023
1052
|
digest: WorkloadDigestSchema
|
|
1024
1053
|
});
|
|
1025
|
-
z.strictObject({
|
|
1054
|
+
const WorkloadExportReferenceSchema = z.strictObject({
|
|
1026
1055
|
exportId: z.uuid(),
|
|
1027
1056
|
execution: WorkloadExecutionReferenceSchema,
|
|
1028
1057
|
manifestDigest: WorkloadDigestSchema,
|
|
@@ -1031,6 +1060,11 @@ z.strictObject({
|
|
|
1031
1060
|
"partial",
|
|
1032
1061
|
"lost"
|
|
1033
1062
|
]),
|
|
1063
|
+
cleanupState: z.enum([
|
|
1064
|
+
"not_required",
|
|
1065
|
+
"pending",
|
|
1066
|
+
"complete"
|
|
1067
|
+
]).optional(),
|
|
1034
1068
|
publication: z.enum([
|
|
1035
1069
|
"published",
|
|
1036
1070
|
"unavailable",
|
|
@@ -1057,6 +1091,11 @@ z.strictObject({
|
|
|
1057
1091
|
path: ["expiresAt"],
|
|
1058
1092
|
message: "export retention must be positive"
|
|
1059
1093
|
});
|
|
1094
|
+
if (value.completeness === "complete" !== (value.errors.length === 0)) ctx.addIssue({
|
|
1095
|
+
code: "custom",
|
|
1096
|
+
path: ["errors"],
|
|
1097
|
+
message: "Export errors must agree with completeness"
|
|
1098
|
+
});
|
|
1060
1099
|
const ids = value.objects.map((object) => object.objectId);
|
|
1061
1100
|
if (new Set(ids).size !== ids.length) ctx.addIssue({
|
|
1062
1101
|
code: "custom",
|
|
@@ -1124,6 +1163,14 @@ const PreviewSocketPayload = z.discriminatedUnion("op", [
|
|
|
1124
1163
|
request_id: z.uuid()
|
|
1125
1164
|
})
|
|
1126
1165
|
]);
|
|
1166
|
+
z.strictObject({
|
|
1167
|
+
id: z.uuid(),
|
|
1168
|
+
subject: z.string().min(1).max(256),
|
|
1169
|
+
accessRevision: z.string().min(1).max(256),
|
|
1170
|
+
previews: z.array(PreviewNameSchema).min(1).max(16).refine((names) => new Set(names).size === names.length, "Preview names must be unique"),
|
|
1171
|
+
ceilingAt: z.iso.datetime()
|
|
1172
|
+
});
|
|
1173
|
+
z.strictObject({ accessRevision: z.string().min(1).max(256) });
|
|
1127
1174
|
//#endregion
|
|
1128
1175
|
//#region ../contracts/src/workspaces/workspace.ts
|
|
1129
1176
|
const WORKSPACE_STATES = [
|
|
@@ -1170,6 +1217,7 @@ const REASON_CODES = [
|
|
|
1170
1217
|
"idle_expired",
|
|
1171
1218
|
"queue_timeout",
|
|
1172
1219
|
"launch_failed",
|
|
1220
|
+
"launch_refused",
|
|
1173
1221
|
"preserve_requested",
|
|
1174
1222
|
"preserved_by_policy",
|
|
1175
1223
|
"checkpoint_created",
|
|
@@ -1190,7 +1238,6 @@ const AGENT_STATES = [
|
|
|
1190
1238
|
"running",
|
|
1191
1239
|
"stable"
|
|
1192
1240
|
];
|
|
1193
|
-
const AgentInterruptResponseSchema = z.object({ status: z.enum(["requested", "idle"]) });
|
|
1194
1241
|
z.object({
|
|
1195
1242
|
external_id: z.string().min(1).max(256),
|
|
1196
1243
|
template: z.object({
|
|
@@ -1206,15 +1253,10 @@ const TemplateRefSchema = z.object({
|
|
|
1206
1253
|
version: z.string(),
|
|
1207
1254
|
digest: z.string()
|
|
1208
1255
|
});
|
|
1209
|
-
const AgentMetadataSchema = z.object({
|
|
1210
|
-
type: z.string(),
|
|
1211
|
-
model: z.string().min(1).max(255).nullable()
|
|
1212
|
-
});
|
|
1213
1256
|
const WorkspaceResourceSchema = z.object({
|
|
1214
1257
|
id: z.uuid(),
|
|
1215
1258
|
external_id: z.string(),
|
|
1216
1259
|
template: TemplateRefSchema,
|
|
1217
|
-
agent: AgentMetadataSchema.nullable(),
|
|
1218
1260
|
state: z.enum(WORKSPACE_STATES),
|
|
1219
1261
|
reason_code: z.enum(REASON_CODES).nullable(),
|
|
1220
1262
|
agent_state: z.enum(AGENT_STATES),
|
|
@@ -1228,6 +1270,10 @@ const WorkspaceResourceSchema = z.object({
|
|
|
1228
1270
|
connected_at: z.iso.datetime().nullable(),
|
|
1229
1271
|
ready_at: z.iso.datetime().nullable(),
|
|
1230
1272
|
deadline_at: z.iso.datetime(),
|
|
1273
|
+
lifetime: z.strictObject({
|
|
1274
|
+
revision: z.number().int().positive(),
|
|
1275
|
+
ceilingAt: z.iso.datetime()
|
|
1276
|
+
}).optional(),
|
|
1231
1277
|
terminal_at: z.iso.datetime().nullable(),
|
|
1232
1278
|
metadata: z.record(z.string(), z.string()),
|
|
1233
1279
|
origin_workspace_id: z.uuid().nullable(),
|
|
@@ -1272,7 +1318,6 @@ const TemplateListItemSchema = z.object({
|
|
|
1272
1318
|
name: z.string(),
|
|
1273
1319
|
version: z.string(),
|
|
1274
1320
|
digest: z.string(),
|
|
1275
|
-
agent: AgentMetadataSchema.nullable(),
|
|
1276
1321
|
description: z.string().optional(),
|
|
1277
1322
|
status: z.enum([
|
|
1278
1323
|
"active",
|
|
@@ -1382,7 +1427,8 @@ z.object({ name: SecretNameSchema });
|
|
|
1382
1427
|
const issuerUrl = z.url().refine((value) => {
|
|
1383
1428
|
if (!URL.canParse(value)) return false;
|
|
1384
1429
|
const url = new URL(value);
|
|
1385
|
-
|
|
1430
|
+
const clusterLocal = url.protocol === "http:" && url.hostname.endsWith(".svc.cluster.local");
|
|
1431
|
+
return (url.protocol === "https:" || clusterLocal) && !url.username && !url.password && !url.search && !url.hash;
|
|
1386
1432
|
});
|
|
1387
1433
|
const IssuerConfigSchema = z.strictObject({
|
|
1388
1434
|
url: issuerUrl,
|
|
@@ -1452,14 +1498,6 @@ const HarnessSchema = z.object({
|
|
|
1452
1498
|
env: EnvSchema.default({}),
|
|
1453
1499
|
cwd: z.string().refine(isAbsolutePath, "expected an absolute path").optional()
|
|
1454
1500
|
});
|
|
1455
|
-
const AgentSchema = HarnessSchema.extend({
|
|
1456
|
-
model: z.string().min(1).max(255).optional().describe("Display metadata only; does not configure the agent model."),
|
|
1457
|
-
type: z.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/).default("custom"),
|
|
1458
|
-
transport: z.enum(["pty", "acp"]).default("pty"),
|
|
1459
|
-
termWidth: z.number().int().min(10).max(65535).optional(),
|
|
1460
|
-
stateFile: z.string().refine(isAbsolutePath, "expected an absolute path").optional(),
|
|
1461
|
-
interruptKeys: z.string().min(1).max(16).optional()
|
|
1462
|
-
});
|
|
1463
1501
|
const TerminalSchema = z.object({
|
|
1464
1502
|
command: CommandSchema,
|
|
1465
1503
|
env: EnvSchema.default({}),
|
|
@@ -1538,7 +1576,7 @@ const CheckpointHookSchema = z.object({
|
|
|
1538
1576
|
env: EnvSchema.default({}),
|
|
1539
1577
|
cwd: z.string().refine(isAbsolutePath, "expected an absolute path").optional()
|
|
1540
1578
|
});
|
|
1541
|
-
const
|
|
1579
|
+
const RuntimeTemplatePolicySchema = z.object({
|
|
1542
1580
|
version: z.string().regex(SEMVER_RE),
|
|
1543
1581
|
image: z.string().regex(IMAGE_DIGEST_RE, { message: "image must be digest-pinned (repo@sha256:<64 hex>)" }),
|
|
1544
1582
|
imagePullSecret: z.string().refine((value) => value.startsWith("secretRef:") && SecretNameSchema.safeParse(value.slice(10)).success, "imagePullSecret must name a stored secret").optional(),
|
|
@@ -1549,7 +1587,6 @@ const TemplateSpecSchema = z.object({
|
|
|
1549
1587
|
"/run/pocketcoder/input"
|
|
1550
1588
|
]),
|
|
1551
1589
|
setup: z.array(SetupStepSchema).max(32).default([]),
|
|
1552
|
-
agent: AgentSchema.optional(),
|
|
1553
1590
|
harness: HarnessSchema.optional(),
|
|
1554
1591
|
terminal: TerminalSchema.optional(),
|
|
1555
1592
|
previews: PreviewsSchema.optional(),
|
|
@@ -1561,59 +1598,14 @@ const TemplateSpecSchema = z.object({
|
|
|
1561
1598
|
security: SecuritySchema.prefault({}),
|
|
1562
1599
|
network: NetworkPolicySchema,
|
|
1563
1600
|
maxLaunchInputBytes: z.number().int().positive().max(1048576).default(65536),
|
|
1564
|
-
compat: z.object({
|
|
1565
|
-
agent: z.string().optional(),
|
|
1566
|
-
agentapi: z.string().optional()
|
|
1567
|
-
}).default({}),
|
|
1568
1601
|
persistence: PersistenceSpecSchema.prefault({}),
|
|
1569
1602
|
source: SourceSpecSchema.nullable().default(null),
|
|
1570
1603
|
checkpointHook: CheckpointHookSchema.optional(),
|
|
1571
1604
|
outputs: z.record(z.string().regex(NAME_RE), OutputDeclarationSchema).default({})
|
|
1572
|
-
})
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
message: "either agent or harness is required"
|
|
1577
|
-
});
|
|
1578
|
-
if (!spec.agent) return;
|
|
1579
|
-
if (spec.agent.transport === "acp") for (const field of [
|
|
1580
|
-
"termWidth",
|
|
1581
|
-
"stateFile",
|
|
1582
|
-
"interruptKeys"
|
|
1583
|
-
]) {
|
|
1584
|
-
if (spec.agent[field] === void 0) continue;
|
|
1585
|
-
ctx.addIssue({
|
|
1586
|
-
code: "custom",
|
|
1587
|
-
path: ["agent", field],
|
|
1588
|
-
message: `${field} is only valid for PTY transport`
|
|
1589
|
-
});
|
|
1590
|
-
}
|
|
1591
|
-
for (const field of [
|
|
1592
|
-
"harness",
|
|
1593
|
-
"services",
|
|
1594
|
-
"checkpointHook"
|
|
1595
|
-
]) {
|
|
1596
|
-
if (spec[field] === void 0) continue;
|
|
1597
|
-
ctx.addIssue({
|
|
1598
|
-
code: "custom",
|
|
1599
|
-
path: [field],
|
|
1600
|
-
message: `agent cannot be combined with ${field}`
|
|
1601
|
-
});
|
|
1602
|
-
}
|
|
1603
|
-
}).transform((spec) => {
|
|
1604
|
-
if (spec.agent) {
|
|
1605
|
-
const { harness: _harness, services: _services, checkpointHook: _hook, ...native } = spec;
|
|
1606
|
-
return {
|
|
1607
|
-
...native,
|
|
1608
|
-
agent: spec.agent
|
|
1609
|
-
};
|
|
1610
|
-
}
|
|
1611
|
-
const { agent: _agent, ...legacy } = spec;
|
|
1612
|
-
return {
|
|
1613
|
-
...legacy,
|
|
1614
|
-
harness: spec.harness,
|
|
1615
|
-
services: spec.services ?? {}
|
|
1616
|
-
};
|
|
1605
|
+
});
|
|
1606
|
+
const TemplateSpecSchema = RuntimeTemplatePolicySchema.extend({
|
|
1607
|
+
harness: HarnessSchema,
|
|
1608
|
+
services: z.record(z.string().regex(NAME_RE), ServiceSchema).default({})
|
|
1617
1609
|
});
|
|
1618
1610
|
const TemplateManifestBaseSchema = z.object({
|
|
1619
1611
|
apiVersion: z.literal("pocketcoder.dev/v1alpha1", { error: "unsupported template format for the alpha runtime; canonical workloads require an installed workload runtime" }),
|
|
@@ -1664,7 +1656,12 @@ const WaitingRuntimeSpecSchema = z.strictObject({
|
|
|
1664
1656
|
incarnationId: z.string().min(1).max(256),
|
|
1665
1657
|
profile: WorkloadProfileSchema,
|
|
1666
1658
|
operations: z.record(z.string(), HarnessSchema),
|
|
1667
|
-
infrastructure: z.record(z.string(), HarnessSchema)
|
|
1659
|
+
infrastructure: z.record(z.string(), HarnessSchema),
|
|
1660
|
+
serviceHealth: z.record(z.string(), z.strictObject({
|
|
1661
|
+
baseUrl: z.string().url(),
|
|
1662
|
+
healthPath: z.string()
|
|
1663
|
+
})).optional(),
|
|
1664
|
+
manualServices: z.array(z.string()).optional()
|
|
1668
1665
|
});
|
|
1669
1666
|
const ProcessStartPayload = z.strictObject({
|
|
1670
1667
|
execution: ProcessReferenceSchema,
|
|
@@ -1688,6 +1685,11 @@ const ProcessCancelResultPayload = ProcessTargetPayload.extend({
|
|
|
1688
1685
|
])
|
|
1689
1686
|
});
|
|
1690
1687
|
//#endregion
|
|
1688
|
+
//#region ../contracts/src/templates/template-runtime.ts
|
|
1689
|
+
function templateServices(spec) {
|
|
1690
|
+
return spec.services ?? {};
|
|
1691
|
+
}
|
|
1692
|
+
//#endregion
|
|
1691
1693
|
//#region ../contracts/src/secrets/credential-slot.ts
|
|
1692
1694
|
const CredentialSlotSchema = z.strictObject({
|
|
1693
1695
|
policyRef: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,254}$/).refine((value) => !value.includes("..")),
|
|
@@ -1727,22 +1729,18 @@ const WorkloadInputSchema = z.strictObject({
|
|
|
1727
1729
|
//#endregion
|
|
1728
1730
|
//#region ../contracts/src/templates/template-validation.ts
|
|
1729
1731
|
function envSources(spec) {
|
|
1730
|
-
const sources = [[["spec", "env"], spec.env], [
|
|
1731
|
-
"spec",
|
|
1732
|
-
"agent",
|
|
1733
|
-
"env"
|
|
1734
|
-
] : [
|
|
1732
|
+
const sources = [[["spec", "env"], spec.env], [[
|
|
1735
1733
|
"spec",
|
|
1736
1734
|
"harness",
|
|
1737
1735
|
"env"
|
|
1738
|
-
],
|
|
1736
|
+
], spec.harness.env]];
|
|
1739
1737
|
for (const [i, step] of spec.setup.entries()) sources.push([[
|
|
1740
1738
|
"spec",
|
|
1741
1739
|
"setup",
|
|
1742
1740
|
i,
|
|
1743
1741
|
"env"
|
|
1744
1742
|
], step.env]);
|
|
1745
|
-
if (
|
|
1743
|
+
if (spec.checkpointHook) sources.push([[
|
|
1746
1744
|
"spec",
|
|
1747
1745
|
"checkpointHook",
|
|
1748
1746
|
"env"
|
|
@@ -1793,10 +1791,10 @@ function validateServices$1(spec, ctx) {
|
|
|
1793
1791
|
],
|
|
1794
1792
|
message: "healthPath must be a normalized absolute path"
|
|
1795
1793
|
});
|
|
1796
|
-
validateServiceRoutes(serviceName, service.routes, ctx);
|
|
1794
|
+
validateServiceRoutes$1(serviceName, service.routes, ctx);
|
|
1797
1795
|
}
|
|
1798
1796
|
}
|
|
1799
|
-
function validateServiceRoutes(serviceName, routes, ctx) {
|
|
1797
|
+
function validateServiceRoutes$1(serviceName, routes, ctx) {
|
|
1800
1798
|
const seen = /* @__PURE__ */ new Set();
|
|
1801
1799
|
for (const [index, route] of routes.entries()) {
|
|
1802
1800
|
if (!isNormalizedPath(route.path)) ctx.addIssue({
|
|
@@ -1919,7 +1917,6 @@ function validateTemplatePersistence(spec, ctx) {
|
|
|
1919
1917
|
const mounts = spec.persistence.mounts;
|
|
1920
1918
|
for (const [index, mount] of mounts.entries()) validatePersistenceMount(spec, mounts, mount, index, seenNames, ctx);
|
|
1921
1919
|
validateSourceMount(spec, mounts, ctx);
|
|
1922
|
-
validateAgentStateFile(spec, mounts, ctx);
|
|
1923
1920
|
if (spec.persistence.conversationRestore === "supported" && (!spec.persistence.sessionCompatibility || mounts.length < 2)) ctx.addIssue({
|
|
1924
1921
|
code: "custom",
|
|
1925
1922
|
path: [
|
|
@@ -1930,43 +1927,6 @@ function validateTemplatePersistence(spec, ctx) {
|
|
|
1930
1927
|
message: "supported conversation restore requires sessionCompatibility and a separate harness-state mount"
|
|
1931
1928
|
});
|
|
1932
1929
|
}
|
|
1933
|
-
function validateAgentStateFile(spec, mounts, ctx) {
|
|
1934
|
-
if (!spec.agent) return;
|
|
1935
|
-
const stateFile = spec.agent.stateFile;
|
|
1936
|
-
const normalized = stateFile !== void 0 && isNormalizedFilesystemPath(stateFile);
|
|
1937
|
-
if (stateFile !== void 0 && !normalized) ctx.addIssue({
|
|
1938
|
-
code: "custom",
|
|
1939
|
-
path: [
|
|
1940
|
-
"spec",
|
|
1941
|
-
"agent",
|
|
1942
|
-
"stateFile"
|
|
1943
|
-
],
|
|
1944
|
-
message: "stateFile must be a normalized absolute filesystem path"
|
|
1945
|
-
});
|
|
1946
|
-
if (spec.agent.transport === "acp" && spec.persistence.conversationRestore === "supported") {
|
|
1947
|
-
ctx.addIssue({
|
|
1948
|
-
code: "custom",
|
|
1949
|
-
path: [
|
|
1950
|
-
"spec",
|
|
1951
|
-
"persistence",
|
|
1952
|
-
"conversationRestore"
|
|
1953
|
-
],
|
|
1954
|
-
message: "supported conversation restore requires PTY transport"
|
|
1955
|
-
});
|
|
1956
|
-
return;
|
|
1957
|
-
}
|
|
1958
|
-
if (spec.persistence.conversationRestore !== "supported") return;
|
|
1959
|
-
if (normalized && mounts.some((mount) => stateFile.startsWith(`${mount.target}/`))) return;
|
|
1960
|
-
ctx.addIssue({
|
|
1961
|
-
code: "custom",
|
|
1962
|
-
path: [
|
|
1963
|
-
"spec",
|
|
1964
|
-
"agent",
|
|
1965
|
-
"stateFile"
|
|
1966
|
-
],
|
|
1967
|
-
message: "supported conversation restore requires agent.stateFile below a persistence mount"
|
|
1968
|
-
});
|
|
1969
|
-
}
|
|
1970
1930
|
function validatePersistenceMount(spec, mounts, mount, index, seenNames, ctx) {
|
|
1971
1931
|
const path = [
|
|
1972
1932
|
"spec",
|
|
@@ -2108,7 +2068,7 @@ function validateAdapters(spec, issue) {
|
|
|
2108
2068
|
const path = ["adapters", name];
|
|
2109
2069
|
if (adapter.kind === "service") {
|
|
2110
2070
|
if (!adapter.service || !Object.hasOwn(spec.services, adapter.service) || adapter.command) issue(path, "service adapters require a declared service and no process command");
|
|
2111
|
-
} else if (!adapter.command || adapter.service) issue(path, "process
|
|
2071
|
+
} else if (!adapter.command || adapter.service) issue(path, "process and Pi adapters require a command and no service reference");
|
|
2112
2072
|
}
|
|
2113
2073
|
}
|
|
2114
2074
|
function validateProcessEnvironment(spec, issue) {
|
|
@@ -2164,16 +2124,24 @@ function validateOperations(spec, issue) {
|
|
|
2164
2124
|
"adapter"
|
|
2165
2125
|
], "operation must name a pinned adapter");
|
|
2166
2126
|
if (spec.profile === "cloud-interactive" && adapter?.kind === "process") issue(["operations", name], "cloud-interactive requires request-aware adapters");
|
|
2167
|
-
|
|
2127
|
+
validateOutputRoots(spec, name, operation.outputRoots, issue);
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
function validateOutputRoots(spec, name, roots, issue) {
|
|
2131
|
+
const path = [
|
|
2132
|
+
"operations",
|
|
2133
|
+
name,
|
|
2134
|
+
"outputRoots"
|
|
2135
|
+
];
|
|
2136
|
+
for (const root of roots) {
|
|
2137
|
+
if (!isWorkloadPath(root) || [
|
|
2168
2138
|
"/run",
|
|
2169
2139
|
"/proc",
|
|
2170
2140
|
"/sys",
|
|
2171
2141
|
"/dev"
|
|
2172
|
-
].some((
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
"outputRoots"
|
|
2176
|
-
], "output roots must be normalized and outside protected storage");
|
|
2142
|
+
].some((base) => overlaps(base, root))) issue(path, "output roots must be normalized and outside protected storage");
|
|
2143
|
+
if (spec.lifecycle?.persistence.mounts.some((mount) => overlaps(mount.target, root))) issue(path, "output roots must not overlap checkpoint storage");
|
|
2144
|
+
if (roots.some((other) => other !== root && overlaps(root, other))) issue(path, "output roots must not overlap");
|
|
2177
2145
|
}
|
|
2178
2146
|
}
|
|
2179
2147
|
function serviceUrl(value) {
|
|
@@ -2192,27 +2160,32 @@ function isLoopbackService(url) {
|
|
|
2192
2160
|
}
|
|
2193
2161
|
function validateServices(spec, issue) {
|
|
2194
2162
|
for (const [name, service] of Object.entries(spec.services)) {
|
|
2163
|
+
if (service.autostart === false && service.required) issue(["services", name], "manual services cannot be required for initial readiness");
|
|
2195
2164
|
const url = serviceUrl(service.baseUrl);
|
|
2196
2165
|
if (!url || !isLoopbackService(url)) {
|
|
2197
2166
|
issue(["services", name], "service must use loopback HTTP without credentials or a path");
|
|
2198
2167
|
continue;
|
|
2199
2168
|
}
|
|
2200
|
-
|
|
2201
|
-
|
|
2169
|
+
validateServiceRoutes(name, service, issue);
|
|
2170
|
+
const privateTransport = Object.values(spec.adapters).some((adapter) => adapter.service === name);
|
|
2171
|
+
for (const [previewName, preview] of Object.entries(spec.previews)) if (privateTransport && preview.port === Number(url.port || 80)) issue(["previews", previewName], "preview port is reserved by a service");
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
function validateServiceRoutes(name, service, issue) {
|
|
2175
|
+
const routes = /* @__PURE__ */ new Set();
|
|
2176
|
+
if (!isNormalizedPath(service.healthPath)) issue([
|
|
2177
|
+
"services",
|
|
2178
|
+
name,
|
|
2179
|
+
"healthPath"
|
|
2180
|
+
], "health path must be normalized");
|
|
2181
|
+
for (const route of service.routes) {
|
|
2182
|
+
const key = `${route.method} ${route.path}`;
|
|
2183
|
+
if (!isNormalizedPath(route.path) || routes.has(key)) issue([
|
|
2202
2184
|
"services",
|
|
2203
2185
|
name,
|
|
2204
|
-
"
|
|
2205
|
-
], "
|
|
2206
|
-
|
|
2207
|
-
const key = `${route.method} ${route.path}`;
|
|
2208
|
-
if (!isNormalizedPath(route.path) || routes.has(key)) issue([
|
|
2209
|
-
"services",
|
|
2210
|
-
name,
|
|
2211
|
-
"routes"
|
|
2212
|
-
], "routes must be normalized and unique");
|
|
2213
|
-
routes.add(key);
|
|
2214
|
-
}
|
|
2215
|
-
for (const [previewName, preview] of Object.entries(spec.previews)) if (preview.port === Number(url.port || 80)) issue(["previews", previewName], "preview port is reserved by a service");
|
|
2186
|
+
"routes"
|
|
2187
|
+
], "routes must be normalized and unique");
|
|
2188
|
+
routes.add(key);
|
|
2216
2189
|
}
|
|
2217
2190
|
}
|
|
2218
2191
|
function validateWorkloadTemplate(manifest, ctx) {
|
|
@@ -2243,8 +2216,7 @@ const WorkloadAdapterSchema = z.strictObject({
|
|
|
2243
2216
|
kind: z.enum([
|
|
2244
2217
|
"process",
|
|
2245
2218
|
"service",
|
|
2246
|
-
"pi"
|
|
2247
|
-
"agentapi"
|
|
2219
|
+
"pi"
|
|
2248
2220
|
]),
|
|
2249
2221
|
digest: WorkloadDigestSchema,
|
|
2250
2222
|
protocol: z.string().min(1).max(128),
|
|
@@ -2269,11 +2241,15 @@ const WorkloadTemplateSchema = z.strictObject({
|
|
|
2269
2241
|
spec: z.strictObject({
|
|
2270
2242
|
version: z.string().regex(/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/),
|
|
2271
2243
|
image: WorkloadImageSchema,
|
|
2244
|
+
imagePullSecret: RuntimeTemplatePolicySchema.shape.imagePullSecret,
|
|
2272
2245
|
runtime: WorkloadRuntimePinSchema,
|
|
2273
2246
|
profile: WorkloadProfileSchema,
|
|
2274
2247
|
adapters: z.record(WorkloadNameSchema, WorkloadAdapterSchema),
|
|
2275
2248
|
operations: z.record(WorkloadNameSchema, WorkloadOperationSchema),
|
|
2276
|
-
services: z.record(WorkloadNameSchema, ServiceSchema.extend({
|
|
2249
|
+
services: z.record(WorkloadNameSchema, ServiceSchema.extend({
|
|
2250
|
+
process: HarnessSchema.strict().optional(),
|
|
2251
|
+
autostart: z.boolean().optional()
|
|
2252
|
+
}).strict()),
|
|
2277
2253
|
previews: PreviewsSchema,
|
|
2278
2254
|
credentialSlots: z.record(WorkloadNameSchema, CredentialSlotSchema),
|
|
2279
2255
|
resources: ResourcesSchema.strict(),
|
|
@@ -2300,65 +2276,6 @@ const WorkloadTemplateSnapshotSchema = z.strictObject({
|
|
|
2300
2276
|
message: "snapshot identity does not match its immutable manifest"
|
|
2301
2277
|
});
|
|
2302
2278
|
});
|
|
2303
|
-
//#endregion
|
|
2304
|
-
//#region ../contracts/src/templates/template-runtime.ts
|
|
2305
|
-
const LEGACY_AGENTAPI_SERVICE = ServiceSchema.parse({
|
|
2306
|
-
baseUrl: "http://127.0.0.1:3284",
|
|
2307
|
-
routes: [
|
|
2308
|
-
{
|
|
2309
|
-
method: "GET",
|
|
2310
|
-
path: "/status"
|
|
2311
|
-
},
|
|
2312
|
-
{
|
|
2313
|
-
method: "GET",
|
|
2314
|
-
path: "/messages",
|
|
2315
|
-
query: ["after"]
|
|
2316
|
-
},
|
|
2317
|
-
{
|
|
2318
|
-
method: "POST",
|
|
2319
|
-
path: "/message"
|
|
2320
|
-
}
|
|
2321
|
-
]
|
|
2322
|
-
});
|
|
2323
|
-
const AGENTAPI_SERVICE = ServiceSchema.parse({
|
|
2324
|
-
...LEGACY_AGENTAPI_SERVICE,
|
|
2325
|
-
routes: [...LEGACY_AGENTAPI_SERVICE.routes, {
|
|
2326
|
-
method: "GET",
|
|
2327
|
-
path: "/events",
|
|
2328
|
-
responseMode: "stream",
|
|
2329
|
-
maxResponseBytes: 4194304,
|
|
2330
|
-
deadlineSeconds: 300
|
|
2331
|
-
}]
|
|
2332
|
-
});
|
|
2333
|
-
function isAgentApiNative(spec) {
|
|
2334
|
-
return "agent" in spec && spec.agent !== void 0;
|
|
2335
|
-
}
|
|
2336
|
-
function agentApiHarness(spec) {
|
|
2337
|
-
if (!isAgentApiNative(spec)) {
|
|
2338
|
-
if (!spec.harness) throw new Error("A workload infrastructure process is not an alpha harness.");
|
|
2339
|
-
return spec.harness;
|
|
2340
|
-
}
|
|
2341
|
-
return {
|
|
2342
|
-
command: [
|
|
2343
|
-
"/usr/local/bin/agentapi",
|
|
2344
|
-
"server",
|
|
2345
|
-
"--type",
|
|
2346
|
-
spec.agent.type,
|
|
2347
|
-
...spec.agent.transport === "acp" ? ["--experimental-acp"] : [],
|
|
2348
|
-
...spec.agent.termWidth === void 0 ? [] : ["--term-width", String(spec.agent.termWidth)],
|
|
2349
|
-
...spec.agent.stateFile === void 0 ? [] : ["--state-file", spec.agent.stateFile],
|
|
2350
|
-
"--port",
|
|
2351
|
-
"3284",
|
|
2352
|
-
"--",
|
|
2353
|
-
...spec.agent.command
|
|
2354
|
-
],
|
|
2355
|
-
env: spec.agent.env,
|
|
2356
|
-
...spec.agent.cwd ? { cwd: spec.agent.cwd } : {}
|
|
2357
|
-
};
|
|
2358
|
-
}
|
|
2359
|
-
function templateServices(spec) {
|
|
2360
|
-
return isAgentApiNative(spec) ? { agent: AGENTAPI_SERVICE } : spec.services ?? {};
|
|
2361
|
-
}
|
|
2362
2279
|
z.object({
|
|
2363
2280
|
name: z.string(),
|
|
2364
2281
|
version: z.string(),
|
|
@@ -2428,7 +2345,6 @@ const CheckpointUploadStatusPayload = z.object({
|
|
|
2428
2345
|
const SOURCE_CREDENTIAL_MAX_BYTES = 65536;
|
|
2429
2346
|
const RestoreModeSchema = z.enum(["provider_installed", "controller_archive"]);
|
|
2430
2347
|
const ExecSpecSchema = z.object({
|
|
2431
|
-
agentapi_native: z.boolean().default(false),
|
|
2432
2348
|
setup: z.array(SetupStepSchema),
|
|
2433
2349
|
harness: HarnessSchema.nullable(),
|
|
2434
2350
|
workload: WaitingRuntimeSpecSchema.optional(),
|
|
@@ -2599,7 +2515,8 @@ const TerminalSessionPageSchema = CursorPageSchema(TerminalSessionSchema);
|
|
|
2599
2515
|
//#region ../contracts/src/protocol/protocol-credentials.ts
|
|
2600
2516
|
const WorkspaceCredentialSchema = z.object({
|
|
2601
2517
|
lease_id: z.uuid(),
|
|
2602
|
-
path: z.string().regex(/^\/run\/pocketcoder\/secrets\/leases\/[A-Za-z0-9][A-Za-z0-9_
|
|
2518
|
+
path: z.string().regex(/^\/run\/pocketcoder\/secrets\/leases\/(?:sessions\/[0-9a-f-]{36}\/)?[A-Za-z0-9][A-Za-z0-9_.%-]{0,127}$/),
|
|
2519
|
+
session_id: z.uuid().optional(),
|
|
2603
2520
|
credential: z.string().min(1).max(SOURCE_CREDENTIAL_MAX_BYTES).refine((value) => !value.includes("\0")),
|
|
2604
2521
|
expires_at: z.iso.datetime(),
|
|
2605
2522
|
purpose: z.enum(["setup-issuer", "runtime-issuer"])
|
|
@@ -2617,6 +2534,9 @@ const CredentialInstalledPayload = z.object({
|
|
|
2617
2534
|
previous_lease_id: z.uuid(),
|
|
2618
2535
|
lease_id: z.uuid()
|
|
2619
2536
|
});
|
|
2537
|
+
const CredentialInstallPayload = z.object({ credentials: z.array(WorkspaceCredentialSchema).min(1).max(64) });
|
|
2538
|
+
const CredentialRemovePayload = z.object({ session_id: z.uuid() });
|
|
2539
|
+
const CredentialInstallAckPayload = z.object({ lease_ids: z.array(z.uuid()).min(1).max(64) });
|
|
2620
2540
|
//#endregion
|
|
2621
2541
|
//#region ../contracts/src/protocol/protocol-stream.ts
|
|
2622
2542
|
const ProxyStreamStartPayload = z.object({
|
|
@@ -2705,7 +2625,9 @@ const EnvelopeBase = z.object({
|
|
|
2705
2625
|
z.literal(10),
|
|
2706
2626
|
z.literal(11),
|
|
2707
2627
|
z.literal(12),
|
|
2708
|
-
z.literal(13)
|
|
2628
|
+
z.literal(13),
|
|
2629
|
+
z.literal(14),
|
|
2630
|
+
z.literal(15)
|
|
2709
2631
|
]),
|
|
2710
2632
|
workspace_id: z.uuid(),
|
|
2711
2633
|
connection_id: z.uuid(),
|
|
@@ -2719,25 +2641,17 @@ const RegisteredPayload = z.object({
|
|
|
2719
2641
|
version: z.string(),
|
|
2720
2642
|
digest: z.string()
|
|
2721
2643
|
}),
|
|
2722
|
-
agentapi_version: z.string().optional(),
|
|
2723
2644
|
services: z.array(z.string()),
|
|
2724
2645
|
pid: z.number().int().positive()
|
|
2725
2646
|
});
|
|
2726
|
-
const HeartbeatPayload = z.object({
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
]),
|
|
2735
|
-
agentapi_state: z.enum([
|
|
2736
|
-
"unknown",
|
|
2737
|
-
"stable",
|
|
2738
|
-
"running"
|
|
2739
|
-
]).optional()
|
|
2740
|
-
});
|
|
2647
|
+
const HeartbeatPayload = z.object({ child: z.enum([
|
|
2648
|
+
"starting",
|
|
2649
|
+
"setup",
|
|
2650
|
+
"waiting",
|
|
2651
|
+
"running",
|
|
2652
|
+
"exited",
|
|
2653
|
+
"terminating"
|
|
2654
|
+
]) });
|
|
2741
2655
|
const ProcessStatePayload = z.object({
|
|
2742
2656
|
phase: z.enum([
|
|
2743
2657
|
"starting",
|
|
@@ -2852,6 +2766,10 @@ z.discriminatedUnion("type", [
|
|
|
2852
2766
|
type: z.literal("credential_installed"),
|
|
2853
2767
|
payload: CredentialInstalledPayload
|
|
2854
2768
|
}),
|
|
2769
|
+
EnvelopeBase.extend({
|
|
2770
|
+
type: z.literal("credential_install_ack"),
|
|
2771
|
+
payload: CredentialInstallAckPayload
|
|
2772
|
+
}),
|
|
2855
2773
|
EnvelopeBase.extend({
|
|
2856
2774
|
type: z.literal("setup_complete"),
|
|
2857
2775
|
payload: z.object({ request_id: z.uuid() })
|
|
@@ -3031,6 +2949,14 @@ z.discriminatedUnion("type", [
|
|
|
3031
2949
|
type: z.literal("credential_installed_ack"),
|
|
3032
2950
|
payload: CredentialInstalledPayload
|
|
3033
2951
|
}),
|
|
2952
|
+
EnvelopeBase.extend({
|
|
2953
|
+
type: z.literal("credential_install"),
|
|
2954
|
+
payload: CredentialInstallPayload
|
|
2955
|
+
}),
|
|
2956
|
+
EnvelopeBase.extend({
|
|
2957
|
+
type: z.literal("credential_remove"),
|
|
2958
|
+
payload: CredentialRemovePayload
|
|
2959
|
+
}),
|
|
3034
2960
|
EnvelopeBase.extend({
|
|
3035
2961
|
type: z.literal("setup_complete_ack"),
|
|
3036
2962
|
payload: z.object({ request_id: z.uuid() })
|
|
@@ -3140,82 +3066,750 @@ z.strictObject({
|
|
|
3140
3066
|
root: fileIdentity,
|
|
3141
3067
|
lock: fileIdentity
|
|
3142
3068
|
});
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3069
|
+
//#endregion
|
|
3070
|
+
//#region ../contracts/src/budgets/policy.ts
|
|
3071
|
+
const BudgetPolicyWriteSchema = z.strictObject({
|
|
3072
|
+
scopeId: z.uuid(),
|
|
3073
|
+
revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3074
|
+
period: z.enum(["utc_day", "utc_month"]),
|
|
3075
|
+
limits: z.strictObject({
|
|
3076
|
+
workspaceStarts: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable(),
|
|
3077
|
+
maxActiveWorkspaces: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable(),
|
|
3078
|
+
maxRunningRequestsPerSession: z.literal(1),
|
|
3079
|
+
maxChatProcessesPerWorkspace: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER)
|
|
3080
|
+
})
|
|
3147
3081
|
});
|
|
3148
|
-
z.
|
|
3082
|
+
const BudgetPolicySchema = BudgetPolicyWriteSchema.extend({ effectiveAt: z.iso.datetime({ offset: true }) });
|
|
3083
|
+
//#endregion
|
|
3084
|
+
//#region ../contracts/src/budgets/usage.ts
|
|
3085
|
+
const BudgetUsageSchema = z.strictObject({
|
|
3086
|
+
scopeId: z.uuid(),
|
|
3087
|
+
policyRevision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3088
|
+
periodStart: z.iso.datetime({ offset: true }),
|
|
3089
|
+
periodEnd: z.iso.datetime({ offset: true }),
|
|
3090
|
+
workspaceStarts: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
3091
|
+
activeWorkspaces: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
3092
|
+
asOf: z.iso.datetime({ offset: true })
|
|
3093
|
+
});
|
|
3094
|
+
const CleanupReceiptFieldsSchema = z.strictObject({
|
|
3095
|
+
workspaceId: z.uuid(),
|
|
3096
|
+
generationId: z.string().min(1).max(256),
|
|
3097
|
+
revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3098
|
+
state: z.enum(["pending", "proved"]),
|
|
3099
|
+
basis: z.enum([
|
|
3100
|
+
"never_launched",
|
|
3101
|
+
"processes_exited",
|
|
3102
|
+
"provider_fenced"
|
|
3103
|
+
]).nullable(),
|
|
3104
|
+
observedAt: z.iso.datetime({ offset: true }),
|
|
3105
|
+
capacityReleasedAt: z.iso.datetime({ offset: true }).nullable()
|
|
3106
|
+
});
|
|
3107
|
+
const CleanupReceiptSchema = z.union([CleanupReceiptFieldsSchema.extend({
|
|
3108
|
+
state: z.literal("pending"),
|
|
3109
|
+
basis: z.null(),
|
|
3110
|
+
capacityReleasedAt: z.null()
|
|
3111
|
+
}), CleanupReceiptFieldsSchema.extend({
|
|
3112
|
+
state: z.literal("proved"),
|
|
3113
|
+
basis: z.enum([
|
|
3114
|
+
"never_launched",
|
|
3115
|
+
"processes_exited",
|
|
3116
|
+
"provider_fenced"
|
|
3117
|
+
])
|
|
3118
|
+
})]);
|
|
3119
|
+
//#endregion
|
|
3120
|
+
//#region ../contracts/src/workspaces/lifetime.ts
|
|
3121
|
+
const LifetimeExtensionSchema = z.strictObject({
|
|
3122
|
+
extensionId: z.uuid(),
|
|
3123
|
+
expectedRevision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
3124
|
+
deadlineAt: z.iso.datetime()
|
|
3125
|
+
});
|
|
3126
|
+
const LifetimeReceiptSchema = LifetimeExtensionSchema.extend({
|
|
3127
|
+
workspaceId: z.uuid(),
|
|
3128
|
+
revision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
3129
|
+
ceilingAt: z.iso.datetime()
|
|
3130
|
+
});
|
|
3131
|
+
//#endregion
|
|
3132
|
+
//#region ../contracts/src/workspaces/service-control.ts
|
|
3133
|
+
const ServiceStartSchema = z.strictObject({ startId: z.uuid() });
|
|
3134
|
+
const ServiceReceiptSchema = z.strictObject({
|
|
3149
3135
|
workspaceId: z.uuid(),
|
|
3150
3136
|
incarnationId: z.string().min(1).max(256),
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3137
|
+
name: z.string().regex(/^[a-z][a-z0-9-]{0,62}$/),
|
|
3138
|
+
startId: z.uuid().nullable(),
|
|
3139
|
+
attemptId: z.uuid().nullable(),
|
|
3140
|
+
state: z.enum([
|
|
3141
|
+
"stopped",
|
|
3142
|
+
"starting",
|
|
3143
|
+
"running",
|
|
3144
|
+
"exited",
|
|
3145
|
+
"lost"
|
|
3146
|
+
]),
|
|
3147
|
+
pid: z.number().int().positive().nullable(),
|
|
3148
|
+
exitCode: z.number().int().nullable(),
|
|
3149
|
+
listener: z.enum([
|
|
3150
|
+
"unknown",
|
|
3151
|
+
"healthy",
|
|
3152
|
+
"unhealthy"
|
|
3153
|
+
])
|
|
3157
3154
|
});
|
|
3158
3155
|
//#endregion
|
|
3159
|
-
//#region ../contracts/src/
|
|
3160
|
-
const
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
]);
|
|
3169
|
-
z.strictObject({
|
|
3170
|
-
acceptance: WorkloadAcceptanceSchema,
|
|
3171
|
-
conversationIdentity: ConversationRequestIdentitySchema.nullable(),
|
|
3172
|
-
outcome: JsonValueSchema.nullable(),
|
|
3173
|
-
acceptedAt: z.iso.datetime(),
|
|
3174
|
-
dispatchClaimedAt: z.iso.datetime().nullable(),
|
|
3175
|
-
phase: ExecutionPhaseSchema,
|
|
3176
|
-
cancel: z.strictObject({
|
|
3177
|
-
cancelId: z.uuid(),
|
|
3178
|
-
requestedAt: z.iso.datetime()
|
|
3179
|
-
}).nullable(),
|
|
3180
|
-
settledAt: z.iso.datetime().nullable(),
|
|
3181
|
-
acknowledgedAt: z.iso.datetime().nullable(),
|
|
3182
|
-
finalizedAt: z.iso.datetime().nullable()
|
|
3156
|
+
//#region ../contracts/src/sessions/files.ts
|
|
3157
|
+
const MAX_SESSION_FILE_REFERENCES = 1e3;
|
|
3158
|
+
const InputReferenceSchema = z.strictObject({
|
|
3159
|
+
inputId: z.uuid(),
|
|
3160
|
+
versionId: z.uuid(),
|
|
3161
|
+
sha256: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
3162
|
+
name: z.string().min(1).max(255),
|
|
3163
|
+
mediaType: AttachmentMediaTypeSchema,
|
|
3164
|
+
sizeBytes: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER)
|
|
3183
3165
|
});
|
|
3184
|
-
z.strictObject({
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3166
|
+
const InputUploadSchema = z.strictObject({
|
|
3167
|
+
inputId: z.uuid(),
|
|
3168
|
+
name: z.string().min(1).max(255),
|
|
3169
|
+
mediaType: AttachmentMediaTypeSchema,
|
|
3170
|
+
sizeBytes: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
3171
|
+
sha256: z.string().regex(/^sha256:[a-f0-9]{64}$/)
|
|
3190
3172
|
});
|
|
3191
|
-
|
|
3192
|
-
z.
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3173
|
+
const InputObjectSchema = z.strictObject({
|
|
3174
|
+
sessionId: z.uuid(),
|
|
3175
|
+
reference: InputReferenceSchema,
|
|
3176
|
+
state: z.enum([
|
|
3177
|
+
"uploading",
|
|
3178
|
+
"ready",
|
|
3179
|
+
"rejected",
|
|
3180
|
+
"expired"
|
|
3181
|
+
]),
|
|
3182
|
+
expiresAt: z.iso.datetime({ offset: true })
|
|
3200
3183
|
});
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3184
|
+
const ExportObjectSchema = z.strictObject({
|
|
3185
|
+
exportId: z.uuid(),
|
|
3186
|
+
sessionId: z.uuid(),
|
|
3187
|
+
requestId: z.uuid(),
|
|
3188
|
+
versionId: z.uuid(),
|
|
3189
|
+
sha256: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
3190
|
+
name: z.string().min(1).max(255),
|
|
3191
|
+
mediaType: AttachmentMediaTypeSchema,
|
|
3192
|
+
sizeBytes: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
3193
|
+
completeness: z.enum(["complete", "partial"]),
|
|
3194
|
+
availability: z.enum([
|
|
3195
|
+
"published",
|
|
3196
|
+
"expired",
|
|
3197
|
+
"unavailable"
|
|
3198
|
+
]),
|
|
3199
|
+
expiresAt: z.iso.datetime({ offset: true })
|
|
3200
|
+
});
|
|
3201
|
+
//#endregion
|
|
3202
|
+
//#region ../contracts/src/sessions/collection.ts
|
|
3203
|
+
const fields = z.strictObject({
|
|
3204
|
+
sessionId: z.uuid(),
|
|
3205
|
+
requestId: z.uuid(),
|
|
3206
|
+
revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3207
|
+
state: z.enum([
|
|
3208
|
+
"pending",
|
|
3209
|
+
"finalizing",
|
|
3210
|
+
"settled"
|
|
3211
|
+
]),
|
|
3212
|
+
completeness: z.enum([
|
|
3213
|
+
"complete",
|
|
3214
|
+
"partial",
|
|
3215
|
+
"lost"
|
|
3216
|
+
]).nullable(),
|
|
3217
|
+
manifestDigest: z.string().regex(/^sha256:[a-f0-9]{64}$/).nullable(),
|
|
3218
|
+
objects: z.array(ExportObjectSchema).max(MAX_SESSION_FILE_REFERENCES),
|
|
3219
|
+
errors: z.array(z.string().min(1).max(512)).max(100),
|
|
3220
|
+
settledAt: z.iso.datetime({ offset: true }).nullable(),
|
|
3221
|
+
expiresAt: z.iso.datetime({ offset: true }).nullable(),
|
|
3222
|
+
cleanupState: z.enum([
|
|
3223
|
+
"not_required",
|
|
3224
|
+
"pending",
|
|
3225
|
+
"complete"
|
|
3226
|
+
])
|
|
3227
|
+
});
|
|
3228
|
+
const CollectionResultSchema = z.union([fields.extend({
|
|
3229
|
+
state: z.enum(["pending", "finalizing"]),
|
|
3230
|
+
completeness: z.null(),
|
|
3231
|
+
manifestDigest: z.null(),
|
|
3232
|
+
settledAt: z.null(),
|
|
3233
|
+
expiresAt: z.null()
|
|
3234
|
+
}), fields.extend({
|
|
3235
|
+
state: z.literal("settled"),
|
|
3236
|
+
completeness: z.enum([
|
|
3237
|
+
"complete",
|
|
3238
|
+
"partial",
|
|
3239
|
+
"lost"
|
|
3240
|
+
]),
|
|
3241
|
+
manifestDigest: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
3242
|
+
settledAt: z.iso.datetime({ offset: true }),
|
|
3243
|
+
expiresAt: z.iso.datetime({ offset: true })
|
|
3244
|
+
})]).superRefine((value, ctx) => {
|
|
3245
|
+
if (value.completeness && value.completeness === "complete" !== (value.errors.length === 0)) ctx.addIssue({
|
|
3246
|
+
code: "custom",
|
|
3247
|
+
path: ["errors"],
|
|
3248
|
+
message: "Collection errors must agree with completeness"
|
|
3249
|
+
});
|
|
3250
|
+
for (const object of value.objects) if (object.sessionId !== value.sessionId || object.requestId !== value.requestId) ctx.addIssue({
|
|
3251
|
+
code: "custom",
|
|
3252
|
+
path: ["objects"],
|
|
3253
|
+
message: "Collection object owner mismatch"
|
|
3254
|
+
});
|
|
3255
|
+
});
|
|
3256
|
+
//#endregion
|
|
3257
|
+
//#region ../contracts/src/sessions/profile.ts
|
|
3258
|
+
const ExecutionProfileSchema = z.strictObject({
|
|
3259
|
+
profileId: z.uuid(),
|
|
3260
|
+
revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3261
|
+
isolationScopeId: z.uuid(),
|
|
3262
|
+
budgetScopeIds: z.array(z.uuid()).min(1).max(1e3).refine((items) => new Set(items).size === items.length, "Values must be unique"),
|
|
3263
|
+
templateDigest: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
3264
|
+
credentialBindingId: z.uuid().nullable(),
|
|
3265
|
+
credentialPlacement: z.enum(["exclusive", "shared"]).optional()
|
|
3266
|
+
}).refine((profile) => profile.credentialBindingId !== null || profile.credentialPlacement === void 0, {
|
|
3267
|
+
message: "Only a credentialed profile can choose its credential placement",
|
|
3268
|
+
path: ["credentialPlacement"]
|
|
3269
|
+
});
|
|
3270
|
+
const SessionCreateSchema = z.strictObject({
|
|
3271
|
+
sessionId: z.uuid(),
|
|
3272
|
+
profileId: z.uuid(),
|
|
3273
|
+
profileRevision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER)
|
|
3274
|
+
});
|
|
3275
|
+
const SessionSchema = z.strictObject({
|
|
3276
|
+
sessionId: z.uuid(),
|
|
3277
|
+
profileId: z.uuid(),
|
|
3278
|
+
profileRevision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3279
|
+
revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3280
|
+
state: z.enum([
|
|
3281
|
+
"provisioning",
|
|
3282
|
+
"ready",
|
|
3283
|
+
"suspended",
|
|
3284
|
+
"closed",
|
|
3285
|
+
"failed"
|
|
3286
|
+
]),
|
|
3287
|
+
reasonCode: z.string().min(1).max(256).nullable(),
|
|
3288
|
+
createdAt: z.iso.datetime({ offset: true }),
|
|
3289
|
+
updatedAt: z.iso.datetime({ offset: true })
|
|
3290
|
+
});
|
|
3291
|
+
//#endregion
|
|
3292
|
+
//#region ../contracts/src/sessions/request.ts
|
|
3293
|
+
const RequestInputSchema = z.strictObject({
|
|
3294
|
+
requestId: z.uuid(),
|
|
3295
|
+
message: z.string().min(1).max(262144).refine((value) => value.isWellFormed(), "Message must contain valid Unicode").refine((value) => new TextEncoder().encode(value).length <= 262144, "Message exceeds 256 KiB UTF-8"),
|
|
3296
|
+
attachments: z.array(InputReferenceSchema).max(MAX_SESSION_FILE_REFERENCES),
|
|
3297
|
+
dispatchDeadline: z.iso.datetime({ offset: true })
|
|
3298
|
+
});
|
|
3299
|
+
const RequestFieldsSchema = z.strictObject({
|
|
3300
|
+
sessionId: z.uuid(),
|
|
3301
|
+
requestId: z.uuid(),
|
|
3302
|
+
turnId: z.uuid(),
|
|
3303
|
+
inputFingerprint: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
3304
|
+
revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3305
|
+
state: z.enum([
|
|
3208
3306
|
"accepted",
|
|
3307
|
+
"waiting",
|
|
3209
3308
|
"running",
|
|
3210
|
-
"
|
|
3211
|
-
"
|
|
3309
|
+
"checking_outcome",
|
|
3310
|
+
"terminal"
|
|
3212
3311
|
]),
|
|
3213
|
-
outcome:
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3312
|
+
outcome: z.enum([
|
|
3313
|
+
"completed",
|
|
3314
|
+
"failed",
|
|
3315
|
+
"canceled",
|
|
3316
|
+
"interrupted",
|
|
3317
|
+
"lost"
|
|
3318
|
+
]).nullable(),
|
|
3319
|
+
reasonCode: z.string().min(1).max(256).nullable(),
|
|
3320
|
+
acceptedAt: z.iso.datetime({ offset: true }),
|
|
3321
|
+
startedAt: z.iso.datetime({ offset: true }).nullable(),
|
|
3322
|
+
endedAt: z.iso.datetime({ offset: true }).nullable(),
|
|
3323
|
+
dispatchDeadline: z.iso.datetime({ offset: true }),
|
|
3324
|
+
collection: CollectionResultSchema,
|
|
3325
|
+
finalResponse: z.string().max(1048576).nullable()
|
|
3326
|
+
});
|
|
3327
|
+
const RequestSchema = z.union([RequestFieldsSchema.extend({
|
|
3328
|
+
state: z.literal("terminal"),
|
|
3329
|
+
outcome: z.enum([
|
|
3330
|
+
"completed",
|
|
3331
|
+
"failed",
|
|
3332
|
+
"canceled",
|
|
3333
|
+
"interrupted",
|
|
3334
|
+
"lost"
|
|
3335
|
+
])
|
|
3336
|
+
}), RequestFieldsSchema.extend({
|
|
3337
|
+
state: z.enum([
|
|
3338
|
+
"accepted",
|
|
3339
|
+
"waiting",
|
|
3340
|
+
"running",
|
|
3341
|
+
"checking_outcome"
|
|
3342
|
+
]),
|
|
3343
|
+
outcome: z.null(),
|
|
3344
|
+
endedAt: z.null()
|
|
3345
|
+
})]).superRefine((request, ctx) => {
|
|
3346
|
+
if (request.sessionId !== request.collection.sessionId || request.requestId !== request.collection.requestId) ctx.addIssue({
|
|
3347
|
+
code: "custom",
|
|
3348
|
+
path: ["collection"],
|
|
3349
|
+
message: "Collection owner mismatch"
|
|
3350
|
+
});
|
|
3351
|
+
});
|
|
3352
|
+
const CancelCommandSchema = z.strictObject({ cancelId: z.uuid() });
|
|
3353
|
+
const CancelReceiptFieldsSchema = z.strictObject({
|
|
3354
|
+
sessionId: z.uuid(),
|
|
3355
|
+
requestId: z.uuid().nullable(),
|
|
3356
|
+
cancelId: z.uuid(),
|
|
3357
|
+
scope: z.enum(["request", "session"]),
|
|
3358
|
+
state: z.enum(["pending", "completed"]),
|
|
3359
|
+
acceptedAt: z.iso.datetime({ offset: true }),
|
|
3360
|
+
completedAt: z.iso.datetime({ offset: true }).nullable(),
|
|
3361
|
+
cancelDeadline: z.iso.datetime({ offset: true })
|
|
3362
|
+
});
|
|
3363
|
+
const CancelReceiptSchema = z.union([CancelReceiptFieldsSchema.extend({
|
|
3364
|
+
scope: z.literal("request"),
|
|
3365
|
+
requestId: z.uuid()
|
|
3366
|
+
}), CancelReceiptFieldsSchema.extend({
|
|
3367
|
+
scope: z.literal("session"),
|
|
3368
|
+
requestId: z.null()
|
|
3369
|
+
})]).superRefine((receipt, ctx) => {
|
|
3370
|
+
if (receipt.state === "completed" !== (receipt.completedAt !== null)) ctx.addIssue({
|
|
3371
|
+
code: "custom",
|
|
3372
|
+
path: ["completedAt"],
|
|
3373
|
+
message: "Completion time must agree with state"
|
|
3374
|
+
});
|
|
3375
|
+
});
|
|
3376
|
+
//#endregion
|
|
3377
|
+
//#region ../contracts/src/sessions/event.ts
|
|
3378
|
+
const RuntimeEventFieldsSchema = z.strictObject({
|
|
3379
|
+
eventId: z.uuid(),
|
|
3380
|
+
cursor: z.string().min(1).max(256),
|
|
3381
|
+
sessionId: z.uuid(),
|
|
3382
|
+
requestId: z.uuid().nullable(),
|
|
3383
|
+
sequence: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3384
|
+
revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
|
|
3385
|
+
occurredAt: z.iso.datetime({ offset: true }).nullable(),
|
|
3386
|
+
recordedAt: z.iso.datetime({ offset: true }),
|
|
3387
|
+
kind: z.enum([
|
|
3388
|
+
"session.updated",
|
|
3389
|
+
"request.updated",
|
|
3390
|
+
"output.published"
|
|
3391
|
+
]),
|
|
3392
|
+
data: z.union([
|
|
3393
|
+
SessionSchema,
|
|
3394
|
+
RequestSchema,
|
|
3395
|
+
ExportObjectSchema
|
|
3396
|
+
])
|
|
3397
|
+
});
|
|
3398
|
+
const RuntimeEventSchema = z.discriminatedUnion("kind", [
|
|
3399
|
+
RuntimeEventFieldsSchema.extend({
|
|
3400
|
+
kind: z.literal("session.updated"),
|
|
3401
|
+
requestId: z.null(),
|
|
3402
|
+
data: SessionSchema
|
|
3403
|
+
}),
|
|
3404
|
+
RuntimeEventFieldsSchema.extend({
|
|
3405
|
+
kind: z.literal("request.updated"),
|
|
3406
|
+
requestId: z.uuid(),
|
|
3407
|
+
data: RequestSchema
|
|
3408
|
+
}),
|
|
3409
|
+
RuntimeEventFieldsSchema.extend({
|
|
3410
|
+
kind: z.literal("output.published"),
|
|
3411
|
+
requestId: z.uuid(),
|
|
3412
|
+
data: ExportObjectSchema
|
|
3413
|
+
})
|
|
3414
|
+
]).superRefine((event, ctx) => {
|
|
3415
|
+
if (event.sessionId !== event.data.sessionId) ctx.addIssue({
|
|
3416
|
+
code: "custom",
|
|
3417
|
+
path: ["sessionId"],
|
|
3418
|
+
message: "Session identity mismatch"
|
|
3419
|
+
});
|
|
3420
|
+
if (event.kind !== "session.updated" && event.requestId !== event.data.requestId) ctx.addIssue({
|
|
3421
|
+
code: "custom",
|
|
3422
|
+
path: ["requestId"],
|
|
3423
|
+
message: "Request identity mismatch"
|
|
3424
|
+
});
|
|
3425
|
+
if (event.kind !== "output.published" && event.revision !== event.data.revision) ctx.addIssue({
|
|
3426
|
+
code: "custom",
|
|
3427
|
+
path: ["revision"],
|
|
3428
|
+
message: "Resource revision mismatch"
|
|
3429
|
+
});
|
|
3430
|
+
});
|
|
3431
|
+
const ErrorSchema = z.strictObject({ error: z.strictObject({
|
|
3432
|
+
code: z.string().min(1).max(256),
|
|
3433
|
+
message: z.string().max(512),
|
|
3434
|
+
retry: z.enum([
|
|
3435
|
+
"never",
|
|
3436
|
+
"same_identity",
|
|
3437
|
+
"after_capacity_change",
|
|
3438
|
+
"reconcile"
|
|
3439
|
+
]),
|
|
3440
|
+
retryAfterSeconds: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable(),
|
|
3441
|
+
requestId: z.uuid().nullable()
|
|
3442
|
+
}) });
|
|
3443
|
+
//#endregion
|
|
3444
|
+
//#region ../contracts/src/sessions/fingerprint.ts
|
|
3445
|
+
const LogicalRequestInputSchema = RequestInputSchema.extend({
|
|
3446
|
+
sessionId: z.uuid(),
|
|
3447
|
+
profileId: z.uuid(),
|
|
3448
|
+
profileRevision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER)
|
|
3449
|
+
}).superRefine((input, ctx) => {
|
|
3450
|
+
for (const [index, attachment] of input.attachments.entries()) for (const field of ["name", "mediaType"]) if (!attachment[field].isWellFormed()) ctx.addIssue({
|
|
3451
|
+
code: "custom",
|
|
3452
|
+
path: [
|
|
3453
|
+
"attachments",
|
|
3454
|
+
index,
|
|
3455
|
+
field
|
|
3456
|
+
],
|
|
3457
|
+
message: "Invalid Unicode"
|
|
3458
|
+
});
|
|
3459
|
+
});
|
|
3460
|
+
function fingerprintRequest(input) {
|
|
3461
|
+
return digestOf(LogicalRequestInputSchema.parse(input));
|
|
3462
|
+
}
|
|
3463
|
+
//#endregion
|
|
3464
|
+
//#region ../contracts/src/sessions/pages.ts
|
|
3465
|
+
const ManagedHistoryQuerySchema = z.strictObject({
|
|
3466
|
+
cursor: z.string().min(1).max(4096).optional(),
|
|
3467
|
+
limit: z.number().int().min(1).max(200).optional()
|
|
3468
|
+
});
|
|
3469
|
+
const ManagedHistoryPageSchema = z.strictObject({
|
|
3470
|
+
records: z.array(ConversationRecordDocumentSchema),
|
|
3471
|
+
nextCursor: z.string().min(1).max(4096).nullable(),
|
|
3472
|
+
eventCursor: z.string().min(1).max(4096)
|
|
3473
|
+
});
|
|
3474
|
+
const ManagedExportPageSchema = z.strictObject({
|
|
3475
|
+
items: z.array(ExportObjectSchema),
|
|
3476
|
+
nextCursor: z.string().min(1).max(4096).nullable()
|
|
3477
|
+
});
|
|
3478
|
+
//#endregion
|
|
3479
|
+
//#region ../contracts/src/sessions/placement.ts
|
|
3480
|
+
function managedPlacement(principalId, sessionId, input) {
|
|
3481
|
+
const profile = ExecutionProfileSchema.parse(input);
|
|
3482
|
+
const mode = profile.credentialBindingId === null || profile.credentialPlacement === "shared" ? "shared" : "exclusive";
|
|
3483
|
+
return {
|
|
3484
|
+
mode,
|
|
3485
|
+
key: digestOf({
|
|
3486
|
+
principalId,
|
|
3487
|
+
profile,
|
|
3488
|
+
sessionId: mode === "exclusive" ? sessionId : null
|
|
3489
|
+
})
|
|
3490
|
+
};
|
|
3491
|
+
}
|
|
3492
|
+
const MANAGED_SESSION_METADATA = "pocketcoder.managed-session";
|
|
3493
|
+
//#endregion
|
|
3494
|
+
//#region ../contracts/src/sessions/provisioning.ts
|
|
3495
|
+
const BudgetScopeGrantSchema = z.strictObject({
|
|
3496
|
+
principalId: z.uuid(),
|
|
3497
|
+
installation: z.boolean()
|
|
3498
|
+
});
|
|
3499
|
+
const CredentialBindingSchema = z.strictObject({
|
|
3500
|
+
bindingId: z.uuid(),
|
|
3501
|
+
principalId: z.uuid(),
|
|
3502
|
+
secretName: z.string().min(1).max(128),
|
|
3503
|
+
secretVersionId: z.uuid().optional(),
|
|
3504
|
+
slots: z.array(z.string().min(1).max(128)).min(1).max(100),
|
|
3505
|
+
authorityExpiresAt: z.iso.datetime({ offset: true })
|
|
3506
|
+
});
|
|
3507
|
+
//#endregion
|
|
3508
|
+
//#region ../contracts/src/sessions/states.ts
|
|
3509
|
+
const requestTransitions = {
|
|
3510
|
+
accepted: [
|
|
3511
|
+
"waiting",
|
|
3512
|
+
"running",
|
|
3513
|
+
"checking_outcome",
|
|
3514
|
+
"terminal"
|
|
3515
|
+
],
|
|
3516
|
+
waiting: [
|
|
3517
|
+
"running",
|
|
3518
|
+
"checking_outcome",
|
|
3519
|
+
"terminal"
|
|
3520
|
+
],
|
|
3521
|
+
running: ["checking_outcome", "terminal"],
|
|
3522
|
+
checking_outcome: ["running", "terminal"],
|
|
3523
|
+
terminal: []
|
|
3524
|
+
};
|
|
3525
|
+
const sessionTransitions = {
|
|
3526
|
+
provisioning: [
|
|
3527
|
+
"ready",
|
|
3528
|
+
"suspended",
|
|
3529
|
+
"closed",
|
|
3530
|
+
"failed"
|
|
3531
|
+
],
|
|
3532
|
+
ready: [
|
|
3533
|
+
"provisioning",
|
|
3534
|
+
"suspended",
|
|
3535
|
+
"closed",
|
|
3536
|
+
"failed"
|
|
3537
|
+
],
|
|
3538
|
+
suspended: [
|
|
3539
|
+
"provisioning",
|
|
3540
|
+
"closed",
|
|
3541
|
+
"failed"
|
|
3542
|
+
],
|
|
3543
|
+
closed: [],
|
|
3544
|
+
failed: ["provisioning", "closed"]
|
|
3545
|
+
};
|
|
3546
|
+
const canTransitionRequest = (from, to) => requestTransitions[from].includes(to);
|
|
3547
|
+
const canTransitionSession = (from, to) => sessionTransitions[from].includes(to);
|
|
3548
|
+
const ManagedQueueLimitsSchema = z.strictObject({
|
|
3549
|
+
requests: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
3550
|
+
bytes: z.number().int().positive().max(Number.MAX_SAFE_INTEGER)
|
|
3551
|
+
});
|
|
3552
|
+
//#endregion
|
|
3553
|
+
//#region ../contracts/src/sessions/schemas.ts
|
|
3554
|
+
const MANAGED_CONTRACT_REVISION = "pocketcoder.managed/v1";
|
|
3555
|
+
const managedSchemas = {
|
|
3556
|
+
ExecutionProfile: ExecutionProfileSchema,
|
|
3557
|
+
BudgetScopeGrant: BudgetScopeGrantSchema,
|
|
3558
|
+
CredentialBinding: CredentialBindingSchema,
|
|
3559
|
+
SessionCreate: SessionCreateSchema,
|
|
3560
|
+
Session: SessionSchema,
|
|
3561
|
+
InputReference: InputReferenceSchema,
|
|
3562
|
+
InputUpload: InputUploadSchema,
|
|
3563
|
+
InputObject: InputObjectSchema,
|
|
3564
|
+
ExportObject: ExportObjectSchema,
|
|
3565
|
+
CollectionResult: CollectionResultSchema,
|
|
3566
|
+
RequestInput: RequestInputSchema,
|
|
3567
|
+
Request: RequestSchema,
|
|
3568
|
+
CancelCommand: CancelCommandSchema,
|
|
3569
|
+
CancelReceipt: CancelReceiptSchema,
|
|
3570
|
+
RuntimeEvent: RuntimeEventSchema,
|
|
3571
|
+
Error: ErrorSchema,
|
|
3572
|
+
WireError: ErrorEnvelopeSchema,
|
|
3573
|
+
BudgetPolicy: BudgetPolicySchema,
|
|
3574
|
+
BudgetPolicyWrite: BudgetPolicyWriteSchema,
|
|
3575
|
+
BudgetUsage: BudgetUsageSchema,
|
|
3576
|
+
CleanupReceipt: CleanupReceiptSchema,
|
|
3577
|
+
HistoryPage: ManagedHistoryPageSchema,
|
|
3578
|
+
OpenTurns: z.object({ turns: z.array(ConversationLiveEventSchema) }),
|
|
3579
|
+
ExportPage: ManagedExportPageSchema,
|
|
3580
|
+
ServiceStart: ServiceStartSchema,
|
|
3581
|
+
ServiceReceipt: ServiceReceiptSchema,
|
|
3582
|
+
LifetimeExtension: LifetimeExtensionSchema,
|
|
3583
|
+
LifetimeReceipt: LifetimeReceiptSchema,
|
|
3584
|
+
QueueLimits: ManagedQueueLimitsSchema
|
|
3585
|
+
};
|
|
3586
|
+
//#endregion
|
|
3587
|
+
//#region ../contracts/src/sessions/index.ts
|
|
3588
|
+
var sessions_exports = /* @__PURE__ */ __exportAll({
|
|
3589
|
+
BudgetPolicySchema: () => BudgetPolicySchema,
|
|
3590
|
+
BudgetPolicyWriteSchema: () => BudgetPolicyWriteSchema,
|
|
3591
|
+
BudgetUsageSchema: () => BudgetUsageSchema,
|
|
3592
|
+
CancelCommandSchema: () => CancelCommandSchema,
|
|
3593
|
+
CancelReceiptSchema: () => CancelReceiptSchema,
|
|
3594
|
+
CleanupReceiptSchema: () => CleanupReceiptSchema,
|
|
3595
|
+
CollectionResultSchema: () => CollectionResultSchema,
|
|
3596
|
+
ErrorSchema: () => ErrorSchema,
|
|
3597
|
+
ExecutionProfileSchema: () => ExecutionProfileSchema,
|
|
3598
|
+
ExportObjectSchema: () => ExportObjectSchema,
|
|
3599
|
+
InputObjectSchema: () => InputObjectSchema,
|
|
3600
|
+
InputReferenceSchema: () => InputReferenceSchema,
|
|
3601
|
+
InputUploadSchema: () => InputUploadSchema,
|
|
3602
|
+
LifetimeExtensionSchema: () => LifetimeExtensionSchema,
|
|
3603
|
+
LifetimeReceiptSchema: () => LifetimeReceiptSchema,
|
|
3604
|
+
LogicalRequestInputSchema: () => LogicalRequestInputSchema,
|
|
3605
|
+
MANAGED_CONTRACT_REVISION: () => MANAGED_CONTRACT_REVISION,
|
|
3606
|
+
MANAGED_SESSION_METADATA: () => MANAGED_SESSION_METADATA,
|
|
3607
|
+
MAX_SESSION_FILE_REFERENCES: () => MAX_SESSION_FILE_REFERENCES,
|
|
3608
|
+
ManagedExportPageSchema: () => ManagedExportPageSchema,
|
|
3609
|
+
ManagedHistoryPageSchema: () => ManagedHistoryPageSchema,
|
|
3610
|
+
ManagedHistoryQuerySchema: () => ManagedHistoryQuerySchema,
|
|
3611
|
+
ManagedQueueLimitsSchema: () => ManagedQueueLimitsSchema,
|
|
3612
|
+
RequestInputSchema: () => RequestInputSchema,
|
|
3613
|
+
RequestSchema: () => RequestSchema,
|
|
3614
|
+
RuntimeEventSchema: () => RuntimeEventSchema,
|
|
3615
|
+
ServiceReceiptSchema: () => ServiceReceiptSchema,
|
|
3616
|
+
ServiceStartSchema: () => ServiceStartSchema,
|
|
3617
|
+
SessionCreateSchema: () => SessionCreateSchema,
|
|
3618
|
+
SessionSchema: () => SessionSchema,
|
|
3619
|
+
canTransitionRequest: () => canTransitionRequest,
|
|
3620
|
+
canTransitionSession: () => canTransitionSession,
|
|
3621
|
+
fingerprintRequest: () => fingerprintRequest,
|
|
3622
|
+
managedPlacement: () => managedPlacement,
|
|
3623
|
+
managedSchemas: () => managedSchemas
|
|
3624
|
+
});
|
|
3625
|
+
//#endregion
|
|
3626
|
+
//#region ../contracts/src/templates/session-template.ts
|
|
3627
|
+
function sessionTemplate(input) {
|
|
3628
|
+
const protocol = "pocketcoder.execution/v1";
|
|
3629
|
+
const { producer } = input;
|
|
3630
|
+
return WorkloadTemplateSchema.parse({
|
|
3631
|
+
apiVersion: "pocketcoder.dev/v1",
|
|
3632
|
+
kind: "Template",
|
|
3633
|
+
metadata: { name: input.name },
|
|
3634
|
+
spec: {
|
|
3635
|
+
version: input.version,
|
|
3636
|
+
image: input.image,
|
|
3637
|
+
profile: "service",
|
|
3638
|
+
runtime: {
|
|
3639
|
+
protocol: "pocketcoder.workload/v1",
|
|
3640
|
+
digest: input.runtimeDigest
|
|
3641
|
+
},
|
|
3642
|
+
adapters: { session: {
|
|
3643
|
+
kind: "service",
|
|
3644
|
+
digest: producer.digest,
|
|
3645
|
+
protocol,
|
|
3646
|
+
service: "session",
|
|
3647
|
+
env: {}
|
|
3648
|
+
} },
|
|
3649
|
+
operations: { message: {
|
|
3650
|
+
adapter: "session",
|
|
3651
|
+
inputSchema: {
|
|
3652
|
+
type: "object",
|
|
3653
|
+
properties: { message: { type: "string" } },
|
|
3654
|
+
required: ["message"],
|
|
3655
|
+
additionalProperties: false
|
|
3656
|
+
},
|
|
3657
|
+
requiredCapabilities: [
|
|
3658
|
+
"request-lookup",
|
|
3659
|
+
"deduplicated-accept",
|
|
3660
|
+
"targeted-cancel"
|
|
3661
|
+
],
|
|
3662
|
+
outputRoots: []
|
|
3663
|
+
} },
|
|
3664
|
+
services: { session: {
|
|
3665
|
+
...ServiceSchema.parse({
|
|
3666
|
+
baseUrl: "http://127.0.0.1:3284",
|
|
3667
|
+
healthPath: "/healthz",
|
|
3668
|
+
routes: [
|
|
3669
|
+
"accept",
|
|
3670
|
+
"lookup",
|
|
3671
|
+
"cancel",
|
|
3672
|
+
"ack"
|
|
3673
|
+
].map((action) => ({
|
|
3674
|
+
method: "POST",
|
|
3675
|
+
path: `/executions/${action}`,
|
|
3676
|
+
maxRequestBytes: 1048576,
|
|
3677
|
+
maxResponseBytes: 8388608,
|
|
3678
|
+
deadlineSeconds: 30
|
|
3679
|
+
}))
|
|
3680
|
+
}),
|
|
3681
|
+
process: {
|
|
3682
|
+
command: producer.command,
|
|
3683
|
+
env: producer.env ?? {},
|
|
3684
|
+
...producer.cwd ? { cwd: producer.cwd } : {}
|
|
3685
|
+
}
|
|
3686
|
+
} },
|
|
3687
|
+
previews: {},
|
|
3688
|
+
credentialSlots: {},
|
|
3689
|
+
resources: {
|
|
3690
|
+
cpu: "1",
|
|
3691
|
+
memory: "1Gi"
|
|
3692
|
+
},
|
|
3693
|
+
network: { mode: "unrestricted" },
|
|
3694
|
+
security: SecuritySchema.parse({ writableMemoryPaths: ["/tmp"] }),
|
|
3695
|
+
lifecycle: { timeouts: TimeoutsSchema.parse({}) },
|
|
3696
|
+
limits: {
|
|
3697
|
+
deadlineSeconds: 7200,
|
|
3698
|
+
finalizationSeconds: 30,
|
|
3699
|
+
inputFileBytes: 16777216,
|
|
3700
|
+
stagedInputBytes: 67108864,
|
|
3701
|
+
inputFiles: 100,
|
|
3702
|
+
inFlightTransfers: 2,
|
|
3703
|
+
exportBytes: 16777216,
|
|
3704
|
+
exportFiles: 100,
|
|
3705
|
+
unreferencedInputRetentionSeconds: 3600,
|
|
3706
|
+
exportRetentionSeconds: 86400
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
});
|
|
3710
|
+
}
|
|
3711
|
+
z.strictObject({ manifest: z.union([TemplateManifestSchema, WorkloadTemplateSchema]) });
|
|
3712
|
+
z.object({
|
|
3713
|
+
name: z.string().regex(/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/),
|
|
3714
|
+
version: z.string().min(1).max(256)
|
|
3715
|
+
});
|
|
3716
|
+
z.strictObject({
|
|
3717
|
+
workspaceId: z.uuid(),
|
|
3718
|
+
incarnationId: z.string().min(1).max(256),
|
|
3719
|
+
profiles: z.array(WorkloadProfileSchema),
|
|
3720
|
+
storageProfiles: z.array(z.enum(["controller-readonly/v1", "shared-writer-readonly/v1"])),
|
|
3721
|
+
ceilings: WorkloadLimitsSchema,
|
|
3722
|
+
now: z.iso.datetime(),
|
|
3723
|
+
expiresAt: z.iso.datetime(),
|
|
3724
|
+
installed: InstalledWorkloadSchema.optional()
|
|
3725
|
+
});
|
|
3726
|
+
z.strictObject({
|
|
3727
|
+
requestId: z.uuid(),
|
|
3728
|
+
conversationId: z.uuid(),
|
|
3729
|
+
message: z.string().min(1).max(262144),
|
|
3730
|
+
files: z.array(InputObjectReferenceSchema).max(1e3)
|
|
3731
|
+
});
|
|
3732
|
+
//#endregion
|
|
3733
|
+
//#region ../contracts/src/workspaces/execution-dispatch.ts
|
|
3734
|
+
const ExecutionPhaseSchema = z.enum([
|
|
3735
|
+
"accepted",
|
|
3736
|
+
"dispatching",
|
|
3737
|
+
"running",
|
|
3738
|
+
"terminal",
|
|
3739
|
+
"canceled",
|
|
3740
|
+
"unknown",
|
|
3741
|
+
"lost"
|
|
3742
|
+
]);
|
|
3743
|
+
const ExecutionRecordSchema = z.strictObject({
|
|
3744
|
+
acceptance: WorkloadAcceptanceSchema,
|
|
3745
|
+
conversationIdentity: ConversationRequestIdentitySchema.nullable(),
|
|
3746
|
+
outcome: JsonValueSchema.nullable(),
|
|
3747
|
+
acceptedAt: z.iso.datetime(),
|
|
3748
|
+
dispatchClaimedAt: z.iso.datetime().nullable(),
|
|
3749
|
+
producerSendClaimedAt: z.iso.datetime().optional(),
|
|
3750
|
+
finalizationBasis: z.enum([
|
|
3751
|
+
"never_sent",
|
|
3752
|
+
"producer_acknowledged",
|
|
3753
|
+
"runtime_fenced"
|
|
3754
|
+
]).optional(),
|
|
3755
|
+
phase: ExecutionPhaseSchema,
|
|
3756
|
+
cancel: z.strictObject({
|
|
3757
|
+
cancelId: z.uuid(),
|
|
3758
|
+
requestedAt: z.iso.datetime()
|
|
3759
|
+
}).nullable(),
|
|
3760
|
+
settledAt: z.iso.datetime().nullable(),
|
|
3761
|
+
acknowledgedAt: z.iso.datetime().nullable(),
|
|
3762
|
+
finalizedAt: z.iso.datetime().nullable(),
|
|
3763
|
+
collection: WorkloadExportReferenceSchema.optional(),
|
|
3764
|
+
publicationComplete: z.boolean().optional()
|
|
3765
|
+
});
|
|
3766
|
+
z.strictObject({
|
|
3767
|
+
acceptance: WorkloadAcceptanceSchema,
|
|
3768
|
+
conversationIdentity: ConversationRequestIdentitySchema.optional()
|
|
3769
|
+
}).refine(({ acceptance, conversationIdentity }) => acceptance.execution.owner !== "conversation-request" || conversationIdentity !== void 0, {
|
|
3770
|
+
path: ["conversationIdentity"],
|
|
3771
|
+
message: "Conversation execution requires a conversation identity."
|
|
3772
|
+
});
|
|
3773
|
+
WorkloadCancelSchema.refine((cancel) => cancel.scope === "operation", { message: "Use workspace release for workspace cancellation" });
|
|
3774
|
+
z.strictObject({
|
|
3775
|
+
workspaceId: z.uuid(),
|
|
3776
|
+
callerPrincipalId: z.uuid(),
|
|
3777
|
+
incarnationId: z.string().min(1),
|
|
3778
|
+
template: WorkloadTemplateSnapshotSchema,
|
|
3779
|
+
producer: InstalledWorkloadSchema,
|
|
3780
|
+
readyAt: z.iso.datetime().nullable(),
|
|
3781
|
+
endedAt: z.iso.datetime().nullable()
|
|
3782
|
+
});
|
|
3783
|
+
z.discriminatedUnion("phase", [z.strictObject({
|
|
3784
|
+
execution: WorkloadExecutionReferenceSchema,
|
|
3785
|
+
phase: z.literal("absent")
|
|
3786
|
+
}), z.strictObject({
|
|
3787
|
+
execution: WorkloadExecutionReferenceSchema,
|
|
3788
|
+
fingerprint: WorkloadDigestSchema,
|
|
3789
|
+
phase: z.enum([
|
|
3790
|
+
"accepted",
|
|
3791
|
+
"running",
|
|
3792
|
+
"terminal",
|
|
3793
|
+
"canceled"
|
|
3794
|
+
]),
|
|
3795
|
+
outcome: JsonValueSchema.nullable(),
|
|
3796
|
+
messages: z.array(ConversationMessageInputSchema).max(1024).optional(),
|
|
3797
|
+
publication: z.strictObject({
|
|
3798
|
+
complete: z.boolean(),
|
|
3799
|
+
objects: z.array(z.strictObject({
|
|
3800
|
+
publicationId: z.uuid(),
|
|
3801
|
+
name: z.string().min(1).max(255),
|
|
3802
|
+
mediaType: AttachmentMediaTypeSchema,
|
|
3803
|
+
sizeBytes: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
3804
|
+
digest: WorkloadDigestSchema,
|
|
3805
|
+
contentBase64: z.string()
|
|
3806
|
+
})).max(1e3)
|
|
3807
|
+
}).optional()
|
|
3808
|
+
})]);
|
|
3809
|
+
WorkloadCancelSchema.extend({ fingerprint: WorkloadDigestSchema });
|
|
3810
|
+
//#endregion
|
|
3811
|
+
//#region src/resources/admin/admin.ts
|
|
3812
|
+
var AdministrationApi = class {
|
|
3219
3813
|
transport;
|
|
3220
3814
|
constructor(transport) {
|
|
3221
3815
|
this.transport = transport;
|
|
@@ -3234,106 +3828,6 @@ var AdministrationApi = class {
|
|
|
3234
3828
|
}
|
|
3235
3829
|
};
|
|
3236
3830
|
//#endregion
|
|
3237
|
-
//#region src/transport/errors.ts
|
|
3238
|
-
z.enum(["client.non_json_response", "client.invalid_response"]);
|
|
3239
|
-
var PocketCoderError = class extends Error {
|
|
3240
|
-
code;
|
|
3241
|
-
status;
|
|
3242
|
-
requestId;
|
|
3243
|
-
details;
|
|
3244
|
-
constructor(input) {
|
|
3245
|
-
super(input.message);
|
|
3246
|
-
this.name = "PocketCoderError";
|
|
3247
|
-
this.code = input.code;
|
|
3248
|
-
this.status = input.status;
|
|
3249
|
-
this.requestId = input.requestId;
|
|
3250
|
-
this.details = input.details;
|
|
3251
|
-
}
|
|
3252
|
-
};
|
|
3253
|
-
var ConversationGoneError = class extends PocketCoderError {};
|
|
3254
|
-
var WorkspaceTerminalError = class extends Error {
|
|
3255
|
-
workspace;
|
|
3256
|
-
constructor(workspace) {
|
|
3257
|
-
const reason = workspace.reason_code ?? workspace.failure?.reason_code ?? "no reason";
|
|
3258
|
-
const tail = workspace.failure?.log_tail.trim();
|
|
3259
|
-
super([`workspace ${workspace.id} reached ${workspace.state} (${reason})`, ...tail ? [`failure log:\n${tail}`] : []].join("\n"));
|
|
3260
|
-
this.name = "WorkspaceTerminalError";
|
|
3261
|
-
this.workspace = workspace;
|
|
3262
|
-
}
|
|
3263
|
-
};
|
|
3264
|
-
var AgentNotReadyError = class extends Error {
|
|
3265
|
-
workspaceId;
|
|
3266
|
-
agentState;
|
|
3267
|
-
constructor(workspaceId, agentState, timeoutMs) {
|
|
3268
|
-
super(`agent in workspace ${workspaceId} was still ${agentState} after ${timeoutMs}ms and cannot accept a message`);
|
|
3269
|
-
this.name = "AgentNotReadyError";
|
|
3270
|
-
this.workspaceId = workspaceId;
|
|
3271
|
-
this.agentState = agentState;
|
|
3272
|
-
}
|
|
3273
|
-
};
|
|
3274
|
-
function isPocketCoderErrorCode(value) {
|
|
3275
|
-
return typeof value === "string" && value in ERROR_CODES;
|
|
3276
|
-
}
|
|
3277
|
-
function responseError(response, body) {
|
|
3278
|
-
const parsed = ErrorEnvelopeSchema.safeParse(body);
|
|
3279
|
-
if (!parsed.success) return new PocketCoderError({
|
|
3280
|
-
message: `PocketCoder returned an invalid error response (${response.status})`,
|
|
3281
|
-
code: "client.invalid_response",
|
|
3282
|
-
status: response.status
|
|
3283
|
-
});
|
|
3284
|
-
const { code, message, request_id: requestId, details } = parsed.data.error;
|
|
3285
|
-
return new (code === "conversation.deleted" || code === "conversation.expired" ? ConversationGoneError : PocketCoderError)({
|
|
3286
|
-
message,
|
|
3287
|
-
code,
|
|
3288
|
-
status: response.status,
|
|
3289
|
-
requestId,
|
|
3290
|
-
details
|
|
3291
|
-
});
|
|
3292
|
-
}
|
|
3293
|
-
//#endregion
|
|
3294
|
-
//#region src/resources/agent/agent.ts
|
|
3295
|
-
const DEFAULT_READY_TIMEOUT_MS = 12e4;
|
|
3296
|
-
var AgentApi = class {
|
|
3297
|
-
transport;
|
|
3298
|
-
workspaces;
|
|
3299
|
-
constructor(transport, workspaces) {
|
|
3300
|
-
this.transport = transport;
|
|
3301
|
-
this.workspaces = workspaces;
|
|
3302
|
-
}
|
|
3303
|
-
async sendMessage(workspaceId, input) {
|
|
3304
|
-
await this.workspaces.waitForAgentInput(workspaceId, input.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS, input.signal ? { signal: input.signal } : {});
|
|
3305
|
-
const response = await this.transport.raw(`/v1/workspaces/${encodeURIComponent(workspaceId)}/agent/message`, {
|
|
3306
|
-
method: "POST",
|
|
3307
|
-
...input.signal ? { signal: input.signal } : {},
|
|
3308
|
-
headers: { "content-type": "application/json" },
|
|
3309
|
-
body: JSON.stringify({
|
|
3310
|
-
type: "user",
|
|
3311
|
-
content: input.content,
|
|
3312
|
-
...input.attachmentIds?.length ? { attachment_ids: input.attachmentIds } : {}
|
|
3313
|
-
})
|
|
3314
|
-
});
|
|
3315
|
-
if (response.ok) return;
|
|
3316
|
-
const text = await response.text();
|
|
3317
|
-
let body;
|
|
3318
|
-
try {
|
|
3319
|
-
body = JSON.parse(text);
|
|
3320
|
-
} catch {
|
|
3321
|
-
throw new PocketCoderError({
|
|
3322
|
-
message: `PocketCoder returned a non-JSON response (${response.status})`,
|
|
3323
|
-
code: "client.non_json_response",
|
|
3324
|
-
status: response.status
|
|
3325
|
-
});
|
|
3326
|
-
}
|
|
3327
|
-
throw responseError(response, body);
|
|
3328
|
-
}
|
|
3329
|
-
interrupt(workspaceId, options = {}) {
|
|
3330
|
-
return this.transport.request(`/v1/workspaces/${encodeURIComponent(workspaceId)}/agent/interrupt`, AgentInterruptResponseSchema, {
|
|
3331
|
-
method: "POST",
|
|
3332
|
-
signal: options.signal
|
|
3333
|
-
});
|
|
3334
|
-
}
|
|
3335
|
-
};
|
|
3336
|
-
//#endregion
|
|
3337
3831
|
//#region src/resources/attachments/attachments.ts
|
|
3338
3832
|
function contentDisposition(name) {
|
|
3339
3833
|
const clean = name.replace(/[\r\n]/g, "");
|
|
@@ -3380,6 +3874,50 @@ var AttachmentsApi = class {
|
|
|
3380
3874
|
}
|
|
3381
3875
|
};
|
|
3382
3876
|
//#endregion
|
|
3877
|
+
//#region src/resources/budgets/budgets.ts
|
|
3878
|
+
const scopePath = (scopeId) => `/v1/budget-scopes/${encodeURIComponent(scopeId)}`;
|
|
3879
|
+
var ManagedAuthorityApi = class {
|
|
3880
|
+
transport;
|
|
3881
|
+
constructor(transport) {
|
|
3882
|
+
this.transport = transport;
|
|
3883
|
+
}
|
|
3884
|
+
async grantScope(scopeId, grant, options = {}) {
|
|
3885
|
+
await this.transport.request(`${scopePath(scopeId)}/grant`, z.undefined(), {
|
|
3886
|
+
...options,
|
|
3887
|
+
method: "PUT",
|
|
3888
|
+
body: JSON.stringify(managedSchemas.BudgetScopeGrant.parse(grant))
|
|
3889
|
+
});
|
|
3890
|
+
}
|
|
3891
|
+
putPolicy(policy, expectedRevision, options = {}) {
|
|
3892
|
+
return this.transport.request(`${scopePath(policy.scopeId)}/policy`, BudgetPolicySchema, {
|
|
3893
|
+
...options,
|
|
3894
|
+
method: "PUT",
|
|
3895
|
+
body: JSON.stringify(BudgetPolicyWriteSchema.parse(policy)),
|
|
3896
|
+
headers: expectedRevision === null ? { "if-none-match": "*" } : { "if-match": `"${expectedRevision}"` }
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3899
|
+
getPolicy(scopeId, options = {}) {
|
|
3900
|
+
return this.transport.request(`${scopePath(scopeId)}/policy`, BudgetPolicySchema, options);
|
|
3901
|
+
}
|
|
3902
|
+
usage(scopeId, options = {}) {
|
|
3903
|
+
return this.transport.request(`${scopePath(scopeId)}/usage`, BudgetUsageSchema, options);
|
|
3904
|
+
}
|
|
3905
|
+
putProfile(principalId, profile, options = {}) {
|
|
3906
|
+
return this.transport.request(`/v1/execution-profiles/${encodeURIComponent(profile.profileId)}/revisions/${profile.revision}?principalId=${encodeURIComponent(principalId)}`, ExecutionProfileSchema, {
|
|
3907
|
+
...options,
|
|
3908
|
+
method: "PUT",
|
|
3909
|
+
body: JSON.stringify(ExecutionProfileSchema.parse(profile))
|
|
3910
|
+
});
|
|
3911
|
+
}
|
|
3912
|
+
async putCredentialBinding(binding, options = {}) {
|
|
3913
|
+
await this.transport.request(`/v1/credential-bindings/${encodeURIComponent(binding.bindingId)}`, z.undefined(), {
|
|
3914
|
+
...options,
|
|
3915
|
+
method: "PUT",
|
|
3916
|
+
body: JSON.stringify(managedSchemas.CredentialBinding.parse(binding))
|
|
3917
|
+
});
|
|
3918
|
+
}
|
|
3919
|
+
};
|
|
3920
|
+
//#endregion
|
|
3383
3921
|
//#region src/transport/common.ts
|
|
3384
3922
|
function queryString(values) {
|
|
3385
3923
|
const params = new URLSearchParams();
|
|
@@ -3509,8 +4047,95 @@ var ConversationsApi = class {
|
|
|
3509
4047
|
const response = await this.transport.stream(path, options.signal);
|
|
3510
4048
|
if (response.body) yield* liveEvents(response.body);
|
|
3511
4049
|
}
|
|
4050
|
+
async open(id, options = {}) {
|
|
4051
|
+
return this.transport.request(`${workspacePath(id)}/conversation/open${options.conversationId ? `?${queryString({ conversationId: options.conversationId })}` : ""}`, z.object({ turns: z.array(ConversationLiveEventSchema) }), options);
|
|
4052
|
+
}
|
|
4053
|
+
};
|
|
4054
|
+
//#endregion
|
|
4055
|
+
//#region src/resources/conversations/requests.ts
|
|
4056
|
+
const path = (workspaceId) => `/v1/workspaces/${encodeURIComponent(workspaceId)}/requests`;
|
|
4057
|
+
var WorkspaceRequestsApi = class {
|
|
4058
|
+
transport;
|
|
4059
|
+
constructor(transport) {
|
|
4060
|
+
this.transport = transport;
|
|
4061
|
+
}
|
|
4062
|
+
submit(workspaceId, input, options = {}) {
|
|
4063
|
+
return this.transport.request(path(workspaceId), ExecutionRecordSchema, {
|
|
4064
|
+
...options,
|
|
4065
|
+
method: "POST",
|
|
4066
|
+
body: JSON.stringify(input)
|
|
4067
|
+
});
|
|
4068
|
+
}
|
|
4069
|
+
get(workspaceId, requestId, conversationId, options = {}) {
|
|
4070
|
+
return this.transport.request(`${path(workspaceId)}/${encodeURIComponent(requestId)}?${queryString({ conversationId })}`, ExecutionRecordSchema, options);
|
|
4071
|
+
}
|
|
4072
|
+
list(workspaceId, query, options = {}) {
|
|
4073
|
+
return this.transport.request(`${path(workspaceId)}?${queryString(query)}`, z.object({
|
|
4074
|
+
items: z.array(ExecutionRecordSchema),
|
|
4075
|
+
next_cursor: z.uuid().nullable()
|
|
4076
|
+
}), options);
|
|
4077
|
+
}
|
|
4078
|
+
cancel(record, cancelId, options = {}) {
|
|
4079
|
+
const execution = record.acceptance.execution;
|
|
4080
|
+
return this.transport.request(`/v1/workspaces/${encodeURIComponent(execution.workspaceId)}/executions/${encodeURIComponent(execution.requestId)}/cancel`, ExecutionRecordSchema, {
|
|
4081
|
+
...options,
|
|
4082
|
+
method: "POST",
|
|
4083
|
+
body: JSON.stringify({
|
|
4084
|
+
execution,
|
|
4085
|
+
cancelId,
|
|
4086
|
+
scope: "operation"
|
|
4087
|
+
})
|
|
4088
|
+
});
|
|
4089
|
+
}
|
|
3512
4090
|
};
|
|
3513
4091
|
//#endregion
|
|
4092
|
+
//#region src/transport/errors.ts
|
|
4093
|
+
z.enum(["client.non_json_response", "client.invalid_response"]);
|
|
4094
|
+
var PocketCoderError = class extends Error {
|
|
4095
|
+
code;
|
|
4096
|
+
status;
|
|
4097
|
+
requestId;
|
|
4098
|
+
details;
|
|
4099
|
+
constructor(input) {
|
|
4100
|
+
super(input.message);
|
|
4101
|
+
this.name = "PocketCoderError";
|
|
4102
|
+
this.code = input.code;
|
|
4103
|
+
this.status = input.status;
|
|
4104
|
+
this.requestId = input.requestId;
|
|
4105
|
+
this.details = input.details;
|
|
4106
|
+
}
|
|
4107
|
+
};
|
|
4108
|
+
var ConversationGoneError = class extends PocketCoderError {};
|
|
4109
|
+
var WorkspaceTerminalError = class extends Error {
|
|
4110
|
+
workspace;
|
|
4111
|
+
constructor(workspace) {
|
|
4112
|
+
const reason = workspace.reason_code ?? workspace.failure?.reason_code ?? "no reason";
|
|
4113
|
+
const tail = workspace.failure?.log_tail.trim();
|
|
4114
|
+
super([`workspace ${workspace.id} reached ${workspace.state} (${reason})`, ...tail ? [`failure log:\n${tail}`] : []].join("\n"));
|
|
4115
|
+
this.name = "WorkspaceTerminalError";
|
|
4116
|
+
this.workspace = workspace;
|
|
4117
|
+
}
|
|
4118
|
+
};
|
|
4119
|
+
function isPocketCoderErrorCode(value) {
|
|
4120
|
+
return typeof value === "string" && value in ERROR_CODES;
|
|
4121
|
+
}
|
|
4122
|
+
function responseError(response, body) {
|
|
4123
|
+
const parsed = ErrorEnvelopeSchema.safeParse(body);
|
|
4124
|
+
if (!parsed.success) return new PocketCoderError({
|
|
4125
|
+
message: `PocketCoder returned an invalid error response (${response.status})`,
|
|
4126
|
+
code: "client.invalid_response",
|
|
4127
|
+
status: response.status
|
|
4128
|
+
});
|
|
4129
|
+
const { code, message, request_id: requestId, details } = parsed.data.error;
|
|
4130
|
+
return new (code === "conversation.deleted" || code === "conversation.expired" ? ConversationGoneError : PocketCoderError)({
|
|
4131
|
+
message,
|
|
4132
|
+
code,
|
|
4133
|
+
status: response.status,
|
|
4134
|
+
requestId,
|
|
4135
|
+
details
|
|
4136
|
+
});
|
|
4137
|
+
}
|
|
4138
|
+
//#endregion
|
|
3514
4139
|
//#region src/resources/diagnostics/diagnostics.ts
|
|
3515
4140
|
var WorkspaceCursorApi = class {
|
|
3516
4141
|
transport;
|
|
@@ -3660,7 +4285,10 @@ var PreviewsApi = class {
|
|
|
3660
4285
|
open(workspaceId, name, options = {}) {
|
|
3661
4286
|
return this.transport.request(`/v1/workspaces/${encodeURIComponent(workspaceId)}/previews/${encodeURIComponent(name)}`, PreviewOpenResponseSchema, {
|
|
3662
4287
|
method: "POST",
|
|
3663
|
-
body: JSON.stringify({
|
|
4288
|
+
body: JSON.stringify({
|
|
4289
|
+
session: options.session ?? { mode: "local" },
|
|
4290
|
+
...options.grantId ? { grantId: options.grantId } : {}
|
|
4291
|
+
}),
|
|
3664
4292
|
signal: options.signal
|
|
3665
4293
|
});
|
|
3666
4294
|
}
|
|
@@ -3718,6 +4346,204 @@ var SecretsApi = class {
|
|
|
3718
4346
|
}
|
|
3719
4347
|
};
|
|
3720
4348
|
//#endregion
|
|
4349
|
+
//#region src/resources/sessions/events.ts
|
|
4350
|
+
async function* frames(body) {
|
|
4351
|
+
const decoder = new TextDecoder();
|
|
4352
|
+
let buffer = "";
|
|
4353
|
+
for await (const chunk of body) {
|
|
4354
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
4355
|
+
let end = buffer.indexOf("\n\n");
|
|
4356
|
+
while (end !== -1) {
|
|
4357
|
+
const block = buffer.slice(0, end).split("\n");
|
|
4358
|
+
buffer = buffer.slice(end + 2);
|
|
4359
|
+
const field = (name) => block.find((line) => line.startsWith(`${name}:`))?.slice(name.length + 1).trim();
|
|
4360
|
+
const data = block.filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
4361
|
+
yield {
|
|
4362
|
+
id: field("id") ?? null,
|
|
4363
|
+
event: field("event") ?? null,
|
|
4364
|
+
data
|
|
4365
|
+
};
|
|
4366
|
+
end = buffer.indexOf("\n\n");
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
async function* sessionEvents(transport, sessionId, options = {}) {
|
|
4371
|
+
let cursor = options.after ?? null;
|
|
4372
|
+
do {
|
|
4373
|
+
const query = cursor ? `?after=${encodeURIComponent(cursor)}` : "";
|
|
4374
|
+
const response = await transport.stream(`/v1/sessions/${encodeURIComponent(sessionId)}/events${query}`, options.signal, cursor ? { "last-event-id": cursor } : {});
|
|
4375
|
+
if (!response.body) return;
|
|
4376
|
+
for await (const frame of frames(response.body)) {
|
|
4377
|
+
if (frame.event === "keepalive") continue;
|
|
4378
|
+
if (frame.event === "error") {
|
|
4379
|
+
const { code } = JSON.parse(frame.data);
|
|
4380
|
+
throw new PocketCoderError({
|
|
4381
|
+
message: `Session event stream ended: ${code}`,
|
|
4382
|
+
code,
|
|
4383
|
+
status: 0
|
|
4384
|
+
});
|
|
4385
|
+
}
|
|
4386
|
+
const event = RuntimeEventSchema.parse(JSON.parse(frame.data));
|
|
4387
|
+
cursor = event.cursor;
|
|
4388
|
+
yield event;
|
|
4389
|
+
}
|
|
4390
|
+
} while (options.reconnect !== false && !options.signal?.aborted);
|
|
4391
|
+
}
|
|
4392
|
+
//#endregion
|
|
4393
|
+
//#region src/resources/sessions/sessions.ts
|
|
4394
|
+
function sessionPath(sessionId) {
|
|
4395
|
+
return `/v1/sessions/${encodeURIComponent(sessionId)}`;
|
|
4396
|
+
}
|
|
4397
|
+
const SessionPreviewSchema = PreviewOpenResponseSchema.extend({ grantId: z.uuid().nullable() });
|
|
4398
|
+
var SessionsApi = class {
|
|
4399
|
+
transport;
|
|
4400
|
+
constructor(transport) {
|
|
4401
|
+
this.transport = transport;
|
|
4402
|
+
}
|
|
4403
|
+
create(input, options = {}) {
|
|
4404
|
+
return this.transport.request("/v1/sessions", SessionSchema, {
|
|
4405
|
+
...options,
|
|
4406
|
+
method: "POST",
|
|
4407
|
+
body: JSON.stringify(SessionCreateSchema.parse(input))
|
|
4408
|
+
});
|
|
4409
|
+
}
|
|
4410
|
+
get(sessionId, options = {}) {
|
|
4411
|
+
return this.transport.request(sessionPath(sessionId), SessionSchema, options);
|
|
4412
|
+
}
|
|
4413
|
+
resume(sessionId, options = {}) {
|
|
4414
|
+
return this.transport.request(`${sessionPath(sessionId)}/resume`, SessionSchema, {
|
|
4415
|
+
...options,
|
|
4416
|
+
method: "POST"
|
|
4417
|
+
});
|
|
4418
|
+
}
|
|
4419
|
+
close(sessionId, command, options = {}) {
|
|
4420
|
+
return this.transport.request(`${sessionPath(sessionId)}/close`, CancelReceiptSchema, {
|
|
4421
|
+
...options,
|
|
4422
|
+
method: "POST",
|
|
4423
|
+
body: JSON.stringify(CancelCommandSchema.parse(command))
|
|
4424
|
+
});
|
|
4425
|
+
}
|
|
4426
|
+
history(sessionId, query = {}, options = {}) {
|
|
4427
|
+
return this.transport.request(`${sessionPath(sessionId)}/history?${queryString({
|
|
4428
|
+
cursor: query.cursor,
|
|
4429
|
+
limit: query.limit ?? 50
|
|
4430
|
+
})}`, ManagedHistoryPageSchema, options);
|
|
4431
|
+
}
|
|
4432
|
+
async snapshot(sessionId, options = {}) {
|
|
4433
|
+
const records = [];
|
|
4434
|
+
let cursor;
|
|
4435
|
+
let eventCursor = "";
|
|
4436
|
+
do {
|
|
4437
|
+
const page = await this.history(sessionId, {
|
|
4438
|
+
cursor,
|
|
4439
|
+
limit: 200
|
|
4440
|
+
}, options);
|
|
4441
|
+
records.push(...page.records);
|
|
4442
|
+
eventCursor = page.eventCursor;
|
|
4443
|
+
cursor = page.nextCursor ?? void 0;
|
|
4444
|
+
} while (cursor);
|
|
4445
|
+
return {
|
|
4446
|
+
records,
|
|
4447
|
+
eventCursor
|
|
4448
|
+
};
|
|
4449
|
+
}
|
|
4450
|
+
events(sessionId, options = {}) {
|
|
4451
|
+
return sessionEvents(this.transport, sessionId, options);
|
|
4452
|
+
}
|
|
4453
|
+
open(sessionId, options = {}) {
|
|
4454
|
+
return this.transport.request(`${sessionPath(sessionId)}/conversation/open`, z.object({ turns: z.array(ConversationLiveEventSchema) }), options);
|
|
4455
|
+
}
|
|
4456
|
+
openPreview(sessionId, name, options = {}) {
|
|
4457
|
+
return this.transport.request(`${sessionPath(sessionId)}/previews/${encodeURIComponent(name)}`, SessionPreviewSchema, {
|
|
4458
|
+
method: "POST",
|
|
4459
|
+
body: JSON.stringify({
|
|
4460
|
+
session: options.session ?? { mode: "local" },
|
|
4461
|
+
...options.grant ? { grant: options.grant } : {}
|
|
4462
|
+
}),
|
|
4463
|
+
signal: options.signal
|
|
4464
|
+
});
|
|
4465
|
+
}
|
|
4466
|
+
};
|
|
4467
|
+
//#endregion
|
|
4468
|
+
//#region src/resources/sessions/files.ts
|
|
4469
|
+
var SessionFilesApi = class {
|
|
4470
|
+
transport;
|
|
4471
|
+
constructor(transport) {
|
|
4472
|
+
this.transport = transport;
|
|
4473
|
+
}
|
|
4474
|
+
register(sessionId, input, options = {}) {
|
|
4475
|
+
return this.transport.request(`${sessionPath(sessionId)}/inputs`, InputObjectSchema, {
|
|
4476
|
+
...options,
|
|
4477
|
+
method: "POST",
|
|
4478
|
+
body: JSON.stringify(InputUploadSchema.parse(input))
|
|
4479
|
+
});
|
|
4480
|
+
}
|
|
4481
|
+
upload(sessionId, inputId, bytes, options = {}) {
|
|
4482
|
+
return this.transport.request(`${sessionPath(sessionId)}/inputs/${encodeURIComponent(inputId)}/content`, InputObjectSchema, {
|
|
4483
|
+
...options,
|
|
4484
|
+
method: "PUT",
|
|
4485
|
+
body: bytes,
|
|
4486
|
+
headers: { "content-type": "application/octet-stream" }
|
|
4487
|
+
});
|
|
4488
|
+
}
|
|
4489
|
+
async put(sessionId, file, options = {}) {
|
|
4490
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", file.bytes));
|
|
4491
|
+
const sha256 = `sha256:${Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
4492
|
+
const registered = await this.register(sessionId, {
|
|
4493
|
+
inputId: file.inputId,
|
|
4494
|
+
name: file.name,
|
|
4495
|
+
mediaType: file.mediaType,
|
|
4496
|
+
sizeBytes: file.bytes.byteLength,
|
|
4497
|
+
sha256
|
|
4498
|
+
}, options);
|
|
4499
|
+
if (registered.state === "ready") return registered;
|
|
4500
|
+
return this.upload(sessionId, file.inputId, file.bytes, options);
|
|
4501
|
+
}
|
|
4502
|
+
get(sessionId, inputId, options = {}) {
|
|
4503
|
+
return this.transport.request(`${sessionPath(sessionId)}/inputs/${encodeURIComponent(inputId)}`, InputObjectSchema, options);
|
|
4504
|
+
}
|
|
4505
|
+
exports(sessionId, requestId, options = {}) {
|
|
4506
|
+
return this.transport.request(`${sessionPath(sessionId)}/exports?requestId=${encodeURIComponent(requestId)}`, ManagedExportPageSchema, options);
|
|
4507
|
+
}
|
|
4508
|
+
async content(sessionId, exportId, options = {}) {
|
|
4509
|
+
const response = await this.transport.raw(`${sessionPath(sessionId)}/exports/${encodeURIComponent(exportId)}/content`, options);
|
|
4510
|
+
if (!response.ok) {
|
|
4511
|
+
const text = await response.text();
|
|
4512
|
+
throw responseError(response, text ? JSON.parse(text) : void 0);
|
|
4513
|
+
}
|
|
4514
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
4515
|
+
}
|
|
4516
|
+
};
|
|
4517
|
+
//#endregion
|
|
4518
|
+
//#region src/resources/sessions/requests.ts
|
|
4519
|
+
const requestPath = (sessionId, requestId) => `${sessionPath(sessionId)}/requests/${encodeURIComponent(requestId)}`;
|
|
4520
|
+
var SessionRequestsApi = class {
|
|
4521
|
+
transport;
|
|
4522
|
+
constructor(transport) {
|
|
4523
|
+
this.transport = transport;
|
|
4524
|
+
}
|
|
4525
|
+
submit(sessionId, input, options = {}) {
|
|
4526
|
+
return this.transport.request(`${sessionPath(sessionId)}/requests`, RequestSchema, {
|
|
4527
|
+
...options,
|
|
4528
|
+
method: "POST",
|
|
4529
|
+
body: JSON.stringify(RequestInputSchema.parse(input))
|
|
4530
|
+
});
|
|
4531
|
+
}
|
|
4532
|
+
get(sessionId, requestId, options = {}) {
|
|
4533
|
+
return this.transport.request(requestPath(sessionId, requestId), RequestSchema, options);
|
|
4534
|
+
}
|
|
4535
|
+
cancel(sessionId, requestId, command, options = {}) {
|
|
4536
|
+
return this.transport.request(`${requestPath(sessionId, requestId)}/cancel`, CancelReceiptSchema, {
|
|
4537
|
+
...options,
|
|
4538
|
+
method: "POST",
|
|
4539
|
+
body: JSON.stringify(CancelCommandSchema.parse(command))
|
|
4540
|
+
});
|
|
4541
|
+
}
|
|
4542
|
+
collection(sessionId, requestId, options = {}) {
|
|
4543
|
+
return this.transport.request(`${requestPath(sessionId, requestId)}/collection`, CollectionResultSchema, options);
|
|
4544
|
+
}
|
|
4545
|
+
};
|
|
4546
|
+
//#endregion
|
|
3721
4547
|
//#region src/resources/templates/templates.ts
|
|
3722
4548
|
var TemplatesApi = class {
|
|
3723
4549
|
transport;
|
|
@@ -3926,17 +4752,6 @@ var WorkspacesApi = class {
|
|
|
3926
4752
|
}
|
|
3927
4753
|
return workspace;
|
|
3928
4754
|
}
|
|
3929
|
-
async waitForAgentInput(id, timeoutMs, options = {}) {
|
|
3930
|
-
const deadline = Date.now() + timeoutMs;
|
|
3931
|
-
let workspace = await this.get(id, options);
|
|
3932
|
-
while (workspace.agent_state !== "stable") {
|
|
3933
|
-
if (TERMINAL_STATES.includes(workspace.state)) throw new WorkspaceTerminalError(workspace);
|
|
3934
|
-
const remainingMs = deadline - Date.now();
|
|
3935
|
-
if (remainingMs <= 0) throw new AgentNotReadyError(workspace.id, workspace.agent_state, timeoutMs);
|
|
3936
|
-
workspace = (await this.change(workspace.id, workspace.change_cursor, Math.max(1, Math.min(30, Math.ceil(remainingMs / 1e3))), options)).workspace;
|
|
3937
|
-
}
|
|
3938
|
-
return workspace;
|
|
3939
|
-
}
|
|
3940
4755
|
preserve(id, input, key, options = {}) {
|
|
3941
4756
|
return this.jsonOperation(`/v1/workspaces/${encodeURIComponent(id)}/preserve`, input, key, PreserveResponseSchema, options);
|
|
3942
4757
|
}
|
|
@@ -4015,11 +4830,12 @@ var PocketCoderTransport = class {
|
|
|
4015
4830
|
await delay(100 * 2 ** attempt, signal);
|
|
4016
4831
|
}
|
|
4017
4832
|
}
|
|
4018
|
-
async stream(path, signal) {
|
|
4833
|
+
async stream(path, signal, headers = {}) {
|
|
4019
4834
|
const response = await this.fetchImpl(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`, {
|
|
4020
4835
|
headers: {
|
|
4021
4836
|
authorization: `Bearer ${this.apiKey}`,
|
|
4022
|
-
accept: "text/event-stream"
|
|
4837
|
+
accept: "text/event-stream",
|
|
4838
|
+
...headers
|
|
4023
4839
|
},
|
|
4024
4840
|
...signal ? { signal } : {}
|
|
4025
4841
|
});
|
|
@@ -4099,8 +4915,8 @@ var PocketCoderClient = class {
|
|
|
4099
4915
|
previews;
|
|
4100
4916
|
displays;
|
|
4101
4917
|
attachments;
|
|
4102
|
-
agent;
|
|
4103
4918
|
conversations;
|
|
4919
|
+
workspaceRequests;
|
|
4104
4920
|
checkpoints;
|
|
4105
4921
|
operations;
|
|
4106
4922
|
logs;
|
|
@@ -4111,6 +4927,10 @@ var PocketCoderClient = class {
|
|
|
4111
4927
|
principals;
|
|
4112
4928
|
keys;
|
|
4113
4929
|
recovery;
|
|
4930
|
+
sessions;
|
|
4931
|
+
requests;
|
|
4932
|
+
files;
|
|
4933
|
+
authority;
|
|
4114
4934
|
constructor(config, fetchImpl = fetch) {
|
|
4115
4935
|
this.transport = new PocketCoderTransport(config, fetchImpl);
|
|
4116
4936
|
this.secrets = new SecretsApi(this.transport);
|
|
@@ -4119,8 +4939,8 @@ var PocketCoderClient = class {
|
|
|
4119
4939
|
this.previews = new PreviewsApi(this.transport);
|
|
4120
4940
|
this.displays = new DisplaysApi(this.transport);
|
|
4121
4941
|
this.attachments = new AttachmentsApi(this.transport);
|
|
4122
|
-
this.agent = new AgentApi(this.transport, this.workspaces);
|
|
4123
4942
|
this.conversations = new ConversationsApi(this.transport);
|
|
4943
|
+
this.workspaceRequests = new WorkspaceRequestsApi(this.transport);
|
|
4124
4944
|
this.checkpoints = new CheckpointsApi(this.transport);
|
|
4125
4945
|
this.operations = new OperationsApi(this.transport);
|
|
4126
4946
|
this.logs = new LogsApi(this.transport);
|
|
@@ -4131,6 +4951,10 @@ var PocketCoderClient = class {
|
|
|
4131
4951
|
this.principals = new PrincipalsApi(this.transport);
|
|
4132
4952
|
this.keys = new KeysApi(this.transport);
|
|
4133
4953
|
this.recovery = new RecoveryApi(this.transport);
|
|
4954
|
+
this.sessions = new SessionsApi(this.transport);
|
|
4955
|
+
this.requests = new SessionRequestsApi(this.transport);
|
|
4956
|
+
this.files = new SessionFilesApi(this.transport);
|
|
4957
|
+
this.authority = new ManagedAuthorityApi(this.transport);
|
|
4134
4958
|
}
|
|
4135
4959
|
raw(path, init = {}) {
|
|
4136
4960
|
return this.transport.raw(path, init);
|
|
@@ -4281,4 +5105,4 @@ var WorkspaceTurnResolver = class {
|
|
|
4281
5105
|
}
|
|
4282
5106
|
};
|
|
4283
5107
|
//#endregion
|
|
4284
|
-
export { AdministrationApi,
|
|
5108
|
+
export { AdministrationApi, AttachmentsApi, CheckpointsApi, ConversationGoneError, ConversationsApi, KeysApi, LogsApi, ManagedAuthorityApi, NetworkEventsApi, OperationsApi, OutputsApi, PocketCoderClient, PocketCoderError, PrincipalsApi, RecoveryApi, SecretsApi, SessionFilesApi, SessionRequestsApi, SessionsApi, TERMINAL_WORKSPACE_STATES, TemplatesApi, TerminalConnection, TerminalsApi, WorkspaceRequestsApi, WorkspaceTerminalError, WorkspaceTurnResolutionError, WorkspaceTurnResolver, WorkspacesApi, isPocketCoderErrorCode, sessions_exports as managed, sessionTemplate };
|