@kanyun-ai-infra/agenthub 0.1.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 +46 -0
- package/dist/index.cjs +4701 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5828 -0
- package/dist/index.d.ts +5828 -0
- package/dist/index.js +4652 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,4701 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __typeError = (msg) => {
|
|
7
|
+
throw TypeError(msg);
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
23
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
24
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
25
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
26
|
+
|
|
27
|
+
// src/index.ts
|
|
28
|
+
var index_exports = {};
|
|
29
|
+
__export(index_exports, {
|
|
30
|
+
AGENTHUB_SDK_USER_AGENT: () => AGENTHUB_SDK_USER_AGENT,
|
|
31
|
+
CreatePlatformProjectRequestSchema: () => CreatePlatformProjectRequestSchema,
|
|
32
|
+
CreatePlatformSessionRequestSchema: () => CreatePlatformSessionRequestSchema,
|
|
33
|
+
CreatePlatformSessionResponseSchema: () => CreatePlatformSessionResponseSchema,
|
|
34
|
+
CreatePlatformWorkloadRequestSchema: () => CreatePlatformWorkloadRequestSchema,
|
|
35
|
+
ListPlatformProjectsResponseSchema: () => ListPlatformProjectsResponseSchema,
|
|
36
|
+
PILOT_WORKLOAD_MANIFEST_API_VERSION: () => PILOT_WORKLOAD_MANIFEST_API_VERSION,
|
|
37
|
+
PILOT_WORKLOAD_MANIFEST_LEGACY_API_VERSION: () => PILOT_WORKLOAD_MANIFEST_LEGACY_API_VERSION,
|
|
38
|
+
PilotPlatformApiError: () => PilotPlatformApiError,
|
|
39
|
+
PilotPlatformClient: () => PilotPlatformClient,
|
|
40
|
+
PilotPlatformForbiddenError: () => PilotPlatformForbiddenError,
|
|
41
|
+
PilotPlatformNotFoundError: () => PilotPlatformNotFoundError,
|
|
42
|
+
PilotPlatformServerError: () => PilotPlatformServerError,
|
|
43
|
+
PilotPlatformUnauthenticatedError: () => PilotPlatformUnauthenticatedError,
|
|
44
|
+
PlatformProjectSchema: () => PlatformProjectSchema,
|
|
45
|
+
PlatformRevisionSchema: () => PlatformRevisionSchema,
|
|
46
|
+
PlatformWorkloadSchema: () => PlatformWorkloadSchema,
|
|
47
|
+
ProjectsResource: () => ProjectsResource,
|
|
48
|
+
PublishPlatformRevisionRequestSchema: () => PublishPlatformRevisionRequestSchema,
|
|
49
|
+
SessionsResource: () => SessionsResource,
|
|
50
|
+
WorkloadsResource: () => WorkloadsResource,
|
|
51
|
+
pilotPlatformErrorFromResponse: () => pilotPlatformErrorFromResponse,
|
|
52
|
+
platformRevisionPublishToManifest: () => platformRevisionPublishToManifest,
|
|
53
|
+
platformWorkloadCreateToManifest: () => platformWorkloadCreateToManifest
|
|
54
|
+
});
|
|
55
|
+
module.exports = __toCommonJS(index_exports);
|
|
56
|
+
|
|
57
|
+
// ../contracts/dist/chunk-DDAAVRWG.js
|
|
58
|
+
var __defProp2 = Object.defineProperty;
|
|
59
|
+
var __defProps = Object.defineProperties;
|
|
60
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
61
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
62
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
63
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
64
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
65
|
+
var __spreadValues = (a, b) => {
|
|
66
|
+
for (var prop in b || (b = {}))
|
|
67
|
+
if (__hasOwnProp2.call(b, prop))
|
|
68
|
+
__defNormalProp(a, prop, b[prop]);
|
|
69
|
+
if (__getOwnPropSymbols)
|
|
70
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
71
|
+
if (__propIsEnum.call(b, prop))
|
|
72
|
+
__defNormalProp(a, prop, b[prop]);
|
|
73
|
+
}
|
|
74
|
+
return a;
|
|
75
|
+
};
|
|
76
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
77
|
+
|
|
78
|
+
// ../contracts/dist/index.js
|
|
79
|
+
var import_zod = require("zod");
|
|
80
|
+
var import_zod2 = require("zod");
|
|
81
|
+
var import_zod3 = require("zod");
|
|
82
|
+
var import_zod4 = require("zod");
|
|
83
|
+
var import_zod5 = require("zod");
|
|
84
|
+
var import_zod6 = require("zod");
|
|
85
|
+
var import_zod7 = require("zod");
|
|
86
|
+
var import_zod8 = require("zod");
|
|
87
|
+
var import_zod9 = require("zod");
|
|
88
|
+
var import_zod10 = require("zod");
|
|
89
|
+
var import_zod11 = require("zod");
|
|
90
|
+
var import_zod12 = require("zod");
|
|
91
|
+
var import_zod13 = require("zod");
|
|
92
|
+
var import_zod14 = require("zod");
|
|
93
|
+
var import_zod15 = require("zod");
|
|
94
|
+
var import_zod16 = require("zod");
|
|
95
|
+
var import_zod17 = require("zod");
|
|
96
|
+
var import_zod18 = require("zod");
|
|
97
|
+
var import_zod19 = require("zod");
|
|
98
|
+
var import_zod20 = require("zod");
|
|
99
|
+
var import_zod21 = require("zod");
|
|
100
|
+
var import_zod22 = require("zod");
|
|
101
|
+
var import_zod23 = require("zod");
|
|
102
|
+
var import_zod24 = require("zod");
|
|
103
|
+
var import_zod25 = require("zod");
|
|
104
|
+
var import_zod26 = require("zod");
|
|
105
|
+
var import_zod27 = require("zod");
|
|
106
|
+
var import_zod28 = require("zod");
|
|
107
|
+
var import_zod29 = require("zod");
|
|
108
|
+
var import_zod30 = require("zod");
|
|
109
|
+
var import_zod31 = require("zod");
|
|
110
|
+
var import_zod32 = require("zod");
|
|
111
|
+
var import_zod33 = require("zod");
|
|
112
|
+
var import_zod34 = require("zod");
|
|
113
|
+
var import_zod35 = require("zod");
|
|
114
|
+
var import_zod36 = require("zod");
|
|
115
|
+
var import_zod37 = require("zod");
|
|
116
|
+
var import_zod38 = require("zod");
|
|
117
|
+
var import_zod39 = require("zod");
|
|
118
|
+
var import_zod40 = require("zod");
|
|
119
|
+
var import_zod41 = require("zod");
|
|
120
|
+
var import_zod42 = require("zod");
|
|
121
|
+
var import_zod43 = require("zod");
|
|
122
|
+
var import_zod44 = require("zod");
|
|
123
|
+
var import_zod45 = require("zod");
|
|
124
|
+
var import_zod46 = require("zod");
|
|
125
|
+
var RunStatusSchema = import_zod.z.enum([
|
|
126
|
+
"queued",
|
|
127
|
+
"provisioning",
|
|
128
|
+
"preparing",
|
|
129
|
+
"running",
|
|
130
|
+
"finalizing_prepare",
|
|
131
|
+
"finalizing_uploading",
|
|
132
|
+
"finalizing_verifying",
|
|
133
|
+
"finalizing_metadata_commit",
|
|
134
|
+
"finalized",
|
|
135
|
+
"completed",
|
|
136
|
+
"failed",
|
|
137
|
+
"worker_unreachable",
|
|
138
|
+
"finalizing_retryable_failed",
|
|
139
|
+
"finalizing_timeout",
|
|
140
|
+
"finalizing_manual_intervention"
|
|
141
|
+
]);
|
|
142
|
+
var RunDeliveryPhaseSchema = import_zod.z.enum(["in_progress", "completed", "failed"]);
|
|
143
|
+
var TriggerSourceSchema = import_zod.z.enum([
|
|
144
|
+
"user",
|
|
145
|
+
"webhook",
|
|
146
|
+
"alert",
|
|
147
|
+
"cron",
|
|
148
|
+
"wecom_chat",
|
|
149
|
+
"jira"
|
|
150
|
+
]);
|
|
151
|
+
var ProviderTypeSchema = import_zod.z.enum([
|
|
152
|
+
// Legacy runtime keys (do NOT reorder; preserves persisted values).
|
|
153
|
+
"claude-code",
|
|
154
|
+
"codex",
|
|
155
|
+
// ModelGate vendor expansion (names mirror ModelGate `owned_by`).
|
|
156
|
+
"deepseek",
|
|
157
|
+
"google",
|
|
158
|
+
"zhipu",
|
|
159
|
+
"volcengine",
|
|
160
|
+
"tencent",
|
|
161
|
+
"moonshot",
|
|
162
|
+
"minimax",
|
|
163
|
+
"dashscope",
|
|
164
|
+
"xiaomi"
|
|
165
|
+
]);
|
|
166
|
+
var AttachmentMetaSchema = import_zod.z.object({
|
|
167
|
+
/** OSS original URL (Agent Worker downloads via this) */
|
|
168
|
+
ossUrl: import_zod.z.string().min(1),
|
|
169
|
+
/** Original filename */
|
|
170
|
+
filename: import_zod.z.string().min(1).max(255),
|
|
171
|
+
/** File size in bytes */
|
|
172
|
+
size: import_zod.z.number().int().positive(),
|
|
173
|
+
/** Media type classification */
|
|
174
|
+
mediaType: import_zod.z.enum(["image", "document", "code", "notebook"]),
|
|
175
|
+
/** MIME type */
|
|
176
|
+
mimeType: import_zod.z.string()
|
|
177
|
+
});
|
|
178
|
+
var RunSpecSchema = import_zod.z.object({
|
|
179
|
+
prompt: import_zod.z.string().min(1),
|
|
180
|
+
projectId: import_zod.z.string().uuid(),
|
|
181
|
+
agentId: import_zod.z.string().uuid().optional(),
|
|
182
|
+
agentMode: import_zod.z.enum(["task", "chat"]).optional(),
|
|
183
|
+
repo: import_zod.z.string().optional(),
|
|
184
|
+
ref: import_zod.z.string().optional(),
|
|
185
|
+
model: import_zod.z.string().optional(),
|
|
186
|
+
provider: ProviderTypeSchema.optional().default("claude-code"),
|
|
187
|
+
runnerRequired: import_zod.z.boolean().optional().default(false),
|
|
188
|
+
triggerSource: TriggerSourceSchema.optional().default("user"),
|
|
189
|
+
triggerRef: import_zod.z.string().optional(),
|
|
190
|
+
githubInstallationId: import_zod.z.string().optional(),
|
|
191
|
+
attachments: import_zod.z.array(AttachmentMetaSchema).max(5).optional(),
|
|
192
|
+
/**
|
|
193
|
+
* LDAP of the user whose action created this run. Populated by
|
|
194
|
+
* Portal / 企微 entry points. Null / undefined for webhook / automation
|
|
195
|
+
* triggers where we cannot identify a single human, in which case
|
|
196
|
+
* prepareWorkspace falls back to the service-level Bedrock key.
|
|
197
|
+
* See specs/features/user-bedrock-credentials.md.
|
|
198
|
+
*/
|
|
199
|
+
triggerUserLdap: import_zod.z.string().min(1).optional(),
|
|
200
|
+
/**
|
|
201
|
+
* Per-run override for the effective MCP / Skills enable list (spec
|
|
202
|
+
* §6.3). Either field being present (including `[]`) writes into the
|
|
203
|
+
* corresponding `runs.enabled_*` column; `undefined` leaves the
|
|
204
|
+
* column NULL, in which case the runtime resolver falls through to
|
|
205
|
+
* `agents.enabled_*`.
|
|
206
|
+
*
|
|
207
|
+
* Phase 1 has no Portal UI surface for this — the field is reserved
|
|
208
|
+
* for SDK / webhook automations. See specs/features/mcp-and-skills.md.
|
|
209
|
+
*
|
|
210
|
+
* Element shape is validated by the API layer (Zod) — at the
|
|
211
|
+
* RunService layer we accept already-validated arrays as opaque to
|
|
212
|
+
* keep the service free of contracts re-imports.
|
|
213
|
+
*/
|
|
214
|
+
// Element shape validated at the API layer; RunService accepts opaque arrays
|
|
215
|
+
// (see comment above) so no further runtime check here.
|
|
216
|
+
enabledMcpServers: import_zod.z.array(import_zod.z.any()).optional(),
|
|
217
|
+
enabledSkills: import_zod.z.array(import_zod.z.any()).optional()
|
|
218
|
+
});
|
|
219
|
+
var RunSchema = import_zod.z.object({
|
|
220
|
+
id: import_zod.z.string().uuid(),
|
|
221
|
+
agentId: import_zod.z.string().uuid(),
|
|
222
|
+
parentRunId: import_zod.z.string().uuid().nullable(),
|
|
223
|
+
status: RunStatusSchema,
|
|
224
|
+
prompt: import_zod.z.string(),
|
|
225
|
+
projectId: import_zod.z.string().uuid(),
|
|
226
|
+
repoUrl: import_zod.z.string().nullable(),
|
|
227
|
+
targetRef: import_zod.z.string().nullable(),
|
|
228
|
+
modelOverride: import_zod.z.string().nullable(),
|
|
229
|
+
runnerRequired: import_zod.z.boolean(),
|
|
230
|
+
runtimeProfileVersion: import_zod.z.number().int().nullable(),
|
|
231
|
+
runtimeProfileSnapshot: import_zod.z.record(import_zod.z.unknown()).nullable(),
|
|
232
|
+
activeStreamId: import_zod.z.string().nullable(),
|
|
233
|
+
agentStreamId: import_zod.z.string().nullable(),
|
|
234
|
+
provider: ProviderTypeSchema.default("claude-code"),
|
|
235
|
+
triggerSource: TriggerSourceSchema,
|
|
236
|
+
triggerRef: import_zod.z.string().nullable(),
|
|
237
|
+
githubInstallationId: import_zod.z.string().nullable(),
|
|
238
|
+
retryCount: import_zod.z.number().int().default(0),
|
|
239
|
+
maxRetries: import_zod.z.number().int().default(3),
|
|
240
|
+
pullRequestUrl: import_zod.z.string().nullable(),
|
|
241
|
+
errorMessage: import_zod.z.string().nullable(),
|
|
242
|
+
attachmentsJson: import_zod.z.array(AttachmentMetaSchema).nullable(),
|
|
243
|
+
/** LDAP of the triggering user; null when unknown (webhook / automation). */
|
|
244
|
+
triggerUserLdap: import_zod.z.string().nullable(),
|
|
245
|
+
createdAt: import_zod.z.date(),
|
|
246
|
+
updatedAt: import_zod.z.date(),
|
|
247
|
+
startedAt: import_zod.z.date().nullable(),
|
|
248
|
+
completedAt: import_zod.z.date().nullable()
|
|
249
|
+
});
|
|
250
|
+
var LEGACY_MODEL_ALIASES = Object.freeze({
|
|
251
|
+
opus: "claude-opus-4-7",
|
|
252
|
+
sonnet: "claude-sonnet-4-6",
|
|
253
|
+
haiku: "claude-haiku-4-5"
|
|
254
|
+
});
|
|
255
|
+
var BEDROCK_COMPATIBLE_MODEL_IDS = Object.freeze(
|
|
256
|
+
/* @__PURE__ */ new Set(["opus", "sonnet", "haiku"])
|
|
257
|
+
);
|
|
258
|
+
var MODELGATE_VENDOR_TYPES = [
|
|
259
|
+
"anthropic",
|
|
260
|
+
"openai",
|
|
261
|
+
"deepseek",
|
|
262
|
+
"google",
|
|
263
|
+
"zhipu",
|
|
264
|
+
"volcengine",
|
|
265
|
+
"tencent",
|
|
266
|
+
"moonshot",
|
|
267
|
+
"minimax",
|
|
268
|
+
"dashscope",
|
|
269
|
+
"xiaomi"
|
|
270
|
+
];
|
|
271
|
+
var ModelGateVendorTypeSchema = import_zod2.z.enum(MODELGATE_VENDOR_TYPES);
|
|
272
|
+
var AgentModeSchema = import_zod3.z.enum(["task", "chat"]);
|
|
273
|
+
var AgentStatusSchema = import_zod3.z.enum(["active", "closed", "deleted"]);
|
|
274
|
+
var ExternalChatSourceSchema = import_zod3.z.enum(["wecom"]);
|
|
275
|
+
var AgentSchema = import_zod3.z.object({
|
|
276
|
+
id: import_zod3.z.string().uuid(),
|
|
277
|
+
projectId: import_zod3.z.string().uuid(),
|
|
278
|
+
sandboxId: import_zod3.z.string().nullable(),
|
|
279
|
+
agentMode: AgentModeSchema,
|
|
280
|
+
status: AgentStatusSchema,
|
|
281
|
+
customTitle: import_zod3.z.string().max(200).nullable(),
|
|
282
|
+
/**
|
|
283
|
+
* Baseline git ref captured at agent (task) creation. Frozen for the
|
|
284
|
+
* lifetime of the agent so follow-up runs always re-clone from the
|
|
285
|
+
* branch the user originally selected. Nullable for chat-mode agents
|
|
286
|
+
* and pre-migration rows; consumers fall back to project.defaultBranch.
|
|
287
|
+
*/
|
|
288
|
+
baseRef: import_zod3.z.string().nullable(),
|
|
289
|
+
/**
|
|
290
|
+
* Per-agent system prompt (managed_agent profile Phase D). Seeded at
|
|
291
|
+
* creation from the workload default and frozen for the agent's lifetime.
|
|
292
|
+
* `null` → control-worker omits `PilotCoderRunConfigV1.systemPrompt` and
|
|
293
|
+
* agent-worker falls back to the platform-level `SYSTEM_PROMPT`.
|
|
294
|
+
*/
|
|
295
|
+
systemPrompt: import_zod3.z.string().nullable(),
|
|
296
|
+
createdBy: import_zod3.z.string().nullable(),
|
|
297
|
+
messagesJson: import_zod3.z.unknown().nullable(),
|
|
298
|
+
// JSONB - lightweight snapshot
|
|
299
|
+
lastCheckpointId: import_zod3.z.string().uuid().nullable(),
|
|
300
|
+
activeStreamId: import_zod3.z.string().nullable(),
|
|
301
|
+
/** External IM source that created this agent. See specs/features/wecom-chat-integration.md. */
|
|
302
|
+
externalChatSource: ExternalChatSourceSchema.nullable(),
|
|
303
|
+
/** External IM user identifier (e.g. WeCom userid). Unique per (project, source, chatid). */
|
|
304
|
+
externalChatUserid: import_zod3.z.string().nullable(),
|
|
305
|
+
/** External IM chat/conversation identifier. NULL for single chats; set to WeCom `chatid`
|
|
306
|
+
* for group-chat conversations. Part of the composite uniqueness key (2026-04-22). */
|
|
307
|
+
externalChatChatid: import_zod3.z.string().nullable(),
|
|
308
|
+
createdAt: import_zod3.z.date(),
|
|
309
|
+
updatedAt: import_zod3.z.date(),
|
|
310
|
+
lastActiveAt: import_zod3.z.date()
|
|
311
|
+
});
|
|
312
|
+
var ArtifactKindSchema = import_zod4.z.enum([
|
|
313
|
+
"diff",
|
|
314
|
+
"patch",
|
|
315
|
+
"log",
|
|
316
|
+
"screenshot",
|
|
317
|
+
"video",
|
|
318
|
+
"build",
|
|
319
|
+
"report"
|
|
320
|
+
]);
|
|
321
|
+
var ArtifactManifestSchema = import_zod4.z.object({
|
|
322
|
+
path: import_zod4.z.string(),
|
|
323
|
+
kind: ArtifactKindSchema,
|
|
324
|
+
contentType: import_zod4.z.string(),
|
|
325
|
+
size: import_zod4.z.number().int().nonnegative(),
|
|
326
|
+
checksum: import_zod4.z.string(),
|
|
327
|
+
required: import_zod4.z.boolean()
|
|
328
|
+
});
|
|
329
|
+
var ArtifactSchema = import_zod4.z.object({
|
|
330
|
+
id: import_zod4.z.string().uuid(),
|
|
331
|
+
runId: import_zod4.z.string().uuid(),
|
|
332
|
+
kind: ArtifactKindSchema,
|
|
333
|
+
path: import_zod4.z.string(),
|
|
334
|
+
storagePath: import_zod4.z.string(),
|
|
335
|
+
contentType: import_zod4.z.string(),
|
|
336
|
+
size: import_zod4.z.number().int().nonnegative(),
|
|
337
|
+
checksum: import_zod4.z.string(),
|
|
338
|
+
createdAt: import_zod4.z.date()
|
|
339
|
+
});
|
|
340
|
+
var CreateRunResponseSchema = import_zod5.z.object({
|
|
341
|
+
runId: import_zod5.z.string().uuid(),
|
|
342
|
+
agentId: import_zod5.z.string().uuid(),
|
|
343
|
+
isNewAgent: import_zod5.z.boolean()
|
|
344
|
+
});
|
|
345
|
+
var ApiResponseSchema = import_zod5.z.object({
|
|
346
|
+
success: import_zod5.z.boolean(),
|
|
347
|
+
data: import_zod5.z.unknown().optional(),
|
|
348
|
+
error: import_zod5.z.string().optional(),
|
|
349
|
+
code: import_zod5.z.string().optional(),
|
|
350
|
+
message: import_zod5.z.string().optional()
|
|
351
|
+
});
|
|
352
|
+
var FollowUpRequestSchema = import_zod5.z.object({
|
|
353
|
+
runId: import_zod5.z.string().uuid(),
|
|
354
|
+
message: import_zod5.z.string().min(1)
|
|
355
|
+
});
|
|
356
|
+
var AbortRequestSchema = import_zod5.z.object({
|
|
357
|
+
runId: import_zod5.z.string().uuid(),
|
|
358
|
+
reason: import_zod5.z.string().optional()
|
|
359
|
+
});
|
|
360
|
+
var GitProviderSchema = import_zod8.z.enum(["gitlab", "github"]);
|
|
361
|
+
var ProjectKindSchema = import_zod8.z.enum(["coding", "general"]);
|
|
362
|
+
var ProjectSchema = import_zod8.z.object({
|
|
363
|
+
id: import_zod8.z.string().uuid(),
|
|
364
|
+
name: import_zod8.z.string().min(1),
|
|
365
|
+
kind: ProjectKindSchema.default("coding"),
|
|
366
|
+
/**
|
|
367
|
+
* `true` for the built-in `Platform Default` project (id =
|
|
368
|
+
* `PLATFORM_DEFAULT_PROJECT_ID`). System projects are visible to every
|
|
369
|
+
* authenticated user but read-only at the UI layer.
|
|
370
|
+
*
|
|
371
|
+
* See plans/admin-ui-project-namespacing.md §L1.1 (C3).
|
|
372
|
+
*/
|
|
373
|
+
isSystem: import_zod8.z.boolean().default(false),
|
|
374
|
+
gitProvider: GitProviderSchema.nullable(),
|
|
375
|
+
gitlabProjectId: import_zod8.z.string().nullable(),
|
|
376
|
+
gitlabProjectPath: import_zod8.z.string().nullable(),
|
|
377
|
+
githubRepoFullName: import_zod8.z.string().nullable(),
|
|
378
|
+
githubRepoId: import_zod8.z.string().nullable(),
|
|
379
|
+
/** Cached installation id for follow-up runs; authoritative value is on runs. */
|
|
380
|
+
githubInstallationId: import_zod8.z.string().nullable(),
|
|
381
|
+
repoUrl: import_zod8.z.string().nullable(),
|
|
382
|
+
defaultBranch: import_zod8.z.string().default("main"),
|
|
383
|
+
defaultModel: import_zod8.z.string().nullable(),
|
|
384
|
+
description: import_zod8.z.string().nullable(),
|
|
385
|
+
webhookEnabled: import_zod8.z.boolean().default(false),
|
|
386
|
+
webhookTriggerLabel: import_zod8.z.string().default("pilot"),
|
|
387
|
+
webhookSecret: import_zod8.z.string().nullable(),
|
|
388
|
+
webhookPromptTemplate: import_zod8.z.string().nullable(),
|
|
389
|
+
/** WeCom aibot long-connection integration toggle. See specs/features/wecom-chat-integration.md. */
|
|
390
|
+
wecomEnabled: import_zod8.z.boolean().default(false),
|
|
391
|
+
/** WeCom aibot ID; unique across projects, reverse-lookup from incoming messages. */
|
|
392
|
+
wecomBotId: import_zod8.z.string().nullable(),
|
|
393
|
+
/** Reference to `credential_bindings.name` holding the long-connection SDK secret. */
|
|
394
|
+
wecomSecretRef: import_zod8.z.string().nullable(),
|
|
395
|
+
/** Optional prompt prefix prepended to user message when creating a wecom_chat Run. */
|
|
396
|
+
wecomPromptTemplate: import_zod8.z.string().nullable(),
|
|
397
|
+
createdAt: import_zod8.z.date(),
|
|
398
|
+
updatedAt: import_zod8.z.date()
|
|
399
|
+
});
|
|
400
|
+
var WebhookTriggerContextSchema = import_zod9.z.discriminatedUnion("provider", [
|
|
401
|
+
import_zod9.z.object({
|
|
402
|
+
provider: import_zod9.z.literal("github"),
|
|
403
|
+
/** `owner/repo`, e.g. `pilot-ai/pilot` */
|
|
404
|
+
repoFullName: import_zod9.z.string().min(1),
|
|
405
|
+
/** Issue or Pull Request number. */
|
|
406
|
+
number: import_zod9.z.number().int().positive(),
|
|
407
|
+
/** True when the trigger came from a PR (GitHub issue_comment fires for both). */
|
|
408
|
+
isPr: import_zod9.z.boolean(),
|
|
409
|
+
/** Id of the @mention comment that triggered the run (if applicable). */
|
|
410
|
+
commentId: import_zod9.z.number().int().positive().optional(),
|
|
411
|
+
/**
|
|
412
|
+
* Installation token minted by Control Worker (GitHub App). TTL ≤ 1h;
|
|
413
|
+
* Agent Worker uses this to back `GitHubClient` directly.
|
|
414
|
+
*/
|
|
415
|
+
installationToken: import_zod9.z.string().min(1),
|
|
416
|
+
/** Custom GitHub API base URL (GitHub Enterprise). */
|
|
417
|
+
apiUrl: import_zod9.z.string().url().optional()
|
|
418
|
+
}),
|
|
419
|
+
import_zod9.z.object({
|
|
420
|
+
provider: import_zod9.z.literal("gitlab"),
|
|
421
|
+
/** `group/subgroup/project`. */
|
|
422
|
+
projectPath: import_zod9.z.string().min(1),
|
|
423
|
+
/** Issue IID or Merge Request IID. */
|
|
424
|
+
iid: import_zod9.z.number().int().positive(),
|
|
425
|
+
/** True when the trigger came from an MR note. */
|
|
426
|
+
isMr: import_zod9.z.boolean(),
|
|
427
|
+
/** Id of the note that triggered the run (if applicable). */
|
|
428
|
+
noteId: import_zod9.z.number().int().positive().optional(),
|
|
429
|
+
/** Decrypted OAuth / PAT token used to build `GitLabClient`. */
|
|
430
|
+
accessToken: import_zod9.z.string().min(1),
|
|
431
|
+
/** GitLab instance URL (e.g. `https://gitlab.example.com`). */
|
|
432
|
+
instanceUrl: import_zod9.z.string().url()
|
|
433
|
+
})
|
|
434
|
+
]);
|
|
435
|
+
var CheckpointStatusSchema = import_zod7.z.enum(["in_progress", "completed", "failed"]);
|
|
436
|
+
var RecoveryTypeSchema = import_zod7.z.enum([
|
|
437
|
+
"normal",
|
|
438
|
+
// 正常恢复(有 checkpoint)
|
|
439
|
+
"zero_context",
|
|
440
|
+
// 零起点恢复(无 checkpoint,预期)
|
|
441
|
+
"context_loss"
|
|
442
|
+
// 上下文丢失(有 checkpoint 但丢失,异常)
|
|
443
|
+
]);
|
|
444
|
+
var DegradedReasonSchema = import_zod7.z.enum([
|
|
445
|
+
"no_checkpoint",
|
|
446
|
+
// 无 checkpoint
|
|
447
|
+
"context_mismatch",
|
|
448
|
+
// 上下文不一致
|
|
449
|
+
"checkpoint_corrupt",
|
|
450
|
+
// Checkpoint 损坏
|
|
451
|
+
"checkpoint_storage_unavailable"
|
|
452
|
+
// 对象存储 checkpoint 不可用(Phase 2 未实现)
|
|
453
|
+
]);
|
|
454
|
+
var CheckpointTriggerSourceSchema = import_zod7.z.enum([
|
|
455
|
+
"finalization",
|
|
456
|
+
// Run Finalization 后(Phase 1)
|
|
457
|
+
"turn_count",
|
|
458
|
+
// Turn 计数触发(Phase 2)
|
|
459
|
+
"time_interval",
|
|
460
|
+
// 定时器触发(Phase 2)
|
|
461
|
+
"critical_tool",
|
|
462
|
+
// 关键工具调用触发(Phase 2)
|
|
463
|
+
"idle"
|
|
464
|
+
// Sandbox idle 前触发(Phase 2)
|
|
465
|
+
]);
|
|
466
|
+
var RunCheckpointSchema = import_zod7.z.object({
|
|
467
|
+
id: import_zod7.z.string().uuid(),
|
|
468
|
+
agentId: import_zod7.z.string().uuid(),
|
|
469
|
+
runId: import_zod7.z.string().uuid().nullable(),
|
|
470
|
+
checkpointStatus: CheckpointStatusSchema,
|
|
471
|
+
messagesSnapshot: import_zod7.z.array(import_zod7.z.unknown()).nullable(),
|
|
472
|
+
messagesSnapshotRef: import_zod7.z.string().nullable(),
|
|
473
|
+
lastEventCursor: import_zod7.z.number().int().nullable(),
|
|
474
|
+
pendingToolCalls: import_zod7.z.unknown().nullable(),
|
|
475
|
+
workspaceDeltaManifestRef: import_zod7.z.string().nullable(),
|
|
476
|
+
runtimeProfileSnapshot: import_zod7.z.record(import_zod7.z.unknown()).nullable(),
|
|
477
|
+
triggerSource: CheckpointTriggerSourceSchema.nullable().optional(),
|
|
478
|
+
degradedRecovery: import_zod7.z.boolean().default(false),
|
|
479
|
+
createdAt: import_zod7.z.date()
|
|
480
|
+
});
|
|
481
|
+
var AgentRestoreRequestSchema = import_zod7.z.object({
|
|
482
|
+
runId: import_zod7.z.string(),
|
|
483
|
+
agentId: import_zod7.z.string(),
|
|
484
|
+
messages: import_zod7.z.array(import_zod7.z.unknown()),
|
|
485
|
+
messagesHash: import_zod7.z.string(),
|
|
486
|
+
lastEventId: import_zod7.z.number().int().optional(),
|
|
487
|
+
pendingToolCalls: import_zod7.z.array(import_zod7.z.unknown()).optional(),
|
|
488
|
+
workspaceHydrationRef: import_zod7.z.string().optional(),
|
|
489
|
+
runtimeProfileSnapshot: import_zod7.z.record(import_zod7.z.unknown()).optional(),
|
|
490
|
+
degradedRecovery: import_zod7.z.boolean().optional()
|
|
491
|
+
});
|
|
492
|
+
var AgentRestoreResponseSchema = import_zod7.z.object({
|
|
493
|
+
success: import_zod7.z.boolean(),
|
|
494
|
+
recovered: import_zod7.z.boolean(),
|
|
495
|
+
messagesHash: import_zod7.z.string().optional(),
|
|
496
|
+
messagesCount: import_zod7.z.number().int().optional(),
|
|
497
|
+
degradedRecovery: import_zod7.z.boolean().optional(),
|
|
498
|
+
error: import_zod7.z.string().optional()
|
|
499
|
+
});
|
|
500
|
+
var McpServerEntrySchema = import_zod7.z.union([
|
|
501
|
+
// stdio entry
|
|
502
|
+
import_zod7.z.object({
|
|
503
|
+
command: import_zod7.z.string().min(1),
|
|
504
|
+
args: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
505
|
+
env: import_zod7.z.record(import_zod7.z.string()).optional()
|
|
506
|
+
}).passthrough(),
|
|
507
|
+
// http / sse entry
|
|
508
|
+
import_zod7.z.object({
|
|
509
|
+
type: import_zod7.z.enum(["http", "sse"]),
|
|
510
|
+
url: import_zod7.z.string().url(),
|
|
511
|
+
headers: import_zod7.z.record(import_zod7.z.string()).optional()
|
|
512
|
+
}).passthrough()
|
|
513
|
+
]);
|
|
514
|
+
var McpServersMapSchema = import_zod7.z.record(McpServerEntrySchema);
|
|
515
|
+
var PromptRequestSchema = import_zod7.z.object({
|
|
516
|
+
runId: import_zod7.z.string().optional(),
|
|
517
|
+
agentId: import_zod7.z.string().optional(),
|
|
518
|
+
prompt: import_zod7.z.string().min(1),
|
|
519
|
+
provider: ProviderTypeSchema.optional(),
|
|
520
|
+
model: import_zod7.z.string().optional(),
|
|
521
|
+
workspacePath: import_zod7.z.string().optional(),
|
|
522
|
+
/**
|
|
523
|
+
* Directory holding the bootstrap-rendered `.mcp.json`. Decoupled from
|
|
524
|
+
* `workspacePath` (which is the agent CWD = user repo) so MCP config never
|
|
525
|
+
* lands inside the user's project tree. When omitted, agent-worker falls
|
|
526
|
+
* back to `workspacePath` for backwards compatibility.
|
|
527
|
+
*/
|
|
528
|
+
mcpConfigDir: import_zod7.z.string().optional(),
|
|
529
|
+
attachments: import_zod7.z.array(AttachmentMetaSchema).max(5).optional(),
|
|
530
|
+
/**
|
|
531
|
+
* Runtime-derived context for webhook-triggered runs. When present, Agent
|
|
532
|
+
* Worker injects a set of read-only provider tools so the agent can pull
|
|
533
|
+
* Issue/PR body / history / diff on demand. See `webhook-context.ts`.
|
|
534
|
+
*/
|
|
535
|
+
triggerContext: WebhookTriggerContextSchema.optional(),
|
|
536
|
+
/**
|
|
537
|
+
* Resolved MCP servers to inject directly into the SDK (preferred over
|
|
538
|
+
* `<mcpConfigDir>/.mcp.json`). When omitted, the agent-worker falls back
|
|
539
|
+
* to reading `.mcp.json` from `mcpConfigDir` / `workspacePath` (the legacy
|
|
540
|
+
* bootstrap path).
|
|
541
|
+
*/
|
|
542
|
+
mcpServers: McpServersMapSchema.optional(),
|
|
543
|
+
/**
|
|
544
|
+
* Run-scoped environment variables to inject into the AI CLI subprocess
|
|
545
|
+
* spawned by agent-worker (e.g. `MCP_<NAME>_BEARER_TOKEN` referenced by
|
|
546
|
+
* codex `config.toml`'s `bearer_token_env_var`). Pilot keeps these out
|
|
547
|
+
* of the on-disk config files so tokens never land on the sandbox FS.
|
|
548
|
+
* Merged into `ProviderConfig.env` by agent-worker.
|
|
549
|
+
*/
|
|
550
|
+
env: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).optional(),
|
|
551
|
+
projectKind: ProjectKindSchema.optional().default("coding")
|
|
552
|
+
});
|
|
553
|
+
var FollowupRequestSchema = import_zod7.z.object({
|
|
554
|
+
runId: import_zod7.z.string().optional(),
|
|
555
|
+
agentId: import_zod7.z.string().optional(),
|
|
556
|
+
message: import_zod7.z.string(),
|
|
557
|
+
provider: ProviderTypeSchema.optional(),
|
|
558
|
+
model: import_zod7.z.string().optional(),
|
|
559
|
+
workspacePath: import_zod7.z.string().optional(),
|
|
560
|
+
/** See `PromptRequestSchema.mcpConfigDir`. */
|
|
561
|
+
mcpConfigDir: import_zod7.z.string().optional(),
|
|
562
|
+
expectedMessagesHash: import_zod7.z.string().optional(),
|
|
563
|
+
expectedMessagesCount: import_zod7.z.number().int().optional(),
|
|
564
|
+
attachments: import_zod7.z.array(AttachmentMetaSchema).max(5).optional(),
|
|
565
|
+
/** See `PromptRequestSchema.mcpServers` — same semantics for follow-ups. */
|
|
566
|
+
mcpServers: McpServersMapSchema.optional(),
|
|
567
|
+
/** See `PromptRequestSchema.env` — same semantics for follow-ups. */
|
|
568
|
+
env: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()).optional(),
|
|
569
|
+
projectKind: ProjectKindSchema.optional().default("coding")
|
|
570
|
+
});
|
|
571
|
+
var RunnerRestorePolicySchema = import_zod7.z.enum(["restart", "lazy-start", "skip"]);
|
|
572
|
+
var HydrationCategorySchema = import_zod7.z.enum([
|
|
573
|
+
"conversation",
|
|
574
|
+
"workspace",
|
|
575
|
+
"runtimeEnv",
|
|
576
|
+
"runner",
|
|
577
|
+
"attachments",
|
|
578
|
+
"artifactsRef"
|
|
579
|
+
]);
|
|
580
|
+
var HydrationManifestEntrySchema = import_zod7.z.object({
|
|
581
|
+
category: HydrationCategorySchema,
|
|
582
|
+
ref: import_zod7.z.string(),
|
|
583
|
+
checksum: import_zod7.z.string().optional(),
|
|
584
|
+
size: import_zod7.z.number().int().optional()
|
|
585
|
+
});
|
|
586
|
+
var UIMessageChunkTypeSchema = import_zod6.z.enum([
|
|
587
|
+
"text-start",
|
|
588
|
+
"text-delta",
|
|
589
|
+
"text-end",
|
|
590
|
+
"reasoning-start",
|
|
591
|
+
"reasoning-delta",
|
|
592
|
+
"reasoning-end",
|
|
593
|
+
"tool-input-start",
|
|
594
|
+
"tool-input-delta",
|
|
595
|
+
"tool-input-available",
|
|
596
|
+
"tool-output-available",
|
|
597
|
+
"tool-output-error",
|
|
598
|
+
"start",
|
|
599
|
+
"finish",
|
|
600
|
+
"error",
|
|
601
|
+
"start-step",
|
|
602
|
+
"finish-step"
|
|
603
|
+
]);
|
|
604
|
+
var UIMessageChunkSchema = import_zod6.z.object({
|
|
605
|
+
type: UIMessageChunkTypeSchema,
|
|
606
|
+
id: import_zod6.z.string().optional(),
|
|
607
|
+
content: import_zod6.z.string().optional(),
|
|
608
|
+
delta: import_zod6.z.string().optional(),
|
|
609
|
+
toolCallId: import_zod6.z.string().optional(),
|
|
610
|
+
toolName: import_zod6.z.string().optional(),
|
|
611
|
+
input: import_zod6.z.unknown().optional(),
|
|
612
|
+
output: import_zod6.z.string().optional(),
|
|
613
|
+
errorText: import_zod6.z.string().optional(),
|
|
614
|
+
reason: import_zod6.z.string().optional(),
|
|
615
|
+
preliminary: import_zod6.z.boolean().optional()
|
|
616
|
+
});
|
|
617
|
+
var RunEventSchema = import_zod6.z.object({
|
|
618
|
+
id: import_zod6.z.string().uuid(),
|
|
619
|
+
runId: import_zod6.z.string().uuid(),
|
|
620
|
+
eventType: import_zod6.z.string(),
|
|
621
|
+
payload: import_zod6.z.unknown(),
|
|
622
|
+
cursor: import_zod6.z.number().int(),
|
|
623
|
+
createdAt: import_zod6.z.date()
|
|
624
|
+
});
|
|
625
|
+
var AgentRecoveryStartedEventSchema = import_zod6.z.object({
|
|
626
|
+
type: import_zod6.z.literal("agent_recovery_started"),
|
|
627
|
+
agentId: import_zod6.z.string(),
|
|
628
|
+
sandboxId: import_zod6.z.string(),
|
|
629
|
+
degradedRecovery: import_zod6.z.boolean(),
|
|
630
|
+
degradedReason: DegradedReasonSchema.optional(),
|
|
631
|
+
recoveryType: RecoveryTypeSchema
|
|
632
|
+
});
|
|
633
|
+
var AgentRecoveryHydratedEventSchema = import_zod6.z.object({
|
|
634
|
+
type: import_zod6.z.literal("agent_recovery_hydrated"),
|
|
635
|
+
agentId: import_zod6.z.string(),
|
|
636
|
+
checkpointId: import_zod6.z.string().nullable(),
|
|
637
|
+
messagesCount: import_zod6.z.number(),
|
|
638
|
+
degradedRecovery: import_zod6.z.boolean()
|
|
639
|
+
});
|
|
640
|
+
var RecoveredFromCheckpointEventSchema = import_zod6.z.object({
|
|
641
|
+
type: import_zod6.z.literal("recovered_from_checkpoint"),
|
|
642
|
+
checkpointId: import_zod6.z.string(),
|
|
643
|
+
lastEventCursor: import_zod6.z.number().int().nullable()
|
|
644
|
+
});
|
|
645
|
+
var AgentRecoveryCompletedEventSchema = import_zod6.z.object({
|
|
646
|
+
type: import_zod6.z.literal("agent_recovery_completed"),
|
|
647
|
+
agentId: import_zod6.z.string(),
|
|
648
|
+
degradedRecovery: import_zod6.z.boolean()
|
|
649
|
+
});
|
|
650
|
+
var AgentRecoveryFailedEventSchema = import_zod6.z.object({
|
|
651
|
+
type: import_zod6.z.literal("agent_recovery_failed"),
|
|
652
|
+
agentId: import_zod6.z.string(),
|
|
653
|
+
errorStage: import_zod6.z.string(),
|
|
654
|
+
errorMessage: import_zod6.z.string(),
|
|
655
|
+
degradedReason: DegradedReasonSchema.optional(),
|
|
656
|
+
contextExpected: import_zod6.z.number().optional(),
|
|
657
|
+
contextActual: import_zod6.z.number().optional()
|
|
658
|
+
});
|
|
659
|
+
var SandboxStatusSchema = import_zod10.z.enum([
|
|
660
|
+
"creating",
|
|
661
|
+
"running",
|
|
662
|
+
"idle",
|
|
663
|
+
"destroying",
|
|
664
|
+
"destroyed",
|
|
665
|
+
"error"
|
|
666
|
+
]);
|
|
667
|
+
var SandboxPublicEndpointSchema = import_zod10.z.object({
|
|
668
|
+
name: import_zod10.z.string(),
|
|
669
|
+
url: import_zod10.z.string(),
|
|
670
|
+
host: import_zod10.z.string(),
|
|
671
|
+
path: import_zod10.z.string()
|
|
672
|
+
});
|
|
673
|
+
var SandboxInfoSchema = import_zod10.z.object({
|
|
674
|
+
id: import_zod10.z.string(),
|
|
675
|
+
status: SandboxStatusSchema,
|
|
676
|
+
podIp: import_zod10.z.string().nullable(),
|
|
677
|
+
agentEndpoint: import_zod10.z.string().nullable(),
|
|
678
|
+
createdAt: import_zod10.z.date(),
|
|
679
|
+
ttlSeconds: import_zod10.z.number().int().optional(),
|
|
680
|
+
templateName: import_zod10.z.string().optional(),
|
|
681
|
+
labels: import_zod10.z.record(import_zod10.z.string()).optional(),
|
|
682
|
+
/**
|
|
683
|
+
* GAP 3 — sandbox-actual public endpoints transited from the provider SDK.
|
|
684
|
+
* Optional/absent for providers that do not report them (and for legacy
|
|
685
|
+
* call sites); downstream consumers MUST treat absence as "no transit data"
|
|
686
|
+
* and fall back to declaration-derived URLs.
|
|
687
|
+
*/
|
|
688
|
+
publicEndpoints: import_zod10.z.array(SandboxPublicEndpointSchema).optional()
|
|
689
|
+
});
|
|
690
|
+
var CreateSandboxOptionsSchema = import_zod10.z.object({
|
|
691
|
+
templateName: import_zod10.z.string(),
|
|
692
|
+
/**
|
|
693
|
+
* Caller-supplied stable claim name. When omitted, the provider lets the
|
|
694
|
+
* sandbox control plane generate a per-sandbox id (`claim-<nanoTS>`), which
|
|
695
|
+
* changes on every create — so the derived public ingress host
|
|
696
|
+
* (`<hostPrefix>-<claimName>.<baseDomain>`) drifts across recreate.
|
|
697
|
+
*
|
|
698
|
+
* Supplying a stable, caller-controlled value (e.g. a project-scoped key)
|
|
699
|
+
* keeps the ingress host stable across abort→recreate cycles (GAP 1 = B:
|
|
700
|
+
* scale-to-zero is abort + recreate, not pause/wake). MUST be DNS-label safe
|
|
701
|
+
* (lowercase alphanumeric + hyphen); the control plane truncates the
|
|
702
|
+
* `<hostPrefix>-<claimName>` first label to 63 chars, so callers must ensure
|
|
703
|
+
* the distinguishing portion fits within budget.
|
|
704
|
+
*/
|
|
705
|
+
claimName: import_zod10.z.string().optional(),
|
|
706
|
+
image: import_zod10.z.string().optional(),
|
|
707
|
+
env: import_zod10.z.record(import_zod10.z.string()).optional(),
|
|
708
|
+
ttlSeconds: import_zod10.z.number().int().positive().optional(),
|
|
709
|
+
metadata: import_zod10.z.record(import_zod10.z.string()).optional(),
|
|
710
|
+
labels: import_zod10.z.record(import_zod10.z.string()).optional()
|
|
711
|
+
});
|
|
712
|
+
var ExecResultSchema = import_zod10.z.object({
|
|
713
|
+
exitCode: import_zod10.z.number().int(),
|
|
714
|
+
stdout: import_zod10.z.string(),
|
|
715
|
+
stderr: import_zod10.z.string()
|
|
716
|
+
});
|
|
717
|
+
var MergeRequestStatusSchema = import_zod11.z.enum(["creating", "open", "merged", "closed", "failed"]);
|
|
718
|
+
var MergeRequestSchema = import_zod11.z.object({
|
|
719
|
+
id: import_zod11.z.string().uuid(),
|
|
720
|
+
runId: import_zod11.z.string().uuid(),
|
|
721
|
+
projectId: import_zod11.z.string().uuid(),
|
|
722
|
+
externalId: import_zod11.z.string().nullable(),
|
|
723
|
+
externalUrl: import_zod11.z.string().nullable(),
|
|
724
|
+
sourceBranch: import_zod11.z.string(),
|
|
725
|
+
targetBranch: import_zod11.z.string(),
|
|
726
|
+
title: import_zod11.z.string(),
|
|
727
|
+
description: import_zod11.z.string().nullable(),
|
|
728
|
+
status: MergeRequestStatusSchema,
|
|
729
|
+
createdAt: import_zod11.z.date(),
|
|
730
|
+
updatedAt: import_zod11.z.date()
|
|
731
|
+
});
|
|
732
|
+
var HealthCheckConfigSchema = import_zod12.z.object({
|
|
733
|
+
type: import_zod12.z.enum(["http", "tcp", "command"]),
|
|
734
|
+
port: import_zod12.z.number().int().optional(),
|
|
735
|
+
path: import_zod12.z.string().optional(),
|
|
736
|
+
command: import_zod12.z.string().optional(),
|
|
737
|
+
intervalMs: import_zod12.z.number().int().positive().default(5e3),
|
|
738
|
+
timeoutMs: import_zod12.z.number().int().positive().default(3e3),
|
|
739
|
+
retries: import_zod12.z.number().int().nonnegative().default(3)
|
|
740
|
+
});
|
|
741
|
+
var RuntimeProfileSchema = import_zod12.z.object({
|
|
742
|
+
id: import_zod12.z.string().uuid(),
|
|
743
|
+
projectId: import_zod12.z.string().uuid(),
|
|
744
|
+
version: import_zod12.z.number().int().positive(),
|
|
745
|
+
env: import_zod12.z.record(import_zod12.z.string()).default({}),
|
|
746
|
+
secretRefs: import_zod12.z.record(import_zod12.z.string()).default({}),
|
|
747
|
+
workingDirectory: import_zod12.z.string().default("/workspace"),
|
|
748
|
+
runnerCommand: import_zod12.z.string().optional(),
|
|
749
|
+
runnerPorts: import_zod12.z.array(import_zod12.z.number().int().positive()).optional(),
|
|
750
|
+
healthCheck: HealthCheckConfigSchema.optional(),
|
|
751
|
+
prepareCommands: import_zod12.z.array(import_zod12.z.string()).optional(),
|
|
752
|
+
status: import_zod12.z.enum(["active", "archived"]).default("active"),
|
|
753
|
+
createdAt: import_zod12.z.date(),
|
|
754
|
+
updatedAt: import_zod12.z.date()
|
|
755
|
+
});
|
|
756
|
+
var MAX_SUMMARIZE_PROMPT_CHARS = 1e4;
|
|
757
|
+
var SummarizeRequestSchema = import_zod13.z.object({
|
|
758
|
+
/** Full diff text (legacy mode). Optional when repoDir is provided. */
|
|
759
|
+
diff: import_zod13.z.string().min(1).optional(),
|
|
760
|
+
/** Workspace repo directory path (agentic mode). Must be an absolute path. */
|
|
761
|
+
repoDir: import_zod13.z.string().startsWith("/", { message: "repoDir must be an absolute path" }).optional(),
|
|
762
|
+
/** Git diff reference, e.g. "--cached" or "origin/main...HEAD". */
|
|
763
|
+
diffRef: import_zod13.z.string().regex(/^(--cached|[a-zA-Z0-9_.\-\/~^]+(\.\.\.?[a-zA-Z0-9_.\-\/~^]+)?)$/, {
|
|
764
|
+
message: "diffRef must be '--cached' or a valid git ref (e.g. 'origin/main..HEAD', 'origin/main...HEAD')"
|
|
765
|
+
}).optional(),
|
|
766
|
+
prompt: import_zod13.z.string().max(MAX_SUMMARIZE_PROMPT_CHARS).optional(),
|
|
767
|
+
model: import_zod13.z.string().optional()
|
|
768
|
+
}).refine((data) => data.diff || data.repoDir, {
|
|
769
|
+
message: "Either 'diff' or 'repoDir' must be provided"
|
|
770
|
+
});
|
|
771
|
+
var SummarizeResponseSchema = import_zod13.z.object({
|
|
772
|
+
commitMessage: import_zod13.z.string().min(1).max(200).describe(
|
|
773
|
+
"Single-line commit message in conventional commits format: <type>(<scope>): <description>"
|
|
774
|
+
),
|
|
775
|
+
prTitle: import_zod13.z.string().min(1).max(256).describe(
|
|
776
|
+
"Pull request title, descriptive. Aim for under 72 characters but the schema accepts up to 256 (GitHub/GitLab hard limit) to tolerate model overshoot."
|
|
777
|
+
),
|
|
778
|
+
prDescription: import_zod13.z.string().min(1).describe(
|
|
779
|
+
"Pull request description in markdown. Start with ## Changes, then list key changes as bullet points."
|
|
780
|
+
)
|
|
781
|
+
});
|
|
782
|
+
var MAX_WORKSPACE_DIFF_BYTES = 20 * 1024 * 1024;
|
|
783
|
+
var WorkspaceDiffStatResponseSchema = import_zod14.z.object({
|
|
784
|
+
filesChanged: import_zod14.z.number().int().nonnegative(),
|
|
785
|
+
insertions: import_zod14.z.number().int().nonnegative(),
|
|
786
|
+
deletions: import_zod14.z.number().int().nonnegative(),
|
|
787
|
+
estimatedBytes: import_zod14.z.number().int().nonnegative()
|
|
788
|
+
});
|
|
789
|
+
var AGENT_PUSH_OUTPUT_TRUNCATE_BYTES = 8 * 1024;
|
|
790
|
+
var AGENT_PUSH_MAX_ATTEMPTS = 3;
|
|
791
|
+
var AgentPushRetryReasonSchema = import_zod15.z.enum([
|
|
792
|
+
"gnutls_recv_error",
|
|
793
|
+
"rpc_failed",
|
|
794
|
+
"connection_reset",
|
|
795
|
+
"timeout",
|
|
796
|
+
"broken_pipe",
|
|
797
|
+
"early_eof",
|
|
798
|
+
"dns"
|
|
799
|
+
]);
|
|
800
|
+
var AgentPushAuthSchema = import_zod15.z.discriminatedUnion("kind", [
|
|
801
|
+
import_zod15.z.object({
|
|
802
|
+
kind: import_zod15.z.literal("github"),
|
|
803
|
+
username: import_zod15.z.string().min(1),
|
|
804
|
+
token: import_zod15.z.string().min(1)
|
|
805
|
+
}),
|
|
806
|
+
import_zod15.z.object({
|
|
807
|
+
kind: import_zod15.z.literal("gitlab"),
|
|
808
|
+
token: import_zod15.z.string().min(1)
|
|
809
|
+
})
|
|
810
|
+
]);
|
|
811
|
+
var AgentPushRequestSchema = import_zod15.z.object({
|
|
812
|
+
/** Absolute path inside the sandbox to the git working directory. */
|
|
813
|
+
repoDir: import_zod15.z.string().refine((s) => s.startsWith("/"), {
|
|
814
|
+
message: "repoDir must be an absolute path"
|
|
815
|
+
}),
|
|
816
|
+
/** Remote name, typically `origin`. */
|
|
817
|
+
remote: import_zod15.z.string().min(1).default("origin"),
|
|
818
|
+
/** Branch to push. */
|
|
819
|
+
branch: import_zod15.z.string().min(1),
|
|
820
|
+
/** When true, appends `--force`. Default `false`. */
|
|
821
|
+
force: import_zod15.z.boolean().default(false),
|
|
822
|
+
auth: AgentPushAuthSchema
|
|
823
|
+
});
|
|
824
|
+
var AgentPushResponseSchema = import_zod15.z.object({
|
|
825
|
+
/** Convenience flag — equivalent to `exitCode === 0`. */
|
|
826
|
+
ok: import_zod15.z.boolean(),
|
|
827
|
+
/**
|
|
828
|
+
* Final `git push` process exit code (from the last attempt if
|
|
829
|
+
* retries happened). `0` on success. Non-zero values follow git's
|
|
830
|
+
* own conventions (e.g. `128` for fatal errors).
|
|
831
|
+
*/
|
|
832
|
+
exitCode: import_zod15.z.number().int(),
|
|
833
|
+
/** Captured stdout, truncated per AGENT_PUSH_OUTPUT_TRUNCATE_BYTES. */
|
|
834
|
+
stdout: import_zod15.z.string(),
|
|
835
|
+
/** Captured stderr, truncated per AGENT_PUSH_OUTPUT_TRUNCATE_BYTES. */
|
|
836
|
+
stderr: import_zod15.z.string(),
|
|
837
|
+
/** Total wall time across all attempts, in milliseconds. */
|
|
838
|
+
durationMs: import_zod15.z.number().int().nonnegative(),
|
|
839
|
+
/**
|
|
840
|
+
* Number of attempts actually made. Always ≥ 1 and
|
|
841
|
+
* ≤ AGENT_PUSH_MAX_ATTEMPTS.
|
|
842
|
+
*/
|
|
843
|
+
attempts: import_zod15.z.number().int().min(1).max(AGENT_PUSH_MAX_ATTEMPTS),
|
|
844
|
+
/**
|
|
845
|
+
* Reason for the most recent retry. Present only when `attempts > 1`.
|
|
846
|
+
* Absent when the initial attempt succeeded or when the failure was
|
|
847
|
+
* classified as non-transient (auth failure, non-fast-forward, etc.).
|
|
848
|
+
*/
|
|
849
|
+
lastRetryReason: AgentPushRetryReasonSchema.optional()
|
|
850
|
+
});
|
|
851
|
+
var CredentialsBrokerRequestSchema = import_zod17.z.object({}).strict();
|
|
852
|
+
var GitProviderCredentialSchema = import_zod17.z.object({
|
|
853
|
+
/** Git hosting provider name. */
|
|
854
|
+
provider: import_zod17.z.enum(["github", "gitlab"]),
|
|
855
|
+
/**
|
|
856
|
+
* Short-lived access token. For GitHub App, this is an installation
|
|
857
|
+
* token (~1 hour TTL). For GitLab OAuth, this is the just-refreshed
|
|
858
|
+
* access token.
|
|
859
|
+
*/
|
|
860
|
+
accessToken: import_zod17.z.string().min(1),
|
|
861
|
+
/** ISO-8601 expiry; callers MUST NOT use the token beyond this. */
|
|
862
|
+
expiresAt: import_zod17.z.string().datetime(),
|
|
863
|
+
/**
|
|
864
|
+
* Monotonic rotation counter. The Pod Agent uses this to invalidate
|
|
865
|
+
* its in-memory cache on refresh; bumps every time the broker hands
|
|
866
|
+
* out a token (so two consecutive calls return different versions
|
|
867
|
+
* even if the upstream provider returned the same string).
|
|
868
|
+
*/
|
|
869
|
+
rotationVersion: import_zod17.z.number().int().nonnegative(),
|
|
870
|
+
/** GitLab only: the instance base URL the token was minted for. */
|
|
871
|
+
instanceUrl: import_zod17.z.string().url().optional()
|
|
872
|
+
});
|
|
873
|
+
var LlmCredentialSchema = import_zod17.z.object({
|
|
874
|
+
/** LLM provider name. `bedrock` covers the per-LDAP AK/SK path. */
|
|
875
|
+
provider: import_zod17.z.enum(["bedrock", "anthropic"]),
|
|
876
|
+
/** Base URL the Worker / proxy should target. */
|
|
877
|
+
baseUrl: import_zod17.z.string().url(),
|
|
878
|
+
/**
|
|
879
|
+
* HTTP headers the proxy must send upstream. May contain the
|
|
880
|
+
* Bedrock-related AWS overrides (encoded as headers consumed by the
|
|
881
|
+
* Pod-Agent local proxy, not as bare AWS sig v4 yet — see proposal in
|
|
882
|
+
* `docs/proposals/pilot-v2-llm-proxy.md`).
|
|
883
|
+
*/
|
|
884
|
+
headers: import_zod17.z.record(import_zod17.z.string(), import_zod17.z.string()),
|
|
885
|
+
/**
|
|
886
|
+
* Optional expiry. Bedrock AK/SK are long-lived; this is present only
|
|
887
|
+
* when the underlying credential issuer (e.g. STS-backed Bedrock
|
|
888
|
+
* adapter in the future) returns a TTL.
|
|
889
|
+
*/
|
|
890
|
+
expiresAt: import_zod17.z.string().datetime().optional()
|
|
891
|
+
});
|
|
892
|
+
var OssCredentialSchema = import_zod17.z.object({
|
|
893
|
+
/** OSS region (e.g. `oss-cn-beijing`). */
|
|
894
|
+
region: import_zod17.z.string().min(1),
|
|
895
|
+
/** Target bucket. */
|
|
896
|
+
bucket: import_zod17.z.string().min(1),
|
|
897
|
+
/**
|
|
898
|
+
* Per-session prefix the Worker MUST stay within (the presigned URL
|
|
899
|
+
* is scoped to a single object key, but the prefix is exposed so the
|
|
900
|
+
* client can compose multi-key flows by requesting fresh URLs).
|
|
901
|
+
*/
|
|
902
|
+
prefix: import_zod17.z.string().min(1),
|
|
903
|
+
/**
|
|
904
|
+
* Pre-signed PUT URL for the Session's default artifact object key
|
|
905
|
+
* (`${prefix}artifact.bin` by convention). Phase 1 fallback in place
|
|
906
|
+
* of true STS credentials. Single-use semantics: callers needing a
|
|
907
|
+
* different object key MUST call this endpoint again.
|
|
908
|
+
*/
|
|
909
|
+
presignedUploadUrl: import_zod17.z.string().url(),
|
|
910
|
+
/** ISO-8601 expiry of the presigned URL. */
|
|
911
|
+
expiresAt: import_zod17.z.string().datetime(),
|
|
912
|
+
// Reserved for the future STS variant. Optional today.
|
|
913
|
+
stsAccessKeyId: import_zod17.z.string().optional(),
|
|
914
|
+
stsSecretAccessKey: import_zod17.z.string().optional(),
|
|
915
|
+
stsSessionToken: import_zod17.z.string().optional()
|
|
916
|
+
});
|
|
917
|
+
var CredentialsBrokerErrorCodeSchema = import_zod17.z.enum([
|
|
918
|
+
// 401 — authentication failures
|
|
919
|
+
"MISSING_SESSION_TOKEN",
|
|
920
|
+
"MISSING_POD_AGENT_TOKEN",
|
|
921
|
+
"SESSION_TOKEN_INVALID",
|
|
922
|
+
"SESSION_TOKEN_REVOKED",
|
|
923
|
+
"SESSION_TOKEN_EXPIRED",
|
|
924
|
+
"POD_AGENT_TOKEN_INVALID",
|
|
925
|
+
// 403 — authorization failures
|
|
926
|
+
"SESSION_TOKEN_SESSION_MISMATCH",
|
|
927
|
+
// 404 — session does not exist
|
|
928
|
+
"SESSION_NOT_FOUND",
|
|
929
|
+
// 503 — upstream credential issuer (GitHub App / Vault / OSS) is down
|
|
930
|
+
"GIT_PROVIDER_NOT_CONFIGURED",
|
|
931
|
+
"GIT_TOKEN_UNAVAILABLE",
|
|
932
|
+
"LLM_CREDENTIAL_UNAVAILABLE",
|
|
933
|
+
"OSS_STS_UNAVAILABLE",
|
|
934
|
+
// 500 — fallthrough
|
|
935
|
+
"INTERNAL_ERROR"
|
|
936
|
+
]);
|
|
937
|
+
var InvalidateKeysRequestSchema = import_zod16.z.object({
|
|
938
|
+
sessionId: import_zod16.z.string().uuid(),
|
|
939
|
+
runId: import_zod16.z.string().uuid().optional(),
|
|
940
|
+
ldap: import_zod16.z.string().min(1).max(255),
|
|
941
|
+
provider: import_zod16.z.enum(["claude-code", "codex"]),
|
|
942
|
+
observedAt: import_zod16.z.string().datetime({ offset: true }),
|
|
943
|
+
reason: import_zod16.z.string().max(500).optional()
|
|
944
|
+
});
|
|
945
|
+
var InvalidateKeysResponseSchema = import_zod16.z.object({
|
|
946
|
+
pushed: import_zod16.z.boolean(),
|
|
947
|
+
/** Optional sub-status; useful for clients to surface diagnostic detail
|
|
948
|
+
* without parsing prose. */
|
|
949
|
+
reasonCode: import_zod16.z.string().max(100).optional()
|
|
950
|
+
});
|
|
951
|
+
var ReloadCredentialsRequestSchema = import_zod16.z.object({
|
|
952
|
+
env: import_zod16.z.record(import_zod16.z.string().min(1), import_zod16.z.string()).refine((rec) => Object.keys(rec).length > 0, {
|
|
953
|
+
message: "env must contain at least one entry"
|
|
954
|
+
})
|
|
955
|
+
});
|
|
956
|
+
var ReloadCredentialsResponseSchema = import_zod16.z.object({
|
|
957
|
+
applied: import_zod16.z.array(import_zod16.z.string())
|
|
958
|
+
});
|
|
959
|
+
var PodAgentGitPushRequestSchema = import_zod18.z.object({
|
|
960
|
+
/** Lease token issued by pod-agent at worker startup; same value used by clone. */
|
|
961
|
+
leaseToken: import_zod18.z.string().min(1),
|
|
962
|
+
/** Absolute workspace path returned by an earlier `/pilot/workspace/clone`. */
|
|
963
|
+
workspaceDir: import_zod18.z.string().refine((s) => s.startsWith("/"), {
|
|
964
|
+
message: "workspaceDir must be an absolute path"
|
|
965
|
+
}),
|
|
966
|
+
/** Remote name. Defaults to `origin`. */
|
|
967
|
+
remote: import_zod18.z.string().min(1).default("origin"),
|
|
968
|
+
/** Branch to push. */
|
|
969
|
+
branch: import_zod18.z.string().min(1),
|
|
970
|
+
/** Whether to add `--force`. Default `false`. */
|
|
971
|
+
force: import_zod18.z.boolean().default(false)
|
|
972
|
+
}).strict();
|
|
973
|
+
var PodAgentGitPushResponseSchema = import_zod18.z.discriminatedUnion("kind", [
|
|
974
|
+
import_zod18.z.object({
|
|
975
|
+
kind: import_zod18.z.literal("ok"),
|
|
976
|
+
/** Final `git push` process exit code (0 = success). */
|
|
977
|
+
exitCode: import_zod18.z.number().int(),
|
|
978
|
+
/** Captured stdout, truncated per AGENT_PUSH_OUTPUT_TRUNCATE_BYTES. */
|
|
979
|
+
stdout: import_zod18.z.string(),
|
|
980
|
+
/** Captured stderr, truncated per AGENT_PUSH_OUTPUT_TRUNCATE_BYTES. */
|
|
981
|
+
stderr: import_zod18.z.string(),
|
|
982
|
+
/** Total wall time across all attempts, in milliseconds. */
|
|
983
|
+
durationMs: import_zod18.z.number().int().nonnegative(),
|
|
984
|
+
/** Number of attempts actually made (1..AGENT_PUSH_MAX_ATTEMPTS). */
|
|
985
|
+
attempts: import_zod18.z.number().int().min(1).max(AGENT_PUSH_MAX_ATTEMPTS),
|
|
986
|
+
/** Reason for the most recent retry; present only when attempts > 1. */
|
|
987
|
+
lastRetryReason: AgentPushRetryReasonSchema.optional()
|
|
988
|
+
}),
|
|
989
|
+
import_zod18.z.object({
|
|
990
|
+
kind: import_zod18.z.literal("failed"),
|
|
991
|
+
/** Human-readable failure reason; safe to surface in delivery audit row. */
|
|
992
|
+
reason: import_zod18.z.string().min(1),
|
|
993
|
+
/** Coarse failure category for caller branching. */
|
|
994
|
+
code: import_zod18.z.enum(["AUTH_FETCH_FAILED", "INVALID_WORKSPACE", "INTERNAL", "TRANSPORT_FAILED"]).optional()
|
|
995
|
+
})
|
|
996
|
+
]);
|
|
997
|
+
var WecomMsgTypeSchema = import_zod19.z.enum([
|
|
998
|
+
"text",
|
|
999
|
+
"image",
|
|
1000
|
+
"file",
|
|
1001
|
+
"mixed",
|
|
1002
|
+
"voice",
|
|
1003
|
+
"video",
|
|
1004
|
+
"stream"
|
|
1005
|
+
]);
|
|
1006
|
+
var WecomChatTypeSchema = import_zod19.z.enum(["single", "group"]);
|
|
1007
|
+
var WecomSenderSchema = import_zod19.z.object({
|
|
1008
|
+
userid: import_zod19.z.string().min(1)
|
|
1009
|
+
});
|
|
1010
|
+
var WecomTextContentSchema = import_zod19.z.object({
|
|
1011
|
+
content: import_zod19.z.string()
|
|
1012
|
+
});
|
|
1013
|
+
var WecomImageContentSchema = import_zod19.z.object({
|
|
1014
|
+
url: import_zod19.z.string().url(),
|
|
1015
|
+
/** AES-256-CBC key (Base64) tied to this specific payload. Present in
|
|
1016
|
+
* long-connection mode — use with SDK `decryptFile(buffer, aesKey)`. */
|
|
1017
|
+
aeskey: import_zod19.z.string().optional()
|
|
1018
|
+
});
|
|
1019
|
+
var WecomFileContentSchema = import_zod19.z.object({
|
|
1020
|
+
url: import_zod19.z.string().url(),
|
|
1021
|
+
/** AES-256-CBC key (Base64) tied to this specific payload. */
|
|
1022
|
+
aeskey: import_zod19.z.string().optional()
|
|
1023
|
+
});
|
|
1024
|
+
var WecomVoiceContentSchema = import_zod19.z.object({
|
|
1025
|
+
/** Voice transcribed to text by WeCom (not a URL). */
|
|
1026
|
+
content: import_zod19.z.string()
|
|
1027
|
+
});
|
|
1028
|
+
var WecomVideoContentSchema = import_zod19.z.object({
|
|
1029
|
+
url: import_zod19.z.string().url(),
|
|
1030
|
+
/** AES-256-CBC key (Base64) tied to this specific payload. */
|
|
1031
|
+
aeskey: import_zod19.z.string().optional()
|
|
1032
|
+
});
|
|
1033
|
+
var WecomMixedItemSchema = import_zod19.z.discriminatedUnion("msgtype", [
|
|
1034
|
+
import_zod19.z.object({ msgtype: import_zod19.z.literal("text"), text: WecomTextContentSchema }),
|
|
1035
|
+
import_zod19.z.object({ msgtype: import_zod19.z.literal("image"), image: WecomImageContentSchema })
|
|
1036
|
+
]);
|
|
1037
|
+
var WecomMixedContentSchema = import_zod19.z.object({
|
|
1038
|
+
msg_item: import_zod19.z.array(WecomMixedItemSchema).min(1)
|
|
1039
|
+
});
|
|
1040
|
+
var WecomQuoteSchema = import_zod19.z.object({
|
|
1041
|
+
msgtype: import_zod19.z.enum(["text", "image", "mixed", "voice", "file", "video"]),
|
|
1042
|
+
text: WecomTextContentSchema.optional(),
|
|
1043
|
+
image: WecomImageContentSchema.optional(),
|
|
1044
|
+
mixed: WecomMixedContentSchema.optional(),
|
|
1045
|
+
voice: WecomVoiceContentSchema.optional(),
|
|
1046
|
+
file: WecomFileContentSchema.optional(),
|
|
1047
|
+
video: WecomVideoContentSchema.optional()
|
|
1048
|
+
});
|
|
1049
|
+
var WecomStreamRefSchema = import_zod19.z.object({
|
|
1050
|
+
id: import_zod19.z.string().min(1)
|
|
1051
|
+
});
|
|
1052
|
+
var wecomBasePayload = {
|
|
1053
|
+
/** Unique message id for dedup (potential duplicate delivery). */
|
|
1054
|
+
msgid: import_zod19.z.string().min(1),
|
|
1055
|
+
/** WeCom aibot id, used to reverse-lookup which Pilot project owns this bot. */
|
|
1056
|
+
aibotid: import_zod19.z.string().min(1),
|
|
1057
|
+
/** Group chat id; only present when chattype === "group". */
|
|
1058
|
+
chatid: import_zod19.z.string().optional(),
|
|
1059
|
+
chattype: WecomChatTypeSchema,
|
|
1060
|
+
from: WecomSenderSchema,
|
|
1061
|
+
/** Temporary push URL for active replies (short-lived). Optional in stream frames. */
|
|
1062
|
+
response_url: import_zod19.z.string().optional(),
|
|
1063
|
+
/** Optional quote reference if the user quoted a prior message. */
|
|
1064
|
+
quote: WecomQuoteSchema.optional()
|
|
1065
|
+
};
|
|
1066
|
+
var WecomMessagePayloadSchema = import_zod19.z.discriminatedUnion("msgtype", [
|
|
1067
|
+
import_zod19.z.object(__spreadProps(__spreadValues({}, wecomBasePayload), {
|
|
1068
|
+
msgtype: import_zod19.z.literal("text"),
|
|
1069
|
+
text: WecomTextContentSchema
|
|
1070
|
+
})),
|
|
1071
|
+
import_zod19.z.object(__spreadProps(__spreadValues({}, wecomBasePayload), {
|
|
1072
|
+
msgtype: import_zod19.z.literal("image"),
|
|
1073
|
+
image: WecomImageContentSchema
|
|
1074
|
+
})),
|
|
1075
|
+
import_zod19.z.object(__spreadProps(__spreadValues({}, wecomBasePayload), {
|
|
1076
|
+
msgtype: import_zod19.z.literal("file"),
|
|
1077
|
+
file: WecomFileContentSchema
|
|
1078
|
+
})),
|
|
1079
|
+
import_zod19.z.object(__spreadProps(__spreadValues({}, wecomBasePayload), {
|
|
1080
|
+
msgtype: import_zod19.z.literal("mixed"),
|
|
1081
|
+
mixed: WecomMixedContentSchema
|
|
1082
|
+
})),
|
|
1083
|
+
import_zod19.z.object(__spreadProps(__spreadValues({}, wecomBasePayload), {
|
|
1084
|
+
msgtype: import_zod19.z.literal("voice"),
|
|
1085
|
+
voice: WecomVoiceContentSchema
|
|
1086
|
+
})),
|
|
1087
|
+
import_zod19.z.object(__spreadProps(__spreadValues({}, wecomBasePayload), {
|
|
1088
|
+
msgtype: import_zod19.z.literal("video"),
|
|
1089
|
+
video: WecomVideoContentSchema
|
|
1090
|
+
})),
|
|
1091
|
+
import_zod19.z.object(__spreadProps(__spreadValues({}, wecomBasePayload), {
|
|
1092
|
+
msgtype: import_zod19.z.literal("stream"),
|
|
1093
|
+
stream: WecomStreamRefSchema
|
|
1094
|
+
}))
|
|
1095
|
+
]);
|
|
1096
|
+
var WecomConfigActionSchema = import_zod20.z.enum(["enable", "update", "disable"]);
|
|
1097
|
+
var WecomConfigChangeEventSchema = import_zod20.z.object({
|
|
1098
|
+
projectId: import_zod20.z.string().min(1),
|
|
1099
|
+
action: WecomConfigActionSchema,
|
|
1100
|
+
/**
|
|
1101
|
+
* Current bot id post-change. `null` on disable when the operator
|
|
1102
|
+
* cleared it alongside the disable; absent when the patch didn't
|
|
1103
|
+
* touch bot_id.
|
|
1104
|
+
*/
|
|
1105
|
+
botId: import_zod20.z.string().nullable().optional()
|
|
1106
|
+
});
|
|
1107
|
+
var WecomCredentialLayerSchema = import_zod21.z.enum(["user", "owner", "project", "service"]);
|
|
1108
|
+
var WecomPushTargetSchema = import_zod21.z.object({
|
|
1109
|
+
/** Project that owns the bot — used by dispatcher subscribers to
|
|
1110
|
+
* filter messages addressed to bots this pod doesn't lead. */
|
|
1111
|
+
projectId: import_zod21.z.string().min(1),
|
|
1112
|
+
/** Agent id the run belongs to. Rendered into the card's `card_action`
|
|
1113
|
+
* Portal link so the user can jump to `/agents/<agentId>` to read
|
|
1114
|
+
* the result. */
|
|
1115
|
+
agentId: import_zod21.z.string().min(1),
|
|
1116
|
+
/** "single" or "group" — chooses whether the dispatcher prefixes the
|
|
1117
|
+
* outbound card with a `<@triggerUserid>` markdown so the original
|
|
1118
|
+
* sender gets a real @ notification (template_card cannot carry
|
|
1119
|
+
* inline mentions). */
|
|
1120
|
+
chatType: import_zod21.z.enum(["single", "group"]),
|
|
1121
|
+
/** Destination passed verbatim to `wsClient.sendMessage`. Userid for
|
|
1122
|
+
* single chats, chatid for group chats. */
|
|
1123
|
+
chatTarget: import_zod21.z.string().min(1),
|
|
1124
|
+
/** Userid that triggered the run. Used (a) to build the `<@userid>`
|
|
1125
|
+
* markdown in group-chat pushes and (b) by future audit / logging. */
|
|
1126
|
+
triggerUserid: import_zod21.z.string().min(1),
|
|
1127
|
+
/** Layer the layered Git-credential resolver landed on, when the
|
|
1128
|
+
* resolver was wired and produced a hit. Absent → `null` semantically:
|
|
1129
|
+
* resolver wired but no tier matched (user should configure a PAT)
|
|
1130
|
+
* iff `credentialResolverEnabled` is true; otherwise legacy
|
|
1131
|
+
* pre-resolver deployment (env PAT path). */
|
|
1132
|
+
credentialLayer: WecomCredentialLayerSchema.optional(),
|
|
1133
|
+
/** True iff the resolver was wired into the message handler. Lets
|
|
1134
|
+
* the dispatcher distinguish "no PAT in any tier → user-actionable
|
|
1135
|
+
* error card" from "legacy deployment, env PAT was the intended
|
|
1136
|
+
* path → generic error card". */
|
|
1137
|
+
credentialResolverEnabled: import_zod21.z.boolean()
|
|
1138
|
+
});
|
|
1139
|
+
var WecomPushEventSchema = import_zod21.z.object({
|
|
1140
|
+
runId: import_zod21.z.string().uuid(),
|
|
1141
|
+
success: import_zod21.z.boolean(),
|
|
1142
|
+
/** Optional human-readable error reason. Only meaningful when
|
|
1143
|
+
* `success === false`; ignored otherwise. */
|
|
1144
|
+
reason: import_zod21.z.string().optional()
|
|
1145
|
+
});
|
|
1146
|
+
var GitTokenSchema = import_zod22.z.string().transform((s) => s.trim()).pipe(
|
|
1147
|
+
import_zod22.z.string().min(1, "token must not be empty").max(1024).regex(
|
|
1148
|
+
/^[\x21-\x7e]+$/,
|
|
1149
|
+
"token must contain only printable ASCII characters (no whitespace or special symbols)"
|
|
1150
|
+
)
|
|
1151
|
+
);
|
|
1152
|
+
var UserGitCredentialMetadataSchema = import_zod22.z.object({
|
|
1153
|
+
provider: GitProviderSchema,
|
|
1154
|
+
instanceUrl: import_zod22.z.string().url(),
|
|
1155
|
+
tokenScope: import_zod22.z.string().nullable(),
|
|
1156
|
+
expiresAt: import_zod22.z.coerce.date().nullable(),
|
|
1157
|
+
lastValidatedAt: import_zod22.z.coerce.date(),
|
|
1158
|
+
createdAt: import_zod22.z.coerce.date(),
|
|
1159
|
+
updatedAt: import_zod22.z.coerce.date()
|
|
1160
|
+
});
|
|
1161
|
+
var UpsertUserGitCredentialSchema = import_zod22.z.object({
|
|
1162
|
+
provider: GitProviderSchema,
|
|
1163
|
+
instanceUrl: import_zod22.z.string().url(),
|
|
1164
|
+
token: GitTokenSchema,
|
|
1165
|
+
tokenScope: import_zod22.z.string().optional(),
|
|
1166
|
+
expiresAt: import_zod22.z.coerce.date().optional()
|
|
1167
|
+
});
|
|
1168
|
+
var UserGitCredentialKeySchema = import_zod22.z.object({
|
|
1169
|
+
provider: GitProviderSchema,
|
|
1170
|
+
instanceUrl: import_zod22.z.string().url()
|
|
1171
|
+
});
|
|
1172
|
+
var ProjectSharedCredentialMetadataSchema = import_zod22.z.object({
|
|
1173
|
+
sharedGitlabTokenConfigured: import_zod22.z.boolean().default(false),
|
|
1174
|
+
sharedGithubTokenConfigured: import_zod22.z.boolean().default(false)
|
|
1175
|
+
});
|
|
1176
|
+
var UpsertProjectSharedCredentialSchema = import_zod22.z.object({
|
|
1177
|
+
provider: GitProviderSchema,
|
|
1178
|
+
token: GitTokenSchema
|
|
1179
|
+
});
|
|
1180
|
+
var PlatformScopeSchema = import_zod23.z.enum([
|
|
1181
|
+
// Project-level (clamped by target_project_ids ∩ ACL)
|
|
1182
|
+
"project:read",
|
|
1183
|
+
"project:settings",
|
|
1184
|
+
"agents:write",
|
|
1185
|
+
"runs:create",
|
|
1186
|
+
"runs:stream",
|
|
1187
|
+
"runs:abort",
|
|
1188
|
+
"runs:merge",
|
|
1189
|
+
"files:upload",
|
|
1190
|
+
"pool:acquire",
|
|
1191
|
+
// User-level (not clamped by project allowlist)
|
|
1192
|
+
"user:credentials",
|
|
1193
|
+
"integrations:git:read",
|
|
1194
|
+
// Admin-only (separate approval)
|
|
1195
|
+
"sessions:terminate",
|
|
1196
|
+
"resources:cleanup",
|
|
1197
|
+
"pool:admin",
|
|
1198
|
+
"admin:bedrock-sync"
|
|
1199
|
+
]);
|
|
1200
|
+
var ScopeTemplateSchema = import_zod23.z.enum([
|
|
1201
|
+
"read_only",
|
|
1202
|
+
"ci_automation",
|
|
1203
|
+
"trigger_only",
|
|
1204
|
+
"full_automation",
|
|
1205
|
+
"custom"
|
|
1206
|
+
]);
|
|
1207
|
+
var PlatformTokenPayloadSchema = import_zod24.z.object({
|
|
1208
|
+
/** Discriminator. Rejects cross-system JWTs (reskill-api, summarization-api, ...). */
|
|
1209
|
+
type: import_zod24.z.literal("platform-api"),
|
|
1210
|
+
/** Owner LDAP. */
|
|
1211
|
+
sub: import_zod24.z.string().min(1),
|
|
1212
|
+
/** Corresponds to `platform_tokens.id`. */
|
|
1213
|
+
jti: import_zod24.z.string().uuid(),
|
|
1214
|
+
/** Issued-at (seconds). */
|
|
1215
|
+
iat: import_zod24.z.number().int().nonnegative(),
|
|
1216
|
+
/** Expiry (seconds). Omit for never-expiring tokens. */
|
|
1217
|
+
exp: import_zod24.z.number().int().positive().optional()
|
|
1218
|
+
});
|
|
1219
|
+
var SDKMessageTypeSchema = import_zod25.z.enum([
|
|
1220
|
+
// Assistant text output.
|
|
1221
|
+
"text-delta",
|
|
1222
|
+
// Assistant reasoning (when the model supports it).
|
|
1223
|
+
"reasoning",
|
|
1224
|
+
// A tool invocation by the agent (input available).
|
|
1225
|
+
"tool-use",
|
|
1226
|
+
// A tool result (output available).
|
|
1227
|
+
"tool-result",
|
|
1228
|
+
// A tool failure.
|
|
1229
|
+
"tool-error",
|
|
1230
|
+
// Finalize-stage progress (preparing / uploading / verifying / ...).
|
|
1231
|
+
"finalize-progress",
|
|
1232
|
+
// Terminal error from the run.
|
|
1233
|
+
"error",
|
|
1234
|
+
// Stream completed successfully (run finalized).
|
|
1235
|
+
"done",
|
|
1236
|
+
// Step boundaries (used by multi-step agents).
|
|
1237
|
+
"step-start",
|
|
1238
|
+
"step-end"
|
|
1239
|
+
]);
|
|
1240
|
+
var SDKMessageSchema = import_zod25.z.object({
|
|
1241
|
+
type: SDKMessageTypeSchema,
|
|
1242
|
+
/** Monotonically increasing stream cursor from the server. Usable for resume. */
|
|
1243
|
+
cursor: import_zod25.z.number().int().nonnegative().optional(),
|
|
1244
|
+
/** Stable per-message identifier when the server provides one. */
|
|
1245
|
+
id: import_zod25.z.string().optional(),
|
|
1246
|
+
/** Raw text for `text-delta` / `reasoning`. */
|
|
1247
|
+
text: import_zod25.z.string().optional(),
|
|
1248
|
+
/** Tool invocation details when `type === 'tool-use' | 'tool-result' | 'tool-error'`. */
|
|
1249
|
+
tool: import_zod25.z.object({
|
|
1250
|
+
name: import_zod25.z.string(),
|
|
1251
|
+
callId: import_zod25.z.string().optional(),
|
|
1252
|
+
input: import_zod25.z.unknown().optional(),
|
|
1253
|
+
output: import_zod25.z.string().optional(),
|
|
1254
|
+
error: import_zod25.z.string().optional()
|
|
1255
|
+
}).optional(),
|
|
1256
|
+
/** Finalize progress snapshot for `type === 'finalize-progress'`. */
|
|
1257
|
+
progress: import_zod25.z.object({
|
|
1258
|
+
stage: import_zod25.z.string(),
|
|
1259
|
+
detail: import_zod25.z.string().optional()
|
|
1260
|
+
}).optional(),
|
|
1261
|
+
/** Error detail for `type === 'error'`. */
|
|
1262
|
+
error: import_zod25.z.object({
|
|
1263
|
+
message: import_zod25.z.string(),
|
|
1264
|
+
code: import_zod25.z.string().optional()
|
|
1265
|
+
}).optional(),
|
|
1266
|
+
/**
|
|
1267
|
+
* Terminal run status for `type === 'done'`. Mirrors the DB
|
|
1268
|
+
* run-status enum so callers can branch without another fetch.
|
|
1269
|
+
*/
|
|
1270
|
+
runStatus: RunStatusSchema.optional()
|
|
1271
|
+
}).passthrough();
|
|
1272
|
+
var McpStdioConfigSchema = import_zod27.z.object({
|
|
1273
|
+
type: import_zod27.z.literal("stdio"),
|
|
1274
|
+
command: import_zod27.z.string().min(1),
|
|
1275
|
+
args: import_zod27.z.array(import_zod27.z.string()).optional(),
|
|
1276
|
+
env: import_zod27.z.record(import_zod27.z.string(), import_zod27.z.string()).optional()
|
|
1277
|
+
});
|
|
1278
|
+
var McpSseConfigSchema = import_zod27.z.object({
|
|
1279
|
+
type: import_zod27.z.literal("sse"),
|
|
1280
|
+
url: import_zod27.z.string().url(),
|
|
1281
|
+
headers: import_zod27.z.record(import_zod27.z.string(), import_zod27.z.string()).optional()
|
|
1282
|
+
});
|
|
1283
|
+
var McpHttpConfigSchema = import_zod27.z.object({
|
|
1284
|
+
type: import_zod27.z.literal("http"),
|
|
1285
|
+
url: import_zod27.z.string().url(),
|
|
1286
|
+
headers: import_zod27.z.record(import_zod27.z.string(), import_zod27.z.string()).optional()
|
|
1287
|
+
});
|
|
1288
|
+
var MCPServerConfigSchema = import_zod27.z.discriminatedUnion("type", [
|
|
1289
|
+
McpStdioConfigSchema,
|
|
1290
|
+
McpSseConfigSchema,
|
|
1291
|
+
McpHttpConfigSchema
|
|
1292
|
+
]);
|
|
1293
|
+
var McpTemplateSnapshotSchema = import_zod27.z.object({
|
|
1294
|
+
transportType: import_zod27.z.enum(["stdio", "sse", "http"]),
|
|
1295
|
+
serverConfig: MCPServerConfigSchema,
|
|
1296
|
+
requiredVars: import_zod27.z.array(import_zod27.z.string()).optional(),
|
|
1297
|
+
version: import_zod27.z.string().optional()
|
|
1298
|
+
});
|
|
1299
|
+
var EnabledMcpServerSchema = import_zod27.z.object({
|
|
1300
|
+
rushMcpId: import_zod27.z.string().min(1),
|
|
1301
|
+
displayName: import_zod27.z.string().min(1),
|
|
1302
|
+
templateSnapshot: McpTemplateSnapshotSchema,
|
|
1303
|
+
extraConfigValues: import_zod27.z.record(import_zod27.z.string(), import_zod27.z.string()).optional(),
|
|
1304
|
+
toolFilter: import_zod27.z.array(import_zod27.z.string()).optional(),
|
|
1305
|
+
disabled: import_zod27.z.boolean().optional()
|
|
1306
|
+
});
|
|
1307
|
+
var EnabledMcpServerListSchema = import_zod27.z.array(EnabledMcpServerSchema);
|
|
1308
|
+
var EnabledMcpRefSchema = import_zod27.z.object({
|
|
1309
|
+
rushMcpId: import_zod27.z.string().min(1),
|
|
1310
|
+
disabled: import_zod27.z.boolean().optional(),
|
|
1311
|
+
extraConfigValuesOverride: import_zod27.z.record(import_zod27.z.string(), import_zod27.z.string()).optional()
|
|
1312
|
+
});
|
|
1313
|
+
var EnabledMcpRefListSchema = import_zod27.z.array(EnabledMcpRefSchema);
|
|
1314
|
+
var EnabledMcpEntrySchema = import_zod27.z.union([EnabledMcpServerSchema, EnabledMcpRefSchema]);
|
|
1315
|
+
var EnabledMcpEntryListSchema = import_zod27.z.array(EnabledMcpEntrySchema);
|
|
1316
|
+
var SkillSourceTypeSchema = import_zod28.z.enum([
|
|
1317
|
+
"github",
|
|
1318
|
+
"gitlab",
|
|
1319
|
+
"registry",
|
|
1320
|
+
"local",
|
|
1321
|
+
"oss_url",
|
|
1322
|
+
"custom_url"
|
|
1323
|
+
]);
|
|
1324
|
+
var ResolvedSkillArtifactSchema = import_zod28.z.object({
|
|
1325
|
+
sourceType: SkillSourceTypeSchema,
|
|
1326
|
+
/**
|
|
1327
|
+
* Direct repo / file URL for `github` / `gitlab` source types. For
|
|
1328
|
+
* `registry` / `oss_url` / `local` / `custom_url`, rush stores the
|
|
1329
|
+
* actual download artifact in `skill_versions` (different per
|
|
1330
|
+
* version) so this field is empty / unused at install time — the
|
|
1331
|
+
* installer goes through `RushRegistryClient.resolveDownloadUrl`
|
|
1332
|
+
* instead.
|
|
1333
|
+
*/
|
|
1334
|
+
sourceUrl: import_zod28.z.string().optional().default(""),
|
|
1335
|
+
skillPath: import_zod28.z.string().optional(),
|
|
1336
|
+
integrity: import_zod28.z.string().optional(),
|
|
1337
|
+
version: import_zod28.z.string().optional()
|
|
1338
|
+
});
|
|
1339
|
+
var EnabledSkillSchema = import_zod28.z.object({
|
|
1340
|
+
rushSkillName: import_zod28.z.string().min(1),
|
|
1341
|
+
displayName: import_zod28.z.string().min(1),
|
|
1342
|
+
resolvedArtifact: ResolvedSkillArtifactSchema
|
|
1343
|
+
});
|
|
1344
|
+
var EnabledSkillListSchema = import_zod28.z.array(EnabledSkillSchema);
|
|
1345
|
+
var EnabledSkillRefSchema = import_zod28.z.object({
|
|
1346
|
+
rushSkillName: import_zod28.z.string().min(1)
|
|
1347
|
+
});
|
|
1348
|
+
var EnabledSkillRefListSchema = import_zod28.z.array(EnabledSkillRefSchema);
|
|
1349
|
+
var EnabledSkillEntrySchema = import_zod28.z.union([EnabledSkillSchema, EnabledSkillRefSchema]);
|
|
1350
|
+
var EnabledSkillEntryListSchema = import_zod28.z.array(EnabledSkillEntrySchema);
|
|
1351
|
+
var SdkAgentSummarySchema = import_zod26.z.object({
|
|
1352
|
+
agentId: import_zod26.z.string().uuid(),
|
|
1353
|
+
title: import_zod26.z.string(),
|
|
1354
|
+
project: import_zod26.z.object({
|
|
1355
|
+
id: import_zod26.z.string().uuid(),
|
|
1356
|
+
name: import_zod26.z.string(),
|
|
1357
|
+
gitProvider: GitProviderSchema.nullable()
|
|
1358
|
+
}),
|
|
1359
|
+
agentMode: import_zod26.z.enum(["task", "chat"]),
|
|
1360
|
+
productStatus: import_zod26.z.enum(["idle", "running", "needs_attention", "completed"]),
|
|
1361
|
+
model: import_zod26.z.string().nullable(),
|
|
1362
|
+
isAutomation: import_zod26.z.boolean(),
|
|
1363
|
+
latestRun: import_zod26.z.object({
|
|
1364
|
+
runId: import_zod26.z.string().uuid(),
|
|
1365
|
+
promptSummary: import_zod26.z.string(),
|
|
1366
|
+
status: import_zod26.z.string(),
|
|
1367
|
+
updatedAt: import_zod26.z.string().datetime(),
|
|
1368
|
+
startedAt: import_zod26.z.string().datetime().nullable(),
|
|
1369
|
+
completedAt: import_zod26.z.string().datetime().nullable(),
|
|
1370
|
+
hasArtifacts: import_zod26.z.boolean(),
|
|
1371
|
+
hasReview: import_zod26.z.boolean(),
|
|
1372
|
+
hasDiff: import_zod26.z.boolean(),
|
|
1373
|
+
hasCommits: import_zod26.z.boolean(),
|
|
1374
|
+
hasPullRequest: import_zod26.z.boolean()
|
|
1375
|
+
}).nullable(),
|
|
1376
|
+
lastActiveAt: import_zod26.z.string().datetime()
|
|
1377
|
+
});
|
|
1378
|
+
var ListAgentsQuerySchema = import_zod26.z.object({
|
|
1379
|
+
projectId: import_zod26.z.string().uuid().optional(),
|
|
1380
|
+
limit: import_zod26.z.number().int().min(1).max(100).optional()
|
|
1381
|
+
});
|
|
1382
|
+
var ListAgentsResponseSchema = import_zod26.z.object({
|
|
1383
|
+
items: import_zod26.z.array(SdkAgentSummarySchema),
|
|
1384
|
+
nextCursor: import_zod26.z.string().nullable()
|
|
1385
|
+
});
|
|
1386
|
+
var PilotApiVersionSchema = import_zod26.z.enum(["v1", "v2"]);
|
|
1387
|
+
var SdkCreateAgentRequestSchema = import_zod26.z.object({
|
|
1388
|
+
projectId: import_zod26.z.string().uuid().optional(),
|
|
1389
|
+
gitProvider: GitProviderSchema.optional(),
|
|
1390
|
+
gitlabProjectPath: import_zod26.z.string().trim().min(1).optional(),
|
|
1391
|
+
githubRepoFullName: import_zod26.z.string().trim().min(1).optional(),
|
|
1392
|
+
repoUrl: import_zod26.z.string().min(1).optional(),
|
|
1393
|
+
/**
|
|
1394
|
+
* Baseline git ref frozen on the agent for the lifetime of follow-up
|
|
1395
|
+
* runs. Optional — server falls back to project.defaultBranch.
|
|
1396
|
+
*/
|
|
1397
|
+
baseRef: import_zod26.z.string().optional(),
|
|
1398
|
+
prompt: import_zod26.z.string().min(1),
|
|
1399
|
+
agentMode: import_zod26.z.enum(["task", "chat"]).optional(),
|
|
1400
|
+
model: import_zod26.z.string().optional(),
|
|
1401
|
+
provider: ProviderTypeSchema.optional(),
|
|
1402
|
+
githubInstallationId: import_zod26.z.string().optional(),
|
|
1403
|
+
attachments: import_zod26.z.array(AttachmentMetaSchema).max(5).optional(),
|
|
1404
|
+
/**
|
|
1405
|
+
* Optional MCP / Skill enable lists frozen on the new agent at
|
|
1406
|
+
* creation time.
|
|
1407
|
+
*
|
|
1408
|
+
* Both fields accept the same union the home-composer
|
|
1409
|
+
* pre-edit and `PUT /api/agents/:id/mcp-skills` accept (see
|
|
1410
|
+
* `EnabledMcpEntrySchema` / `EnabledSkillEntrySchema`):
|
|
1411
|
+
* full snapshot **OR** ref into the global credential store.
|
|
1412
|
+
*
|
|
1413
|
+
* `POST /api/agents` semantics (Pilot Web):
|
|
1414
|
+
* - Omitted lists + no CLI seed header → new agent starts with empty
|
|
1415
|
+
* `enabled_*` (interactive / SDK default; spec §4.3).
|
|
1416
|
+
* - Omitted lists + Pilot CLI request (`x-pilot-cli-seed-from-project: 1`) →
|
|
1417
|
+
* server seeds from `projects.enabled_mcp_servers` / `enabled_skills`.
|
|
1418
|
+
* - Either list provided → explicit caller choice; omitted dimension
|
|
1419
|
+
* still follows the seed rule above; `agents.mcp_skills_customized = true`
|
|
1420
|
+
* when any list is caller-supplied.
|
|
1421
|
+
*
|
|
1422
|
+
* See `specs/features/mcp-and-skills.md` §4.4.
|
|
1423
|
+
*/
|
|
1424
|
+
enabledMcpServers: EnabledMcpEntryListSchema.optional(),
|
|
1425
|
+
enabledSkills: EnabledSkillEntryListSchema.optional(),
|
|
1426
|
+
/**
|
|
1427
|
+
* Caller-explicit per-run lifecycle selector. Same semantics as
|
|
1428
|
+
* `SdkCreateRunRequestSchema.pilotApiVersion` — see `PilotApiVersionSchema`
|
|
1429
|
+
* JSDoc for the three-layer LOCK and routing precedence.
|
|
1430
|
+
*
|
|
1431
|
+
* Three-layer LOCK (agents):
|
|
1432
|
+
* L1 SDK `SdkCreateAgentRequestSchema.pilotApiVersion` — this file
|
|
1433
|
+
* L2 API `apps/web/app/api/agents/route.ts` — body field
|
|
1434
|
+
* L3 RT `packages/control-plane/src/run-service.ts` — `runs.pilot_api_version`
|
|
1435
|
+
*
|
|
1436
|
+
* Optional; when omitted, server falls through to `decideRoute()` then
|
|
1437
|
+
* default `"v1"`.
|
|
1438
|
+
*/
|
|
1439
|
+
pilotApiVersion: PilotApiVersionSchema.optional()
|
|
1440
|
+
}).superRefine((data, ctx) => {
|
|
1441
|
+
const hasProjectId = typeof data.projectId === "string" && data.projectId.length > 0;
|
|
1442
|
+
const hasGitlabPath = !!data.gitlabProjectPath;
|
|
1443
|
+
const hasGithubRepo = !!data.githubRepoFullName;
|
|
1444
|
+
const hasGitProvider = !!data.gitProvider;
|
|
1445
|
+
if (hasProjectId) {
|
|
1446
|
+
if (hasGitProvider || hasGitlabPath || hasGithubRepo || data.repoUrl) {
|
|
1447
|
+
ctx.addIssue({
|
|
1448
|
+
code: import_zod26.z.ZodIssueCode.custom,
|
|
1449
|
+
message: "projectId is exclusive with gitProvider / gitlabProjectPath / githubRepoFullName / repoUrl.",
|
|
1450
|
+
path: ["projectId"]
|
|
1451
|
+
});
|
|
1452
|
+
}
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
if (!hasGitProvider) {
|
|
1456
|
+
ctx.addIssue({
|
|
1457
|
+
code: import_zod26.z.ZodIssueCode.custom,
|
|
1458
|
+
message: "Provide either projectId, or (gitProvider + gitlabProjectPath) / (gitProvider + githubRepoFullName).",
|
|
1459
|
+
path: ["gitProvider"]
|
|
1460
|
+
});
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
if (data.gitProvider === "gitlab") {
|
|
1464
|
+
if (!hasGitlabPath) {
|
|
1465
|
+
ctx.addIssue({
|
|
1466
|
+
code: import_zod26.z.ZodIssueCode.custom,
|
|
1467
|
+
message: "gitProvider=gitlab requires gitlabProjectPath.",
|
|
1468
|
+
path: ["gitlabProjectPath"]
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1471
|
+
if (hasGithubRepo) {
|
|
1472
|
+
ctx.addIssue({
|
|
1473
|
+
code: import_zod26.z.ZodIssueCode.custom,
|
|
1474
|
+
message: "gitProvider=gitlab must not carry githubRepoFullName.",
|
|
1475
|
+
path: ["githubRepoFullName"]
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
} else if (data.gitProvider === "github") {
|
|
1479
|
+
if (!hasGithubRepo) {
|
|
1480
|
+
ctx.addIssue({
|
|
1481
|
+
code: import_zod26.z.ZodIssueCode.custom,
|
|
1482
|
+
message: "gitProvider=github requires githubRepoFullName.",
|
|
1483
|
+
path: ["githubRepoFullName"]
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
if (hasGitlabPath) {
|
|
1487
|
+
ctx.addIssue({
|
|
1488
|
+
code: import_zod26.z.ZodIssueCode.custom,
|
|
1489
|
+
message: "gitProvider=github must not carry gitlabProjectPath.",
|
|
1490
|
+
path: ["gitlabProjectPath"]
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
});
|
|
1495
|
+
var SdkCreateAgentResponseSchema = import_zod26.z.object({
|
|
1496
|
+
agentId: import_zod26.z.string().uuid(),
|
|
1497
|
+
runId: import_zod26.z.string().uuid(),
|
|
1498
|
+
isNewAgent: import_zod26.z.boolean()
|
|
1499
|
+
});
|
|
1500
|
+
var SdkMergeAgentRequestSchema = import_zod26.z.object({
|
|
1501
|
+
/** Optional custom commit message. Server falls back to the model output. */
|
|
1502
|
+
commitMessage: import_zod26.z.string().min(1).max(200).optional(),
|
|
1503
|
+
/** Optional PR title override. */
|
|
1504
|
+
prTitle: import_zod26.z.string().min(1).max(256).optional(),
|
|
1505
|
+
/** Optional PR description override. */
|
|
1506
|
+
prDescription: import_zod26.z.string().optional()
|
|
1507
|
+
});
|
|
1508
|
+
var SdkMergeAgentResponseSchema = import_zod26.z.object({
|
|
1509
|
+
mergeRequestId: import_zod26.z.string().uuid(),
|
|
1510
|
+
externalUrl: import_zod26.z.string(),
|
|
1511
|
+
externalId: import_zod26.z.string()
|
|
1512
|
+
});
|
|
1513
|
+
var SdkPatchAgentRequestSchema = import_zod26.z.object({
|
|
1514
|
+
customTitle: import_zod26.z.string().max(200).nullable().optional(),
|
|
1515
|
+
status: import_zod26.z.enum(["active", "closed"]).optional()
|
|
1516
|
+
});
|
|
1517
|
+
var SdkCreateRunRequestSchema = import_zod26.z.object({
|
|
1518
|
+
projectId: import_zod26.z.string().uuid(),
|
|
1519
|
+
prompt: import_zod26.z.string().min(1),
|
|
1520
|
+
agentId: import_zod26.z.string().uuid().optional(),
|
|
1521
|
+
parentRunId: import_zod26.z.string().uuid().optional(),
|
|
1522
|
+
repo: import_zod26.z.string().optional(),
|
|
1523
|
+
ref: import_zod26.z.string().optional(),
|
|
1524
|
+
model: import_zod26.z.string().optional(),
|
|
1525
|
+
provider: ProviderTypeSchema.optional(),
|
|
1526
|
+
attachments: import_zod26.z.array(AttachmentMetaSchema).max(5).optional(),
|
|
1527
|
+
/**
|
|
1528
|
+
* Per-run override of the MCP / Skill enable lists.
|
|
1529
|
+
*
|
|
1530
|
+
* When omitted, the run inherits whatever lives on the agent (Portal /
|
|
1531
|
+
* SDK create without MCP/Skill body and without CLI seed header → empty
|
|
1532
|
+
* lists on the agent; see `SdkCreateAgentRequestSchema`).
|
|
1533
|
+
*
|
|
1534
|
+
* Same union shape as the create-agent fields: snapshot OR ref.
|
|
1535
|
+
* Useful for one-off runs that need a different toolset than the
|
|
1536
|
+
* conversational defaults baked onto the agent.
|
|
1537
|
+
*
|
|
1538
|
+
* See `specs/features/mcp-and-skills.md` §6.3 (per-run override).
|
|
1539
|
+
*/
|
|
1540
|
+
enabledMcpServers: EnabledMcpEntryListSchema.optional(),
|
|
1541
|
+
enabledSkills: EnabledSkillEntryListSchema.optional(),
|
|
1542
|
+
/**
|
|
1543
|
+
* Caller-explicit Pilot runtime API version override for this run.
|
|
1544
|
+
*
|
|
1545
|
+
* Defaults to **server-decided**: when omitted, the server consults
|
|
1546
|
+
* the traffic-split router (PR-TS-1 D5/D6) for the v1/v2 routing
|
|
1547
|
+
* decision and persists it to `runs.pilot_api_version`. When passed
|
|
1548
|
+
* explicitly, the caller value wins regardless of the router state
|
|
1549
|
+
* (see `run-service.ts` line 99-114 and PR-TS-1 D5 explicit-wins
|
|
1550
|
+
* test `run-service-pilot-api-version.test.ts` line 134-149).
|
|
1551
|
+
*
|
|
1552
|
+
* Use this opt-in carefully — it bypasses the canary / kill-switch
|
|
1553
|
+
* gates. Most callers should leave this unset and trust the router.
|
|
1554
|
+
*/
|
|
1555
|
+
pilotApiVersion: PilotApiVersionSchema.optional()
|
|
1556
|
+
});
|
|
1557
|
+
var SdkCreateRunResponseSchema = import_zod26.z.object({
|
|
1558
|
+
run: import_zod26.z.lazy(() => SdkRunSummarySchema)
|
|
1559
|
+
});
|
|
1560
|
+
var SdkAbortRunRequestSchema = import_zod26.z.object({
|
|
1561
|
+
reason: import_zod26.z.string().max(500).optional()
|
|
1562
|
+
});
|
|
1563
|
+
var SdkAbortRunResponseSchema = import_zod26.z.object({
|
|
1564
|
+
aborted: import_zod26.z.boolean(),
|
|
1565
|
+
status: RunStatusSchema
|
|
1566
|
+
});
|
|
1567
|
+
var SdkRunSummarySchema = import_zod26.z.object({
|
|
1568
|
+
runId: import_zod26.z.string().uuid(),
|
|
1569
|
+
agentId: import_zod26.z.string().uuid(),
|
|
1570
|
+
projectId: import_zod26.z.string().uuid(),
|
|
1571
|
+
status: RunStatusSchema,
|
|
1572
|
+
prompt: import_zod26.z.string(),
|
|
1573
|
+
model: import_zod26.z.string().nullable(),
|
|
1574
|
+
provider: ProviderTypeSchema,
|
|
1575
|
+
triggerSource: TriggerSourceSchema,
|
|
1576
|
+
pullRequestUrl: import_zod26.z.string().nullable(),
|
|
1577
|
+
errorMessage: import_zod26.z.string().nullable(),
|
|
1578
|
+
createdAt: import_zod26.z.string().datetime(),
|
|
1579
|
+
startedAt: import_zod26.z.string().datetime().nullable(),
|
|
1580
|
+
completedAt: import_zod26.z.string().datetime().nullable()
|
|
1581
|
+
});
|
|
1582
|
+
var SdkStreamRunQuerySchema = import_zod26.z.object({
|
|
1583
|
+
lastCursor: import_zod26.z.number().int().nonnegative().optional()
|
|
1584
|
+
});
|
|
1585
|
+
var SdkProjectSummarySchema = import_zod26.z.object({
|
|
1586
|
+
id: import_zod26.z.string().uuid(),
|
|
1587
|
+
name: import_zod26.z.string(),
|
|
1588
|
+
// `kind` is now `NOT NULL DEFAULT 'coding'` in the DB (migration
|
|
1589
|
+
// 0034), so the server always emits a concrete value — `.default()`
|
|
1590
|
+
// would silently mask a missing-field bug instead of surfacing it.
|
|
1591
|
+
// Keep the field strict so SDK consumers can rely on the union
|
|
1592
|
+
// without runtime fallbacks.
|
|
1593
|
+
kind: ProjectKindSchema,
|
|
1594
|
+
gitProvider: GitProviderSchema.nullable(),
|
|
1595
|
+
repoUrl: import_zod26.z.string().nullable(),
|
|
1596
|
+
gitlabProjectPath: import_zod26.z.string().nullable(),
|
|
1597
|
+
githubRepoFullName: import_zod26.z.string().nullable(),
|
|
1598
|
+
webhookEnabled: import_zod26.z.boolean(),
|
|
1599
|
+
webhookTriggerLabel: import_zod26.z.string(),
|
|
1600
|
+
jiraEnabled: import_zod26.z.boolean(),
|
|
1601
|
+
wecomEnabled: import_zod26.z.boolean(),
|
|
1602
|
+
ownerLdap: import_zod26.z.string().nullable(),
|
|
1603
|
+
role: import_zod26.z.enum(["owner", "member", "admin"])
|
|
1604
|
+
});
|
|
1605
|
+
var ListProjectsRequestSchema = import_zod26.z.object({
|
|
1606
|
+
kind: ProjectKindSchema.optional()
|
|
1607
|
+
});
|
|
1608
|
+
var CreateGeneralProjectRequestSchema = import_zod26.z.object({
|
|
1609
|
+
name: import_zod26.z.string().trim().min(1).max(255),
|
|
1610
|
+
kind: import_zod26.z.literal("general"),
|
|
1611
|
+
description: import_zod26.z.string().trim().max(2e3).optional()
|
|
1612
|
+
});
|
|
1613
|
+
var CreateGeneralProjectResponseSchema = import_zod26.z.object({
|
|
1614
|
+
projectId: import_zod26.z.string().uuid()
|
|
1615
|
+
});
|
|
1616
|
+
var ListProjectsResponseSchema = import_zod26.z.object({
|
|
1617
|
+
items: import_zod26.z.array(SdkProjectSummarySchema)
|
|
1618
|
+
});
|
|
1619
|
+
var SdkProjectSettingsSchema = import_zod26.z.object({
|
|
1620
|
+
id: import_zod26.z.string().uuid(),
|
|
1621
|
+
webhookEnabled: import_zod26.z.boolean(),
|
|
1622
|
+
webhookTriggerLabel: import_zod26.z.string(),
|
|
1623
|
+
webhookPromptTemplate: import_zod26.z.string().nullable(),
|
|
1624
|
+
wecomEnabled: import_zod26.z.boolean(),
|
|
1625
|
+
wecomBotId: import_zod26.z.string().nullable(),
|
|
1626
|
+
wecomPromptTemplate: import_zod26.z.string().nullable(),
|
|
1627
|
+
jiraEnabled: import_zod26.z.boolean().optional(),
|
|
1628
|
+
jiraBaseUrl: import_zod26.z.string().nullable().optional(),
|
|
1629
|
+
jiraProjectKey: import_zod26.z.string().nullable().optional(),
|
|
1630
|
+
jiraTriggerLabel: import_zod26.z.string().optional(),
|
|
1631
|
+
jiraPromptTemplate: import_zod26.z.string().nullable().optional()
|
|
1632
|
+
});
|
|
1633
|
+
var UpdateProjectSettingsRequestSchema = import_zod26.z.object({
|
|
1634
|
+
webhookEnabled: import_zod26.z.boolean().optional(),
|
|
1635
|
+
webhookTriggerLabel: import_zod26.z.string().min(1).max(100).optional(),
|
|
1636
|
+
webhookPromptTemplate: import_zod26.z.string().nullable().optional(),
|
|
1637
|
+
wecomEnabled: import_zod26.z.boolean().optional(),
|
|
1638
|
+
wecomBotId: import_zod26.z.string().min(1).max(100).nullable().optional(),
|
|
1639
|
+
wecomPromptTemplate: import_zod26.z.string().nullable().optional(),
|
|
1640
|
+
jiraEnabled: import_zod26.z.boolean().optional(),
|
|
1641
|
+
jiraBaseUrl: import_zod26.z.string().url().nullable().optional(),
|
|
1642
|
+
jiraProjectKey: import_zod26.z.string().min(1).max(64).nullable().optional(),
|
|
1643
|
+
jiraTriggerLabel: import_zod26.z.string().min(1).max(100).optional(),
|
|
1644
|
+
jiraPromptTemplate: import_zod26.z.string().nullable().optional()
|
|
1645
|
+
});
|
|
1646
|
+
var SdkAutomationRunSchema = import_zod26.z.object({
|
|
1647
|
+
runId: import_zod26.z.string().uuid(),
|
|
1648
|
+
agentId: import_zod26.z.string().uuid(),
|
|
1649
|
+
projectId: import_zod26.z.string().uuid(),
|
|
1650
|
+
projectName: import_zod26.z.string(),
|
|
1651
|
+
gitProvider: GitProviderSchema.nullable(),
|
|
1652
|
+
repoFullName: import_zod26.z.string().nullable(),
|
|
1653
|
+
status: import_zod26.z.string(),
|
|
1654
|
+
productStatus: import_zod26.z.enum(["idle", "running", "needs_attention", "completed"]),
|
|
1655
|
+
promptSummary: import_zod26.z.string(),
|
|
1656
|
+
triggerRef: import_zod26.z.string().nullable(),
|
|
1657
|
+
triggerType: import_zod26.z.enum(["label", "mention", "wecom", "jira"]),
|
|
1658
|
+
issueUrl: import_zod26.z.string().nullable(),
|
|
1659
|
+
pullRequestUrl: import_zod26.z.string().nullable(),
|
|
1660
|
+
errorMessage: import_zod26.z.string().nullable(),
|
|
1661
|
+
createdAt: import_zod26.z.string().datetime(),
|
|
1662
|
+
updatedAt: import_zod26.z.string().datetime(),
|
|
1663
|
+
startedAt: import_zod26.z.string().datetime().nullable(),
|
|
1664
|
+
completedAt: import_zod26.z.string().datetime().nullable()
|
|
1665
|
+
});
|
|
1666
|
+
var ListAutomationRunsQuerySchema = import_zod26.z.object({
|
|
1667
|
+
projectId: import_zod26.z.string().uuid().optional(),
|
|
1668
|
+
limit: import_zod26.z.number().int().min(1).max(100).optional(),
|
|
1669
|
+
cursor: import_zod26.z.string().optional()
|
|
1670
|
+
});
|
|
1671
|
+
var ListAutomationRunsResponseSchema = import_zod26.z.object({
|
|
1672
|
+
items: import_zod26.z.array(SdkAutomationRunSchema),
|
|
1673
|
+
nextCursor: import_zod26.z.string().nullable()
|
|
1674
|
+
});
|
|
1675
|
+
var CreatePlatformTokenRequestSchema = import_zod26.z.object({
|
|
1676
|
+
name: import_zod26.z.string().min(1).max(200),
|
|
1677
|
+
description: import_zod26.z.string().max(2e3).optional(),
|
|
1678
|
+
scopes: import_zod26.z.array(PlatformScopeSchema).min(1),
|
|
1679
|
+
scopeTemplate: ScopeTemplateSchema,
|
|
1680
|
+
/** NULL means "all projects I currently have access to". */
|
|
1681
|
+
targetProjectIds: import_zod26.z.array(import_zod26.z.string().uuid()).nullable(),
|
|
1682
|
+
/** ISO-8601 string. Omit for never-expire. */
|
|
1683
|
+
expiresAt: import_zod26.z.string().datetime().optional()
|
|
1684
|
+
});
|
|
1685
|
+
var CreatePlatformTokenResponseSchema = import_zod26.z.object({
|
|
1686
|
+
id: import_zod26.z.string().uuid(),
|
|
1687
|
+
name: import_zod26.z.string(),
|
|
1688
|
+
/** The **only** time the full token is returned. */
|
|
1689
|
+
token: import_zod26.z.string(),
|
|
1690
|
+
tokenPrefix: import_zod26.z.string(),
|
|
1691
|
+
scopes: import_zod26.z.array(PlatformScopeSchema),
|
|
1692
|
+
scopeTemplate: ScopeTemplateSchema,
|
|
1693
|
+
targetProjectIds: import_zod26.z.array(import_zod26.z.string().uuid()).nullable(),
|
|
1694
|
+
createdAt: import_zod26.z.string().datetime(),
|
|
1695
|
+
expiresAt: import_zod26.z.string().datetime().nullable()
|
|
1696
|
+
});
|
|
1697
|
+
var PlatformTokenInfoSchema = import_zod26.z.object({
|
|
1698
|
+
id: import_zod26.z.string().uuid(),
|
|
1699
|
+
name: import_zod26.z.string(),
|
|
1700
|
+
description: import_zod26.z.string().nullable(),
|
|
1701
|
+
tokenPrefix: import_zod26.z.string(),
|
|
1702
|
+
scopes: import_zod26.z.array(PlatformScopeSchema),
|
|
1703
|
+
scopeTemplate: ScopeTemplateSchema.nullable(),
|
|
1704
|
+
targetProjectIds: import_zod26.z.array(import_zod26.z.string().uuid()).nullable(),
|
|
1705
|
+
createdAt: import_zod26.z.string().datetime(),
|
|
1706
|
+
expiresAt: import_zod26.z.string().datetime().nullable(),
|
|
1707
|
+
lastUsedAt: import_zod26.z.string().datetime().nullable(),
|
|
1708
|
+
revokedAt: import_zod26.z.string().datetime().nullable(),
|
|
1709
|
+
revokedReason: import_zod26.z.string().nullable()
|
|
1710
|
+
});
|
|
1711
|
+
var ListPlatformTokensResponseSchema = import_zod26.z.object({
|
|
1712
|
+
items: import_zod26.z.array(PlatformTokenInfoSchema)
|
|
1713
|
+
});
|
|
1714
|
+
var PatchPlatformTokenRequestSchema = import_zod26.z.object({
|
|
1715
|
+
name: import_zod26.z.string().min(1).max(200).optional(),
|
|
1716
|
+
description: import_zod26.z.string().max(2e3).nullable().optional(),
|
|
1717
|
+
/**
|
|
1718
|
+
* Allowed to *shrink* the scope set (for tightening); forbidden to
|
|
1719
|
+
* widen. Server enforces `new_scopes ⊆ old_scopes`.
|
|
1720
|
+
*/
|
|
1721
|
+
scopes: import_zod26.z.array(PlatformScopeSchema).min(1).optional()
|
|
1722
|
+
});
|
|
1723
|
+
var X_PILOT_API_VERSION_HEADER = "x-pilot-api-version";
|
|
1724
|
+
var DeliveryResultPhaseSchema = import_zod29.z.enum(["in_progress", "completed", "failed"]);
|
|
1725
|
+
var DeliveryResultArtifactItemSchema = import_zod29.z.object({
|
|
1726
|
+
/** Artifact category. Workers MAY add new kinds; storage is opaque. */
|
|
1727
|
+
kind: import_zod29.z.enum(["diff", "log", "general"]),
|
|
1728
|
+
/**
|
|
1729
|
+
* Logical path inside the sandbox workspace (used as the idempotency
|
|
1730
|
+
* key together with `runId`). Two writes with the same `(runId, path)`
|
|
1731
|
+
* pair collapse to a single row via `ON CONFLICT DO NOTHING`.
|
|
1732
|
+
*/
|
|
1733
|
+
path: import_zod29.z.string().min(1).max(1024),
|
|
1734
|
+
/** Object key inside the OSS bucket where the artifact was uploaded. */
|
|
1735
|
+
storagePath: import_zod29.z.string().min(1).max(1024),
|
|
1736
|
+
/** Reported byte size of the upload. */
|
|
1737
|
+
size: import_zod29.z.number().int().nonnegative(),
|
|
1738
|
+
/**
|
|
1739
|
+
* SHA-256 digest in the form `sha256:<hex>`. Workers compute this
|
|
1740
|
+
* before upload so a later integrity check can cross-verify the
|
|
1741
|
+
* stored object. Length cap 128 mirrors the `artifacts.checksum`
|
|
1742
|
+
* column width.
|
|
1743
|
+
*/
|
|
1744
|
+
checksum: import_zod29.z.string().min(1).max(128),
|
|
1745
|
+
/** MIME content type recorded for downloads / preview. */
|
|
1746
|
+
contentType: import_zod29.z.string().min(1).max(255)
|
|
1747
|
+
}).strict();
|
|
1748
|
+
var DeliveryResultUpdateSchema = import_zod29.z.object({
|
|
1749
|
+
/**
|
|
1750
|
+
* The PR / MR URL the agent created. First-write-wins per spec
|
|
1751
|
+
* (`UPDATE ... WHERE pull_request_url IS NULL`); subsequent writes
|
|
1752
|
+
* are recorded in the response as "skipped" rather than as an error
|
|
1753
|
+
* so Worker retries stay idempotent.
|
|
1754
|
+
*/
|
|
1755
|
+
pullRequestUrl: import_zod29.z.string().url().max(1024).optional(),
|
|
1756
|
+
/**
|
|
1757
|
+
* Append-set of artifacts uploaded for this run. Each item is
|
|
1758
|
+
* upserted independently via the `unique(run_id, path)` constraint;
|
|
1759
|
+
* the response indicates how many of the submitted items resulted
|
|
1760
|
+
* in a new row.
|
|
1761
|
+
*/
|
|
1762
|
+
artifacts: import_zod29.z.array(DeliveryResultArtifactItemSchema).max(64).optional(),
|
|
1763
|
+
/**
|
|
1764
|
+
* Drive the `runs.delivery_phase` column via the L1.2
|
|
1765
|
+
* `RunService.recordDeliveryPhase` helper. `failed` requires
|
|
1766
|
+
* `failedReason`; the service throws `INVALID_INPUT` otherwise.
|
|
1767
|
+
*/
|
|
1768
|
+
phase: DeliveryResultPhaseSchema.optional(),
|
|
1769
|
+
/** Non-empty failure reason; required iff `phase === "failed"`. */
|
|
1770
|
+
failedReason: import_zod29.z.string().min(1).max(2048).optional(),
|
|
1771
|
+
/**
|
|
1772
|
+
* When `true`, increment `runs.delivery_attempts` by 1 alongside
|
|
1773
|
+
* the phase write. Workers SHOULD set this on every delivery
|
|
1774
|
+
* (re)attempt so the audit row reflects retry count.
|
|
1775
|
+
*/
|
|
1776
|
+
incrementAttempts: import_zod29.z.boolean().optional()
|
|
1777
|
+
}).strict().refine(
|
|
1778
|
+
(data) => data.pullRequestUrl !== void 0 || data.artifacts !== void 0 || data.phase !== void 0 || data.failedReason !== void 0 || data.incrementAttempts !== void 0,
|
|
1779
|
+
{
|
|
1780
|
+
message: "At least one of pullRequestUrl / artifacts / phase / failedReason / incrementAttempts MUST be provided"
|
|
1781
|
+
}
|
|
1782
|
+
);
|
|
1783
|
+
var DeliveryResultUpdateResponseSchema = import_zod29.z.object({
|
|
1784
|
+
success: import_zod29.z.literal(true),
|
|
1785
|
+
data: import_zod29.z.object({
|
|
1786
|
+
/** Subset of the request fields whose persisted state actually
|
|
1787
|
+
* changed. `pullRequestUrl` is omitted on second-write (PR URL
|
|
1788
|
+
* already set) so callers can detect idempotent replays. */
|
|
1789
|
+
applied: import_zod29.z.array(
|
|
1790
|
+
import_zod29.z.enum(["pullRequestUrl", "artifacts", "phase", "failedReason", "incrementAttempts"])
|
|
1791
|
+
),
|
|
1792
|
+
/** Number of newly inserted artifact rows. Always 0 when `artifacts`
|
|
1793
|
+
* wasn't in the request. */
|
|
1794
|
+
artifactsInserted: import_zod29.z.number().int().nonnegative()
|
|
1795
|
+
})
|
|
1796
|
+
});
|
|
1797
|
+
var DeliveryResultErrorCodeSchema = import_zod29.z.enum([
|
|
1798
|
+
// 400 — request was malformed or schema-invalid
|
|
1799
|
+
"VALIDATION_ERROR",
|
|
1800
|
+
// 401 — Authorization header missing or session token invalid/expired
|
|
1801
|
+
"MISSING_SESSION_TOKEN",
|
|
1802
|
+
"SESSION_TOKEN_INVALID",
|
|
1803
|
+
"SESSION_TOKEN_EXPIRED",
|
|
1804
|
+
"SESSION_TOKEN_REVOKED",
|
|
1805
|
+
// 403 — the session token belongs to a different session than the URL
|
|
1806
|
+
"SESSION_TOKEN_SESSION_MISMATCH",
|
|
1807
|
+
// 404 — the URL session id / corresponding run does not exist
|
|
1808
|
+
"SESSION_NOT_FOUND",
|
|
1809
|
+
"RUN_NOT_FOUND",
|
|
1810
|
+
// 500 — fallthrough
|
|
1811
|
+
"INTERNAL_ERROR"
|
|
1812
|
+
]);
|
|
1813
|
+
var ResourceProfileSchema = import_zod33.z.object({
|
|
1814
|
+
cpu: import_zod33.z.string().min(1),
|
|
1815
|
+
memory: import_zod33.z.string().min(1),
|
|
1816
|
+
disk: import_zod33.z.string().min(1).optional(),
|
|
1817
|
+
gpu: import_zod33.z.string().min(1).optional()
|
|
1818
|
+
}).strict();
|
|
1819
|
+
var TraceContextSchema = import_zod33.z.object({
|
|
1820
|
+
traceId: import_zod33.z.string().min(1),
|
|
1821
|
+
spanId: import_zod33.z.string().min(1),
|
|
1822
|
+
parentSpanId: import_zod33.z.string().min(1).optional()
|
|
1823
|
+
}).strict();
|
|
1824
|
+
var TemplateKindSchema = import_zod33.z.enum(["claude-code", "codex", "amp"]);
|
|
1825
|
+
var RepoCoordinatesSchema = import_zod33.z.object({
|
|
1826
|
+
repoUrl: import_zod33.z.string().min(1),
|
|
1827
|
+
targetRef: import_zod33.z.string().min(1)
|
|
1828
|
+
}).strict();
|
|
1829
|
+
var ProvisionRequestSchema = import_zod33.z.object({
|
|
1830
|
+
idempotencyKey: import_zod33.z.string().min(1),
|
|
1831
|
+
template: TemplateKindSchema,
|
|
1832
|
+
resourceProfile: ResourceProfileSchema,
|
|
1833
|
+
repoCoordinates: RepoCoordinatesSchema.optional(),
|
|
1834
|
+
env: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()),
|
|
1835
|
+
trace: TraceContextSchema,
|
|
1836
|
+
deadlineMs: import_zod33.z.number().int().positive()
|
|
1837
|
+
}).strict();
|
|
1838
|
+
var WorkerProtocolVersionSchema = import_zod32.z.enum(["v1"]);
|
|
1839
|
+
var SessionRefSchema = import_zod32.z.object({
|
|
1840
|
+
sessionId: import_zod32.z.string().min(1),
|
|
1841
|
+
runtimeBindingId: import_zod32.z.string().min(1)
|
|
1842
|
+
}).strict();
|
|
1843
|
+
var FORBIDDEN_V1_PRIMITIVE_KEYS = ["runId", "agentId", "projectId", "provider"];
|
|
1844
|
+
function forbidV1Primitives(val, ctx) {
|
|
1845
|
+
for (const k of FORBIDDEN_V1_PRIMITIVE_KEYS) {
|
|
1846
|
+
if (k in val) {
|
|
1847
|
+
ctx.addIssue({
|
|
1848
|
+
code: import_zod32.z.ZodIssueCode.custom,
|
|
1849
|
+
path: [k],
|
|
1850
|
+
message: `R-WP-01: v1 primitive '${k}' is forbidden on v2 dispatch envelopes`
|
|
1851
|
+
});
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
var WorkerProtocolPromptRequestSchema = import_zod32.z.object({
|
|
1856
|
+
idempotencyKey: import_zod32.z.string().min(1),
|
|
1857
|
+
session: SessionRefSchema,
|
|
1858
|
+
protocolVersion: WorkerProtocolVersionSchema,
|
|
1859
|
+
promptText: import_zod32.z.string().min(1),
|
|
1860
|
+
trace: TraceContextSchema,
|
|
1861
|
+
// Legacy wall-clock deadline. Kept for back-compat with workers/dispatchers
|
|
1862
|
+
// that have not yet adopted the idle/hardCap split. NEW behavior:
|
|
1863
|
+
// - When `idleTimeoutMs` is supplied, framework uses idle-based deadline
|
|
1864
|
+
// (reset on each ctx.events.append success) plus optional `hardCapMs`
|
|
1865
|
+
// absolute upper bound; the legacy `deadlineMs` is ignored.
|
|
1866
|
+
// - When only `deadlineMs` is supplied, framework falls back to the
|
|
1867
|
+
// original wall-clock behavior (single setTimeout = deadlineMs).
|
|
1868
|
+
deadlineMs: import_zod32.z.number().int().positive(),
|
|
1869
|
+
// Idle timeout: framework fails the turn with `wp_handshake_timeout` if no
|
|
1870
|
+
// `ctx.events.append` succeeds within this many ms. Reset each time the
|
|
1871
|
+
// handler emits a session_event chunk — long-running but actively-streaming
|
|
1872
|
+
// handlers are NOT killed by the wall-clock alone.
|
|
1873
|
+
idleTimeoutMs: import_zod32.z.number().int().positive().optional(),
|
|
1874
|
+
// Hard upper bound that fires regardless of activity (defense against
|
|
1875
|
+
// infinite-loop handlers that keep emitting). Optional companion to
|
|
1876
|
+
// `idleTimeoutMs`; when omitted, no hard cap is armed.
|
|
1877
|
+
hardCapMs: import_zod32.z.number().int().positive().optional()
|
|
1878
|
+
}).passthrough().superRefine(forbidV1Primitives);
|
|
1879
|
+
var WorkerProtocolFollowupRequestSchema = import_zod32.z.object({
|
|
1880
|
+
idempotencyKey: import_zod32.z.string().min(1),
|
|
1881
|
+
session: SessionRefSchema,
|
|
1882
|
+
protocolVersion: WorkerProtocolVersionSchema,
|
|
1883
|
+
parentTurnId: import_zod32.z.string().min(1),
|
|
1884
|
+
followupText: import_zod32.z.string().min(1),
|
|
1885
|
+
trace: TraceContextSchema,
|
|
1886
|
+
// See `WorkerProtocolPromptRequestSchema.deadlineMs` for the legacy /
|
|
1887
|
+
// idle / hardCap precedence rules; same semantics apply for follow-up.
|
|
1888
|
+
deadlineMs: import_zod32.z.number().int().positive(),
|
|
1889
|
+
idleTimeoutMs: import_zod32.z.number().int().positive().optional(),
|
|
1890
|
+
hardCapMs: import_zod32.z.number().int().positive().optional()
|
|
1891
|
+
}).passthrough().superRefine(forbidV1Primitives);
|
|
1892
|
+
var WorkerProtocolAbortReasonSchema = import_zod32.z.discriminatedUnion("kind", [
|
|
1893
|
+
import_zod32.z.object({ kind: import_zod32.z.literal("user"), userId: import_zod32.z.string().min(1).optional() }).strict(),
|
|
1894
|
+
import_zod32.z.object({ kind: import_zod32.z.literal("timeout") }).strict(),
|
|
1895
|
+
import_zod32.z.object({ kind: import_zod32.z.literal("system"), hint: import_zod32.z.string().min(1) }).strict()
|
|
1896
|
+
]);
|
|
1897
|
+
var WorkerProtocolAbortRequestSchema = import_zod32.z.object({
|
|
1898
|
+
idempotencyKey: import_zod32.z.string().min(1),
|
|
1899
|
+
session: SessionRefSchema,
|
|
1900
|
+
protocolVersion: WorkerProtocolVersionSchema,
|
|
1901
|
+
turnId: import_zod32.z.string().min(1),
|
|
1902
|
+
reason: WorkerProtocolAbortReasonSchema,
|
|
1903
|
+
trace: TraceContextSchema
|
|
1904
|
+
}).passthrough().superRefine(forbidV1Primitives);
|
|
1905
|
+
var WorkerProtocolRestoreRequestSchema = import_zod32.z.object({
|
|
1906
|
+
idempotencyKey: import_zod32.z.string().min(1),
|
|
1907
|
+
session: SessionRefSchema,
|
|
1908
|
+
protocolVersion: WorkerProtocolVersionSchema,
|
|
1909
|
+
replayCursor: import_zod32.z.string().min(1).optional(),
|
|
1910
|
+
trace: TraceContextSchema,
|
|
1911
|
+
// See `WorkerProtocolPromptRequestSchema.deadlineMs` for the legacy /
|
|
1912
|
+
// idle / hardCap precedence rules.
|
|
1913
|
+
deadlineMs: import_zod32.z.number().int().positive(),
|
|
1914
|
+
idleTimeoutMs: import_zod32.z.number().int().positive().optional(),
|
|
1915
|
+
hardCapMs: import_zod32.z.number().int().positive().optional()
|
|
1916
|
+
}).passthrough().superRefine(forbidV1Primitives);
|
|
1917
|
+
var WP_FAILURE_REASON_KINDS = [
|
|
1918
|
+
"wp_protocol_violation",
|
|
1919
|
+
"wp_handshake_timeout",
|
|
1920
|
+
"wp_unsupported_version",
|
|
1921
|
+
"wp_invalid_envelope",
|
|
1922
|
+
"wp_stream_terminated",
|
|
1923
|
+
"wp_replay_lost"
|
|
1924
|
+
];
|
|
1925
|
+
var WP_FAILURE_REASON_ENUM = import_zod32.z.enum(WP_FAILURE_REASON_KINDS);
|
|
1926
|
+
var DispatchOutcomeSchema = import_zod32.z.discriminatedUnion("kind", [
|
|
1927
|
+
import_zod32.z.object({
|
|
1928
|
+
kind: import_zod32.z.literal("accepted"),
|
|
1929
|
+
turnId: import_zod32.z.string().min(1),
|
|
1930
|
+
protocolVersion: WorkerProtocolVersionSchema,
|
|
1931
|
+
observedAt: import_zod32.z.string().min(1)
|
|
1932
|
+
}).strict(),
|
|
1933
|
+
import_zod32.z.object({
|
|
1934
|
+
kind: import_zod32.z.literal("rejected"),
|
|
1935
|
+
reason: WP_FAILURE_REASON_ENUM,
|
|
1936
|
+
observedAt: import_zod32.z.string().min(1),
|
|
1937
|
+
message: import_zod32.z.string().min(1).optional()
|
|
1938
|
+
}).strict(),
|
|
1939
|
+
import_zod32.z.object({
|
|
1940
|
+
kind: import_zod32.z.literal("idempotent_replay"),
|
|
1941
|
+
turnId: import_zod32.z.string().min(1),
|
|
1942
|
+
priorOutcome: import_zod32.z.enum(["accepted", "rejected"]),
|
|
1943
|
+
observedAt: import_zod32.z.string().min(1)
|
|
1944
|
+
}).strict(),
|
|
1945
|
+
import_zod32.z.object({
|
|
1946
|
+
kind: import_zod32.z.literal("transport_failed"),
|
|
1947
|
+
reason: WP_FAILURE_REASON_ENUM,
|
|
1948
|
+
observedAt: import_zod32.z.string().min(1),
|
|
1949
|
+
message: import_zod32.z.string().min(1).optional()
|
|
1950
|
+
}).strict()
|
|
1951
|
+
]);
|
|
1952
|
+
var WorkerProtocolAcceptedPayloadSchema = import_zod31.z.object({
|
|
1953
|
+
turnId: import_zod31.z.string().min(1),
|
|
1954
|
+
protocolVersion: WorkerProtocolVersionSchema
|
|
1955
|
+
}).strict();
|
|
1956
|
+
var WorkerProtocolRejectedPayloadSchema = import_zod31.z.object({
|
|
1957
|
+
reason: import_zod31.z.enum(WP_FAILURE_REASON_KINDS),
|
|
1958
|
+
message: import_zod31.z.string().min(1).optional()
|
|
1959
|
+
}).strict();
|
|
1960
|
+
var WorkerProtocolFailedReasonSchema = import_zod31.z.enum([
|
|
1961
|
+
"wp_handshake_timeout",
|
|
1962
|
+
"wp_aborted_by_signal",
|
|
1963
|
+
"wp_protocol_violation",
|
|
1964
|
+
"wp_replay_lost",
|
|
1965
|
+
"wp_session_terminated"
|
|
1966
|
+
]);
|
|
1967
|
+
var WorkerProtocolFailedPayloadSchema = import_zod31.z.object({
|
|
1968
|
+
reason: WorkerProtocolFailedReasonSchema,
|
|
1969
|
+
message: import_zod31.z.string().min(1).optional(),
|
|
1970
|
+
abortContext: import_zod31.z.object({
|
|
1971
|
+
reason: WorkerProtocolAbortReasonSchema,
|
|
1972
|
+
requestedAt: import_zod31.z.string().min(1).optional()
|
|
1973
|
+
}).strict().optional()
|
|
1974
|
+
}).strict().refine((p) => p.reason !== "wp_aborted_by_signal" || p.abortContext !== void 0, {
|
|
1975
|
+
message: "abortContext required when reason = wp_aborted_by_signal"
|
|
1976
|
+
});
|
|
1977
|
+
var WorkerProtocolCompletedPayloadSchema = import_zod31.z.record(import_zod31.z.unknown());
|
|
1978
|
+
var EVENT_TYPE_REGEX = /^([a-z][a-z0-9_]*)\.([a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)?)$/;
|
|
1979
|
+
var EventTypeSchema = import_zod30.z.string().min(1).max(100, "event_type must not exceed SESSION_EVENT_TYPE_MAX_LENGTH (100)").regex(EVENT_TYPE_REGEX, "event_type must be {domain}.{action} in lowercase snake_case");
|
|
1980
|
+
var EVENT_DOMAINS = [
|
|
1981
|
+
"user",
|
|
1982
|
+
"agent",
|
|
1983
|
+
"session",
|
|
1984
|
+
"span",
|
|
1985
|
+
"worker_protocol",
|
|
1986
|
+
"vault"
|
|
1987
|
+
];
|
|
1988
|
+
var EVENT_DOMAIN_SET = new Set(EVENT_DOMAINS);
|
|
1989
|
+
var UserMessagePayloadSchema = import_zod30.z.object({
|
|
1990
|
+
content: import_zod30.z.array(
|
|
1991
|
+
import_zod30.z.union([
|
|
1992
|
+
import_zod30.z.object({ type: import_zod30.z.literal("text"), text: import_zod30.z.string() }).strict(),
|
|
1993
|
+
import_zod30.z.object({ type: import_zod30.z.literal("image"), source: import_zod30.z.unknown() }).strict(),
|
|
1994
|
+
import_zod30.z.object({ type: import_zod30.z.literal("file"), source: import_zod30.z.unknown() }).strict()
|
|
1995
|
+
])
|
|
1996
|
+
)
|
|
1997
|
+
}).strict();
|
|
1998
|
+
var UserInterruptPayloadSchema = import_zod30.z.object({}).strict();
|
|
1999
|
+
var UserToolConfirmationPayloadSchema = import_zod30.z.object({
|
|
2000
|
+
toolUseId: import_zod30.z.string().min(1),
|
|
2001
|
+
result: import_zod30.z.enum(["allow", "deny"]),
|
|
2002
|
+
denyMessage: import_zod30.z.string().optional()
|
|
2003
|
+
}).strict();
|
|
2004
|
+
var UserToolResultPayloadSchema = import_zod30.z.object({
|
|
2005
|
+
toolUseId: import_zod30.z.string().min(1),
|
|
2006
|
+
content: import_zod30.z.array(import_zod30.z.unknown())
|
|
2007
|
+
}).strict();
|
|
2008
|
+
var AgentMessagePayloadSchema = import_zod30.z.object({
|
|
2009
|
+
content: import_zod30.z.array(
|
|
2010
|
+
import_zod30.z.union([
|
|
2011
|
+
import_zod30.z.object({ type: import_zod30.z.literal("text"), text: import_zod30.z.string() }).strict(),
|
|
2012
|
+
import_zod30.z.object({ type: import_zod30.z.literal("image"), source: import_zod30.z.unknown() }).strict()
|
|
2013
|
+
])
|
|
2014
|
+
)
|
|
2015
|
+
}).strict();
|
|
2016
|
+
var AgentToolUsePayloadSchema = import_zod30.z.object({
|
|
2017
|
+
toolUseId: import_zod30.z.string().min(1),
|
|
2018
|
+
toolName: import_zod30.z.string().min(1),
|
|
2019
|
+
input: import_zod30.z.record(import_zod30.z.unknown())
|
|
2020
|
+
}).strict();
|
|
2021
|
+
var AgentToolResultPayloadSchema = import_zod30.z.object({
|
|
2022
|
+
toolUseId: import_zod30.z.string().min(1),
|
|
2023
|
+
content: import_zod30.z.array(import_zod30.z.unknown()),
|
|
2024
|
+
isError: import_zod30.z.boolean().optional()
|
|
2025
|
+
}).strict();
|
|
2026
|
+
var AgentMcpToolUsePayloadSchema = import_zod30.z.object({
|
|
2027
|
+
toolUseId: import_zod30.z.string().min(1),
|
|
2028
|
+
mcpServerName: import_zod30.z.string().min(1),
|
|
2029
|
+
toolName: import_zod30.z.string().min(1),
|
|
2030
|
+
input: import_zod30.z.record(import_zod30.z.unknown())
|
|
2031
|
+
}).strict();
|
|
2032
|
+
var AgentCompletedPayloadSchema = import_zod30.z.object({}).passthrough();
|
|
2033
|
+
var AGENT_SESSION_RESET_REASONS = [
|
|
2034
|
+
"session_terminal",
|
|
2035
|
+
// R-ASB-05 dim (a) — session.status === "failed"
|
|
2036
|
+
"session_lifecycle_terminal",
|
|
2037
|
+
// ready session whose lifecycle_phase is terminating/terminated
|
|
2038
|
+
"binding_missing",
|
|
2039
|
+
// dim (b) — no alive runtime_binding row
|
|
2040
|
+
"ttl_expired",
|
|
2041
|
+
// dim (c) — ttl_expires_at within REPROVISION_BUFFER_MS
|
|
2042
|
+
"keepalive_unhealthy",
|
|
2043
|
+
// dim (d) — MF-4 mark-unhealthy latch tripped
|
|
2044
|
+
"max_lifetime",
|
|
2045
|
+
// dim (e) — MF-5 24h+ session age
|
|
2046
|
+
"agent_session_null"
|
|
2047
|
+
// pre-dim — agent.session_id was NULL on dispatch
|
|
2048
|
+
];
|
|
2049
|
+
var AgentSessionResetReasonSchema = import_zod30.z.enum(AGENT_SESSION_RESET_REASONS);
|
|
2050
|
+
var AgentSessionResetPayloadSchema = import_zod30.z.object({
|
|
2051
|
+
oldSessionId: import_zod30.z.string().uuid(),
|
|
2052
|
+
newSessionId: import_zod30.z.string().uuid(),
|
|
2053
|
+
reason: AgentSessionResetReasonSchema,
|
|
2054
|
+
triggeredByRunId: import_zod30.z.string().uuid(),
|
|
2055
|
+
triggeredAt: import_zod30.z.string().datetime()
|
|
2056
|
+
}).strict();
|
|
2057
|
+
var AGENT_RECOVERY_ERROR_STAGES = ["provision", "startup", "hydrate", "dispatch"];
|
|
2058
|
+
var AgentRecoveryErrorStageSchema = import_zod30.z.enum(AGENT_RECOVERY_ERROR_STAGES);
|
|
2059
|
+
var AgentRecoveryStartedV2PayloadSchema = import_zod30.z.object({
|
|
2060
|
+
/** 1-based attempt counter (first revive of this session = 1). */
|
|
2061
|
+
revivalAttempts: import_zod30.z.number().int().min(1),
|
|
2062
|
+
/**
|
|
2063
|
+
* REV-INV-7 cap for the chain (typically 3). Optional for backward
|
|
2064
|
+
* compatibility with events emitted before the same-session retry
|
|
2065
|
+
* landed; consumers MUST treat absence as "unknown" rather than
|
|
2066
|
+
* "no cap" — they can fall back to `revivalAttempts >= 3` as the
|
|
2067
|
+
* default budget if they need a UI cue.
|
|
2068
|
+
*/
|
|
2069
|
+
maxRevivalAttempts: import_zod30.z.number().int().min(1).optional(),
|
|
2070
|
+
/** `runtime_bindings.id` of the row this revival is superseding. */
|
|
2071
|
+
predecessorBindingId: import_zod30.z.string().uuid(),
|
|
2072
|
+
/** UUID of this revival pipeline run; correlates the 4 lifecycle events. */
|
|
2073
|
+
attemptId: import_zod30.z.string().uuid()
|
|
2074
|
+
}).strict();
|
|
2075
|
+
var AgentRecoveryHydratedV2PayloadSchema = import_zod30.z.object({
|
|
2076
|
+
messagesCount: import_zod30.z.number().int().nonnegative(),
|
|
2077
|
+
/** Canonical SHA-256 hex of restored messages (see `pilot-v2-restore-envelope.md` R-RES-03). */
|
|
2078
|
+
messagesHash: import_zod30.z.string().min(1),
|
|
2079
|
+
degradedRecovery: import_zod30.z.boolean()
|
|
2080
|
+
}).strict();
|
|
2081
|
+
var AgentRecoveryCompletedV2PayloadSchema = import_zod30.z.object({
|
|
2082
|
+
degradedRecovery: import_zod30.z.boolean(),
|
|
2083
|
+
/** Raw `session_events` rows scanned before any cap-trim. */
|
|
2084
|
+
eventsSeen: import_zod30.z.number().int().nonnegative(),
|
|
2085
|
+
attemptId: import_zod30.z.string().uuid()
|
|
2086
|
+
}).strict();
|
|
2087
|
+
var AgentRecoveryFailedV2PayloadSchema = import_zod30.z.object({
|
|
2088
|
+
errorStage: AgentRecoveryErrorStageSchema,
|
|
2089
|
+
/** Human-readable, MUST NOT include credentials / PII. */
|
|
2090
|
+
error: import_zod30.z.string().min(1),
|
|
2091
|
+
attemptId: import_zod30.z.string().uuid()
|
|
2092
|
+
}).strict();
|
|
2093
|
+
var SessionStatusCreatedPayloadSchema = import_zod30.z.object({ sessionId: import_zod30.z.string().uuid(), createdAt: import_zod30.z.string() }).strict();
|
|
2094
|
+
var SessionStatusProvisioningPayloadSchema = import_zod30.z.object({
|
|
2095
|
+
sessionId: import_zod30.z.string().uuid(),
|
|
2096
|
+
runtimeBindingId: import_zod30.z.string().optional(),
|
|
2097
|
+
provisionStartedAt: import_zod30.z.string()
|
|
2098
|
+
}).strict();
|
|
2099
|
+
var SessionStatusStartingPayloadSchema = import_zod30.z.object({
|
|
2100
|
+
sessionId: import_zod30.z.string().uuid(),
|
|
2101
|
+
runtimeBindingId: import_zod30.z.string(),
|
|
2102
|
+
sandboxId: import_zod30.z.string(),
|
|
2103
|
+
workerEndpoint: import_zod30.z.string()
|
|
2104
|
+
}).strict();
|
|
2105
|
+
var SessionStatusReadyPayloadSchema = import_zod30.z.object({
|
|
2106
|
+
sessionId: import_zod30.z.string().uuid(),
|
|
2107
|
+
readyAt: import_zod30.z.string(),
|
|
2108
|
+
gateAggregate: import_zod30.z.object({ worker: import_zod30.z.literal(true) }).passthrough()
|
|
2109
|
+
}).strict();
|
|
2110
|
+
var SessionStatusFailedPayloadSchema = import_zod30.z.object({
|
|
2111
|
+
sessionId: import_zod30.z.string().uuid(),
|
|
2112
|
+
failedAt: import_zod30.z.string(),
|
|
2113
|
+
primaryFailure: import_zod30.z.object({
|
|
2114
|
+
source: import_zod30.z.string(),
|
|
2115
|
+
code: import_zod30.z.string(),
|
|
2116
|
+
message: import_zod30.z.string().optional()
|
|
2117
|
+
})
|
|
2118
|
+
}).strict();
|
|
2119
|
+
var SessionIdlePayloadSchema = import_zod30.z.object({
|
|
2120
|
+
sessionId: import_zod30.z.string().uuid(),
|
|
2121
|
+
stopReason: import_zod30.z.object({
|
|
2122
|
+
type: import_zod30.z.enum(["requires_action", "end_turn"]),
|
|
2123
|
+
eventIds: import_zod30.z.array(import_zod30.z.string()).optional()
|
|
2124
|
+
})
|
|
2125
|
+
}).strict();
|
|
2126
|
+
var EventTypeSessionStatusSchema = import_zod30.z.enum([
|
|
2127
|
+
"session.status_created",
|
|
2128
|
+
"session.status_provisioning",
|
|
2129
|
+
"session.status_starting",
|
|
2130
|
+
"session.status_ready",
|
|
2131
|
+
"session.status_failed"
|
|
2132
|
+
]);
|
|
2133
|
+
var SpanStartPayloadSchema = import_zod30.z.object({
|
|
2134
|
+
spanId: import_zod30.z.string().min(1),
|
|
2135
|
+
parentSpanId: import_zod30.z.string().optional(),
|
|
2136
|
+
name: import_zod30.z.string().min(1),
|
|
2137
|
+
startedAt: import_zod30.z.string(),
|
|
2138
|
+
attributes: import_zod30.z.record(import_zod30.z.unknown()).optional()
|
|
2139
|
+
}).strict();
|
|
2140
|
+
var SpanEndPayloadSchema = import_zod30.z.object({
|
|
2141
|
+
spanId: import_zod30.z.string().min(1),
|
|
2142
|
+
endedAt: import_zod30.z.string(),
|
|
2143
|
+
status: import_zod30.z.enum(["ok", "error"]).optional()
|
|
2144
|
+
}).strict();
|
|
2145
|
+
var SpanEventPayloadSchema = import_zod30.z.object({
|
|
2146
|
+
spanId: import_zod30.z.string().min(1),
|
|
2147
|
+
eventName: import_zod30.z.string().min(1),
|
|
2148
|
+
attributes: import_zod30.z.record(import_zod30.z.unknown()).optional()
|
|
2149
|
+
}).strict();
|
|
2150
|
+
var VaultArchivedPayloadSchema = import_zod30.z.object({ vaultId: import_zod30.z.string().min(1), archivedAt: import_zod30.z.string() }).strict();
|
|
2151
|
+
var VaultDeletedPayloadSchema = import_zod30.z.object({ vaultId: import_zod30.z.string().min(1), deletedAt: import_zod30.z.string() }).strict();
|
|
2152
|
+
var VaultCredentialArchivedPayloadSchema = import_zod30.z.object({
|
|
2153
|
+
vaultId: import_zod30.z.string().min(1),
|
|
2154
|
+
credentialId: import_zod30.z.string().min(1),
|
|
2155
|
+
archivedAt: import_zod30.z.string()
|
|
2156
|
+
}).strict();
|
|
2157
|
+
var VaultCredentialDeletedPayloadSchema = import_zod30.z.object({
|
|
2158
|
+
vaultId: import_zod30.z.string().min(1),
|
|
2159
|
+
credentialId: import_zod30.z.string().min(1),
|
|
2160
|
+
deletedAt: import_zod30.z.string()
|
|
2161
|
+
}).strict();
|
|
2162
|
+
var VaultCredentialRefreshFailedPayloadSchema = import_zod30.z.object({
|
|
2163
|
+
vaultId: import_zod30.z.string().min(1),
|
|
2164
|
+
credentialId: import_zod30.z.string().min(1),
|
|
2165
|
+
failedStatus: import_zod30.z.enum(["invalid", "unknown"]),
|
|
2166
|
+
lastRefreshedAt: import_zod30.z.string()
|
|
2167
|
+
}).strict();
|
|
2168
|
+
var VaultCredentialTargetNotAllowedPayloadSchema = import_zod30.z.object({
|
|
2169
|
+
sessionId: import_zod30.z.string().uuid(),
|
|
2170
|
+
vaultId: import_zod30.z.string().optional(),
|
|
2171
|
+
credentialId: import_zod30.z.string().optional(),
|
|
2172
|
+
mcpServerUrl: import_zod30.z.string(),
|
|
2173
|
+
reason: import_zod30.z.literal("target_not_in_revision_allowlist"),
|
|
2174
|
+
recoverable: import_zod30.z.literal(false),
|
|
2175
|
+
occurredAt: import_zod30.z.string()
|
|
2176
|
+
}).strict();
|
|
2177
|
+
var STANDARD_EVENT_PAYLOAD_SCHEMAS = {
|
|
2178
|
+
"user.message": UserMessagePayloadSchema,
|
|
2179
|
+
"user.interrupt": UserInterruptPayloadSchema,
|
|
2180
|
+
"user.tool_confirmation": UserToolConfirmationPayloadSchema,
|
|
2181
|
+
"user.tool_result": UserToolResultPayloadSchema,
|
|
2182
|
+
"agent.message": AgentMessagePayloadSchema,
|
|
2183
|
+
"agent.tool_use": AgentToolUsePayloadSchema,
|
|
2184
|
+
"agent.tool_result": AgentToolResultPayloadSchema,
|
|
2185
|
+
"agent.mcp_tool_use": AgentMcpToolUsePayloadSchema,
|
|
2186
|
+
"agent.completed": AgentCompletedPayloadSchema,
|
|
2187
|
+
"agent.session_reset": AgentSessionResetPayloadSchema,
|
|
2188
|
+
"agent.recovery_started": AgentRecoveryStartedV2PayloadSchema,
|
|
2189
|
+
"agent.recovery_hydrated": AgentRecoveryHydratedV2PayloadSchema,
|
|
2190
|
+
"agent.recovery_completed": AgentRecoveryCompletedV2PayloadSchema,
|
|
2191
|
+
"agent.recovery_failed": AgentRecoveryFailedV2PayloadSchema,
|
|
2192
|
+
"session.status_created": SessionStatusCreatedPayloadSchema,
|
|
2193
|
+
"session.status_provisioning": SessionStatusProvisioningPayloadSchema,
|
|
2194
|
+
"session.status_starting": SessionStatusStartingPayloadSchema,
|
|
2195
|
+
"session.status_ready": SessionStatusReadyPayloadSchema,
|
|
2196
|
+
"session.status_failed": SessionStatusFailedPayloadSchema,
|
|
2197
|
+
"session.idle": SessionIdlePayloadSchema,
|
|
2198
|
+
"span.start": SpanStartPayloadSchema,
|
|
2199
|
+
"span.end": SpanEndPayloadSchema,
|
|
2200
|
+
"span.event": SpanEventPayloadSchema,
|
|
2201
|
+
"vault.archived": VaultArchivedPayloadSchema,
|
|
2202
|
+
"vault.deleted": VaultDeletedPayloadSchema,
|
|
2203
|
+
"vault.credential_archived": VaultCredentialArchivedPayloadSchema,
|
|
2204
|
+
"vault.credential_deleted": VaultCredentialDeletedPayloadSchema,
|
|
2205
|
+
"vault.credential_refresh_failed": VaultCredentialRefreshFailedPayloadSchema,
|
|
2206
|
+
"vault.credential_target_not_allowed": VaultCredentialTargetNotAllowedPayloadSchema,
|
|
2207
|
+
// §1.5 worker_protocol.* — 4 kinds × 5 suffixes = 20 standard event types
|
|
2208
|
+
"worker_protocol.prompt.dispatched": WorkerProtocolPromptRequestSchema,
|
|
2209
|
+
"worker_protocol.prompt.accepted": WorkerProtocolAcceptedPayloadSchema,
|
|
2210
|
+
"worker_protocol.prompt.rejected": WorkerProtocolRejectedPayloadSchema,
|
|
2211
|
+
"worker_protocol.prompt.completed": WorkerProtocolCompletedPayloadSchema,
|
|
2212
|
+
"worker_protocol.prompt.failed": WorkerProtocolFailedPayloadSchema,
|
|
2213
|
+
"worker_protocol.followup.dispatched": WorkerProtocolFollowupRequestSchema,
|
|
2214
|
+
"worker_protocol.followup.accepted": WorkerProtocolAcceptedPayloadSchema,
|
|
2215
|
+
"worker_protocol.followup.rejected": WorkerProtocolRejectedPayloadSchema,
|
|
2216
|
+
"worker_protocol.followup.completed": WorkerProtocolCompletedPayloadSchema,
|
|
2217
|
+
"worker_protocol.followup.failed": WorkerProtocolFailedPayloadSchema,
|
|
2218
|
+
"worker_protocol.abort.dispatched": WorkerProtocolAbortRequestSchema,
|
|
2219
|
+
"worker_protocol.abort.accepted": WorkerProtocolAcceptedPayloadSchema,
|
|
2220
|
+
"worker_protocol.abort.rejected": WorkerProtocolRejectedPayloadSchema,
|
|
2221
|
+
"worker_protocol.abort.completed": WorkerProtocolCompletedPayloadSchema,
|
|
2222
|
+
"worker_protocol.abort.failed": WorkerProtocolFailedPayloadSchema,
|
|
2223
|
+
"worker_protocol.restore.dispatched": WorkerProtocolRestoreRequestSchema,
|
|
2224
|
+
"worker_protocol.restore.accepted": WorkerProtocolAcceptedPayloadSchema,
|
|
2225
|
+
"worker_protocol.restore.rejected": WorkerProtocolRejectedPayloadSchema,
|
|
2226
|
+
"worker_protocol.restore.completed": WorkerProtocolCompletedPayloadSchema,
|
|
2227
|
+
"worker_protocol.restore.failed": WorkerProtocolFailedPayloadSchema
|
|
2228
|
+
};
|
|
2229
|
+
var STANDARD_EVENT_TYPES = Object.keys(
|
|
2230
|
+
STANDARD_EVENT_PAYLOAD_SCHEMAS
|
|
2231
|
+
);
|
|
2232
|
+
var StandardEventTypeSchema = import_zod30.z.enum(STANDARD_EVENT_TYPES);
|
|
2233
|
+
var POD_AGENT_ENDPOINT_PORT = 8790;
|
|
2234
|
+
var AgentPortSpecSchema = import_zod35.z.object({
|
|
2235
|
+
name: import_zod35.z.string().min(1).max(63),
|
|
2236
|
+
port: import_zod35.z.number().int().min(1).max(65535),
|
|
2237
|
+
protocol: import_zod35.z.literal("TCP")
|
|
2238
|
+
}).strict();
|
|
2239
|
+
var IngressPathTypeSchema = import_zod35.z.enum(["prefix", "exact"]);
|
|
2240
|
+
var IngressSpecSchema = import_zod35.z.object({
|
|
2241
|
+
name: import_zod35.z.string().min(1).max(63),
|
|
2242
|
+
backendPort: import_zod35.z.number().int().min(1).max(65535).refine((p) => p !== POD_AGENT_ENDPOINT_PORT, {
|
|
2243
|
+
message: `backendPort ${POD_AGENT_ENDPOINT_PORT} is reserved for the platform pod-agent endpoint and MUST NOT be exposed via ingress.`
|
|
2244
|
+
}),
|
|
2245
|
+
hostPrefix: import_zod35.z.string().min(1).max(63),
|
|
2246
|
+
path: import_zod35.z.string().min(1).startsWith("/"),
|
|
2247
|
+
pathType: IngressPathTypeSchema
|
|
2248
|
+
}).strict();
|
|
2249
|
+
var AgentPublicEndpointSchema = import_zod35.z.object({
|
|
2250
|
+
/** Stable name; matches the originating `IngressSpec.name`. */
|
|
2251
|
+
name: import_zod35.z.string().min(1).max(63),
|
|
2252
|
+
/** TCP port the ingress targets; equals `IngressSpec.backendPort`. */
|
|
2253
|
+
backendPort: import_zod35.z.number().int().min(1).max(65535),
|
|
2254
|
+
/**
|
|
2255
|
+
* Declaration-derived public URL (`https://{hostPrefix}.{baseDomain}{path}`).
|
|
2256
|
+
* Best-effort — clients MUST validate reachability via standard HTTP
|
|
2257
|
+
* error handling; sandbox-side reconciliation is platform-internal.
|
|
2258
|
+
*/
|
|
2259
|
+
url: import_zod35.z.string().url(),
|
|
2260
|
+
/** Path prefix or exact match; must start with `/`. */
|
|
2261
|
+
path: import_zod35.z.string().min(1).startsWith("/"),
|
|
2262
|
+
/** Business-facing pathType (lowercase). */
|
|
2263
|
+
pathType: IngressPathTypeSchema
|
|
2264
|
+
}).strict();
|
|
2265
|
+
var WorkloadKindSchema = import_zod34.z.enum([
|
|
2266
|
+
"managed_agent",
|
|
2267
|
+
"batch_task",
|
|
2268
|
+
"external_worker",
|
|
2269
|
+
"self_managed"
|
|
2270
|
+
]);
|
|
2271
|
+
var SessionStatusSchema = import_zod34.z.enum([
|
|
2272
|
+
"created",
|
|
2273
|
+
"provisioning",
|
|
2274
|
+
"starting",
|
|
2275
|
+
"ready",
|
|
2276
|
+
"failed"
|
|
2277
|
+
]);
|
|
2278
|
+
var SessionUsageKindSchema = import_zod34.z.enum(["run_scoped", "conversation", "prewarmed"]);
|
|
2279
|
+
var StartupGateStatusSchema = import_zod34.z.enum(["true", "false", "unknown", "stale"]);
|
|
2280
|
+
var FailureReasonSourceSchema = import_zod34.z.enum([
|
|
2281
|
+
"control_plane",
|
|
2282
|
+
"scheduler",
|
|
2283
|
+
"runtime_provider",
|
|
2284
|
+
"pod_agent",
|
|
2285
|
+
"worker"
|
|
2286
|
+
]);
|
|
2287
|
+
var FailureReasonCodeSchema = import_zod34.z.enum([
|
|
2288
|
+
"TEMPLATE_NOT_FOUND",
|
|
2289
|
+
"POOL_NOT_READY",
|
|
2290
|
+
"SANDBOX_CREATE_FAILED",
|
|
2291
|
+
"SANDBOX_CREATE_TIMEOUT",
|
|
2292
|
+
"POD_AGENT_UNREACHABLE",
|
|
2293
|
+
"WORKER_START_FAILED",
|
|
2294
|
+
"WORKER_PROCESS_EXITED",
|
|
2295
|
+
"WORKER_HEALTH_FAILED",
|
|
2296
|
+
"WORKER_INTERNAL_ERROR",
|
|
2297
|
+
"WORKER_HEALTH_TIMEOUT",
|
|
2298
|
+
"GATE_REPORTED_FAILED",
|
|
2299
|
+
"GATE_READY_TIMEOUT",
|
|
2300
|
+
"PERMISSION_DENIED",
|
|
2301
|
+
"UNKNOWN_STARTUP_FAILURE"
|
|
2302
|
+
]);
|
|
2303
|
+
var WorkerHealthStateSchema = import_zod34.z.enum(["heartbeat", "ready", "failed"]);
|
|
2304
|
+
var WorkerHealthReasonCodeSchema = import_zod34.z.enum([
|
|
2305
|
+
"WORKER_BOOTING",
|
|
2306
|
+
"WORKER_READY",
|
|
2307
|
+
"WORKER_PROCESS_EXITED",
|
|
2308
|
+
"WORKER_HEALTH_CHECK_FAILED",
|
|
2309
|
+
"WORKER_INTERNAL_ERROR"
|
|
2310
|
+
]);
|
|
2311
|
+
var WorkerEndpointSpecSchema = import_zod34.z.object({
|
|
2312
|
+
port: import_zod34.z.number().int().positive(),
|
|
2313
|
+
basePath: import_zod34.z.string().optional()
|
|
2314
|
+
});
|
|
2315
|
+
var WorkerHealthSpecSchema = import_zod34.z.object({
|
|
2316
|
+
transport: import_zod34.z.literal("control_plane_pull"),
|
|
2317
|
+
path: import_zod34.z.literal("/pilot/worker/health"),
|
|
2318
|
+
pollIntervalSeconds: import_zod34.z.number().int().positive(),
|
|
2319
|
+
requestTimeoutSeconds: import_zod34.z.number().int().positive(),
|
|
2320
|
+
staleAfterSeconds: import_zod34.z.number().int().positive(),
|
|
2321
|
+
startupTimeoutSeconds: import_zod34.z.number().int().positive()
|
|
2322
|
+
});
|
|
2323
|
+
var P0_WORKER_HEALTH_SPEC = {
|
|
2324
|
+
transport: "control_plane_pull",
|
|
2325
|
+
path: "/pilot/worker/health",
|
|
2326
|
+
pollIntervalSeconds: 5,
|
|
2327
|
+
requestTimeoutSeconds: 3,
|
|
2328
|
+
staleAfterSeconds: 15,
|
|
2329
|
+
startupTimeoutSeconds: 60
|
|
2330
|
+
};
|
|
2331
|
+
var ImageDigestSchema = import_zod34.z.string().min(1).regex(/^sha256:[0-9a-fA-F]{64}$/, "Image digest must be a sha256 digest");
|
|
2332
|
+
var ImageProvenanceSchema = import_zod34.z.discriminatedUnion("kind", [
|
|
2333
|
+
import_zod34.z.object({
|
|
2334
|
+
kind: import_zod34.z.literal("image_asset"),
|
|
2335
|
+
imageAssetId: import_zod34.z.string().min(1),
|
|
2336
|
+
imageRef: import_zod34.z.string().min(1).optional(),
|
|
2337
|
+
imageDigest: ImageDigestSchema,
|
|
2338
|
+
sourceCommit: import_zod34.z.string().min(1).optional(),
|
|
2339
|
+
sourceRef: import_zod34.z.string().min(1).optional(),
|
|
2340
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2341
|
+
}).strict(),
|
|
2342
|
+
import_zod34.z.object({
|
|
2343
|
+
kind: import_zod34.z.literal("platform_image"),
|
|
2344
|
+
platformImageId: import_zod34.z.string().min(1),
|
|
2345
|
+
version: import_zod34.z.string().min(1),
|
|
2346
|
+
imageRef: import_zod34.z.string().min(1).optional(),
|
|
2347
|
+
imageDigest: ImageDigestSchema,
|
|
2348
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2349
|
+
}).strict(),
|
|
2350
|
+
import_zod34.z.object({
|
|
2351
|
+
kind: import_zod34.z.literal("legacy_external_template"),
|
|
2352
|
+
providerTemplateName: import_zod34.z.string().min(1),
|
|
2353
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2354
|
+
}).strict()
|
|
2355
|
+
]);
|
|
2356
|
+
var RuntimeTemplateSnapshotSchema = import_zod34.z.object({
|
|
2357
|
+
provider: import_zod34.z.literal("kanyun"),
|
|
2358
|
+
providerTemplateName: import_zod34.z.string().min(1),
|
|
2359
|
+
providerPoolName: import_zod34.z.string().min(1).optional(),
|
|
2360
|
+
imageProvenance: ImageProvenanceSchema.optional(),
|
|
2361
|
+
defaultWorkerEndpoint: WorkerEndpointSpecSchema,
|
|
2362
|
+
healthSpec: WorkerHealthSpecSchema.default(P0_WORKER_HEALTH_SPEC),
|
|
2363
|
+
/**
|
|
2364
|
+
* PR-E0 / §6 Wave 1 — business worker listen port (`POD_AGENT_WORKER_PORT`).
|
|
2365
|
+
* Defaults to 8787 in the auto-create API; persisted into the snapshot so a
|
|
2366
|
+
* published Revision freezes the value even if the source `runtime_templates`
|
|
2367
|
+
* row is later mutated.
|
|
2368
|
+
*/
|
|
2369
|
+
workerPort: import_zod34.z.number().int().min(1).max(65535).optional(),
|
|
2370
|
+
/**
|
|
2371
|
+
* Internal-only additional business container ports. Strict — does NOT
|
|
2372
|
+
* carry expose/hostPrefix/path; public exposure is declared via `ingresses[]`.
|
|
2373
|
+
*/
|
|
2374
|
+
agentPorts: import_zod34.z.array(AgentPortSpecSchema).optional(),
|
|
2375
|
+
/**
|
|
2376
|
+
* Independent public ingress rules. Each entry's `backendPort` MUST reference
|
|
2377
|
+
* `workerPort` or one of `agentPorts[].port`; cross-field validation is the
|
|
2378
|
+
* caller's responsibility via `validateRuntimeTemplateNetwork()` from
|
|
2379
|
+
* `@pilot/contracts` after `.parse(snapshot)`.
|
|
2380
|
+
*/
|
|
2381
|
+
ingresses: import_zod34.z.array(IngressSpecSchema).optional(),
|
|
2382
|
+
/**
|
|
2383
|
+
* Per-workload sandbox TTL (seconds) — lets each business define how long its
|
|
2384
|
+
* runtime sandbox lives before the provider reclaims it. Read by
|
|
2385
|
+
* `SessionStartupService` when provisioning; when omitted, the platform
|
|
2386
|
+
* `DEFAULT_TTL_SECONDS` applies (backward-compatible). A keep-alive service
|
|
2387
|
+
* extends the TTL while the session is active, so this primarily governs how
|
|
2388
|
+
* long an *idle* sandbox persists. Capped at 30 days to bound resource usage.
|
|
2389
|
+
*/
|
|
2390
|
+
ttlSeconds: import_zod34.z.number().int().positive().max(30 * 24 * 60 * 60).optional(),
|
|
2391
|
+
/**
|
|
2392
|
+
* Selects which set of handlers the agent-worker process registers
|
|
2393
|
+
* (`coder` for the JSON-payload pilot-coder loop, `echo` for the bare-text
|
|
2394
|
+
* managed_agent Default UI demo). Read by control-plane at startWorker
|
|
2395
|
+
* dispatch, forwarded via `PodAgentStartWorkerRequest.agentFlavor`,
|
|
2396
|
+
* eventually injected by pod-agent as `PILOT_AGENT_FLAVOR` env var.
|
|
2397
|
+
* Undefined → agent-worker defaults to coder (existing behavior,
|
|
2398
|
+
* backward-compatible for all existing snapshots).
|
|
2399
|
+
*
|
|
2400
|
+
* Locked enum: extend ONLY after the corresponding `FLAVOR_REGISTRY`
|
|
2401
|
+
* entry exists in `apps/agent-worker/src/v2/init.ts` (otherwise the
|
|
2402
|
+
* worker falls back to coder + console.warn).
|
|
2403
|
+
*/
|
|
2404
|
+
agentFlavor: import_zod34.z.enum(["coder", "echo"]).optional(),
|
|
2405
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2406
|
+
});
|
|
2407
|
+
var WorkerContractRefSchema = import_zod34.z.object({
|
|
2408
|
+
kind: WorkloadKindSchema,
|
|
2409
|
+
name: import_zod34.z.string().optional(),
|
|
2410
|
+
version: import_zod34.z.string().optional(),
|
|
2411
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2412
|
+
});
|
|
2413
|
+
var SESSION_CONFIG_VALUE_KEY_MAX_LENGTH = 100;
|
|
2414
|
+
var SESSION_EVENT_ID_MAX_LENGTH = 100;
|
|
2415
|
+
var SESSION_EVENT_TYPE_MAX_LENGTH = 100;
|
|
2416
|
+
var RESERVED_SESSION_CONFIG_ENV_PREFIXES = ["PILOT_", "SESSION_", "PLATFORM_"];
|
|
2417
|
+
function isReservedSessionConfigEnvKey(key) {
|
|
2418
|
+
return RESERVED_SESSION_CONFIG_ENV_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
2419
|
+
}
|
|
2420
|
+
var SessionConfigValuesSchema = import_zod34.z.record(import_zod34.z.string()).superRefine((values, ctx) => {
|
|
2421
|
+
for (const key of Object.keys(values)) {
|
|
2422
|
+
if (key.length > SESSION_CONFIG_VALUE_KEY_MAX_LENGTH) {
|
|
2423
|
+
ctx.addIssue({
|
|
2424
|
+
code: import_zod34.z.ZodIssueCode.too_big,
|
|
2425
|
+
maximum: SESSION_CONFIG_VALUE_KEY_MAX_LENGTH,
|
|
2426
|
+
type: "string",
|
|
2427
|
+
inclusive: true,
|
|
2428
|
+
message: `Config value key must be at most ${SESSION_CONFIG_VALUE_KEY_MAX_LENGTH} characters`,
|
|
2429
|
+
path: [key]
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
if (isReservedSessionConfigEnvKey(key)) {
|
|
2433
|
+
ctx.addIssue({
|
|
2434
|
+
code: import_zod34.z.ZodIssueCode.custom,
|
|
2435
|
+
message: `Config value key ${key} uses a reserved Pilot platform prefix`,
|
|
2436
|
+
path: [key]
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
});
|
|
2441
|
+
var SessionEventSchema = import_zod34.z.object({
|
|
2442
|
+
id: import_zod34.z.string().uuid(),
|
|
2443
|
+
sessionId: import_zod34.z.string().uuid(),
|
|
2444
|
+
eventId: import_zod34.z.string().min(1).max(SESSION_EVENT_ID_MAX_LENGTH),
|
|
2445
|
+
eventType: import_zod34.z.string().min(1).max(SESSION_EVENT_TYPE_MAX_LENGTH),
|
|
2446
|
+
payload: import_zod34.z.unknown().optional(),
|
|
2447
|
+
createdAt: import_zod34.z.string()
|
|
2448
|
+
});
|
|
2449
|
+
var SessionEventAppendRequestSchema = import_zod34.z.object({
|
|
2450
|
+
eventId: import_zod34.z.string().min(1).max(SESSION_EVENT_ID_MAX_LENGTH).optional(),
|
|
2451
|
+
eventType: import_zod34.z.string().min(1).max(SESSION_EVENT_TYPE_MAX_LENGTH),
|
|
2452
|
+
payload: import_zod34.z.unknown().optional()
|
|
2453
|
+
});
|
|
2454
|
+
var SessionTokenClaimsSchema = import_zod34.z.object({
|
|
2455
|
+
type: import_zod34.z.literal("pilot-session"),
|
|
2456
|
+
jti: import_zod34.z.string().uuid(),
|
|
2457
|
+
session_id: import_zod34.z.string().uuid(),
|
|
2458
|
+
workload_id: import_zod34.z.string().uuid(),
|
|
2459
|
+
revision_id: import_zod34.z.string().uuid(),
|
|
2460
|
+
tenant_id: import_zod34.z.string().uuid(),
|
|
2461
|
+
iat: import_zod34.z.number().int().nonnegative(),
|
|
2462
|
+
exp: import_zod34.z.number().int().positive().optional()
|
|
2463
|
+
});
|
|
2464
|
+
var WorkloadIdentityClaimSchema = import_zod34.z.object({
|
|
2465
|
+
type: import_zod34.z.literal("pilot-workload-identity"),
|
|
2466
|
+
workload_id: import_zod34.z.string().uuid(),
|
|
2467
|
+
revision_id: import_zod34.z.string().uuid(),
|
|
2468
|
+
tenant_id: import_zod34.z.string().uuid()
|
|
2469
|
+
});
|
|
2470
|
+
var StartupGatePolicySchema = import_zod34.z.object({
|
|
2471
|
+
required: import_zod34.z.array(import_zod34.z.string().min(1)).min(1),
|
|
2472
|
+
optional: import_zod34.z.array(import_zod34.z.string().min(1)).optional()
|
|
2473
|
+
});
|
|
2474
|
+
var StartupGateConditionSchema = import_zod34.z.object({
|
|
2475
|
+
gate: import_zod34.z.string().min(1),
|
|
2476
|
+
status: StartupGateStatusSchema,
|
|
2477
|
+
reasonCode: import_zod34.z.string().optional(),
|
|
2478
|
+
message: import_zod34.z.string().optional(),
|
|
2479
|
+
observedAt: import_zod34.z.string(),
|
|
2480
|
+
lastTransitionAt: import_zod34.z.string().optional(),
|
|
2481
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2482
|
+
});
|
|
2483
|
+
var FailureReasonSchema = import_zod34.z.object({
|
|
2484
|
+
code: FailureReasonCodeSchema,
|
|
2485
|
+
source: FailureReasonSourceSchema,
|
|
2486
|
+
message: import_zod34.z.string(),
|
|
2487
|
+
observedAt: import_zod34.z.string(),
|
|
2488
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2489
|
+
});
|
|
2490
|
+
var FailureReasonCandidateSchema = import_zod34.z.object({
|
|
2491
|
+
code: import_zod34.z.string().min(1),
|
|
2492
|
+
message: import_zod34.z.string(),
|
|
2493
|
+
observedAt: import_zod34.z.string().optional(),
|
|
2494
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2495
|
+
});
|
|
2496
|
+
var WorkerReportedConditionSchema = import_zod34.z.object({
|
|
2497
|
+
gate: import_zod34.z.string().min(1),
|
|
2498
|
+
status: StartupGateStatusSchema,
|
|
2499
|
+
reasonCode: import_zod34.z.string().optional(),
|
|
2500
|
+
message: import_zod34.z.string().optional(),
|
|
2501
|
+
observedAt: import_zod34.z.string().optional(),
|
|
2502
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2503
|
+
});
|
|
2504
|
+
var WorkerHealthObservationSchema = import_zod34.z.object({
|
|
2505
|
+
state: WorkerHealthStateSchema,
|
|
2506
|
+
reasonCode: WorkerHealthReasonCodeSchema.optional(),
|
|
2507
|
+
message: import_zod34.z.string().optional(),
|
|
2508
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional(),
|
|
2509
|
+
conditions: import_zod34.z.array(WorkerReportedConditionSchema).optional()
|
|
2510
|
+
});
|
|
2511
|
+
var PodAgentHealthResponseSchema = import_zod34.z.discriminatedUnion("kind", [
|
|
2512
|
+
import_zod34.z.object({
|
|
2513
|
+
kind: import_zod34.z.literal("worker_health"),
|
|
2514
|
+
observedAt: import_zod34.z.string(),
|
|
2515
|
+
worker: WorkerHealthObservationSchema
|
|
2516
|
+
}),
|
|
2517
|
+
import_zod34.z.object({
|
|
2518
|
+
kind: import_zod34.z.literal("worker_start_failed"),
|
|
2519
|
+
observedAt: import_zod34.z.string(),
|
|
2520
|
+
failureCandidate: FailureReasonCandidateSchema
|
|
2521
|
+
})
|
|
2522
|
+
]);
|
|
2523
|
+
var PodAgentStartWorkerRequestSchema = import_zod34.z.object({
|
|
2524
|
+
sessionId: import_zod34.z.string().uuid(),
|
|
2525
|
+
workloadId: import_zod34.z.string().uuid(),
|
|
2526
|
+
revisionId: import_zod34.z.string().uuid(),
|
|
2527
|
+
runtimeBindingId: import_zod34.z.string().uuid(),
|
|
2528
|
+
workerContract: WorkerContractRefSchema,
|
|
2529
|
+
healthSpec: WorkerHealthSpecSchema,
|
|
2530
|
+
env: import_zod34.z.record(import_zod34.z.string()).optional(),
|
|
2531
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional(),
|
|
2532
|
+
/**
|
|
2533
|
+
* Pod-Agent-only auth factor for upcoming Pilot v2 internal credentials API
|
|
2534
|
+
* (`POST /api/internal/credentials/*`). The token is generated by control-plane
|
|
2535
|
+
* at session creation time, stored on the session row, and delivered to
|
|
2536
|
+
* pod-agent **once** via this start request. Pod-agent MUST hold it in memory
|
|
2537
|
+
* only and MUST NOT forward it to the supervised worker process (neither via
|
|
2538
|
+
* env, file, nor IPC). See `specs/features/pilot-v2-pod-agent-oci-runtime-layer.md`
|
|
2539
|
+
* § "podAgentToken (Pod-Agent Auth Factor)" for the full contract.
|
|
2540
|
+
*
|
|
2541
|
+
* Backward-compat: optional in P3 Pre-P1 — pre-existing callers (legacy
|
|
2542
|
+
* control-worker, `--smoke` check) may omit it; pod-agent then operates in
|
|
2543
|
+
* `legacy` mode (no `podAgentToken` held, any future internal-credentials
|
|
2544
|
+
* API calls SHALL reject). P3 Phase 1 L1.4 will tighten control-plane to
|
|
2545
|
+
* always send this field; the schema may be promoted to required in a
|
|
2546
|
+
* separate spec PR after the v1 retirement window closes.
|
|
2547
|
+
*/
|
|
2548
|
+
podAgentToken: import_zod34.z.string().min(32).optional(),
|
|
2549
|
+
/**
|
|
2550
|
+
* Optional agent-worker handler flavor selector. Pod-agent forwards this
|
|
2551
|
+
* verbatim into the spawned child as `PILOT_AGENT_FLAVOR` env var (see
|
|
2552
|
+
* `apps/pod-agent/src/process-manager.ts → buildWorkerEnv`). Undefined →
|
|
2553
|
+
* pod-agent omits the env var, agent-worker `resolveFlavor()` falls back
|
|
2554
|
+
* to coder. Source of truth lives in
|
|
2555
|
+
* `RuntimeTemplateSnapshot.agentFlavor`; control-plane is responsible
|
|
2556
|
+
* for projecting that into this field at `startWorker` call time.
|
|
2557
|
+
*/
|
|
2558
|
+
agentFlavor: import_zod34.z.enum(["coder", "echo"]).optional(),
|
|
2559
|
+
/**
|
|
2560
|
+
* Optional agent-worker bundle tarball URL (v2 hot-deploy). When set,
|
|
2561
|
+
* pod-agent downloads + extracts this tarball over the baked
|
|
2562
|
+
* `/opt/pilot/agent-worker` dist BEFORE spawning the worker, so the
|
|
2563
|
+
* running binary matches the latest `apps/agent-worker` build rather
|
|
2564
|
+
* than whatever was baked into the Kanyun pod image. Mirrors the v1
|
|
2565
|
+
* `OrchestrationService.deployAgentWorker` mechanism (which has no v2
|
|
2566
|
+
* equivalent — see
|
|
2567
|
+
* `docs/handoff/2026-06-10-echo-runtime-coordinator-actions.md` §2).
|
|
2568
|
+
*
|
|
2569
|
+
* The URL is resolved by control-worker (`PodAgentHttpClient`) from
|
|
2570
|
+
* `AGENT_WORKER_BUNDLE_OSS_KEY` (presigned) / `AGENT_WORKER_BUNDLE_URL`
|
|
2571
|
+
* env — the same env contract v1 already uses. control-plane stays
|
|
2572
|
+
* OSS-agnostic and does NOT populate this field.
|
|
2573
|
+
*
|
|
2574
|
+
* Backward-compat: optional. Omitted → pod-agent skips hot-deploy and
|
|
2575
|
+
* runs the baked dist (legacy behavior). Old pod-agents that predate
|
|
2576
|
+
* this field ignore it (zod strip), also falling back to baked dist.
|
|
2577
|
+
*/
|
|
2578
|
+
agentWorkerBundleUrl: import_zod34.z.string().url().optional()
|
|
2579
|
+
});
|
|
2580
|
+
var PodAgentStartWorkerResponseSchema = import_zod34.z.discriminatedUnion("kind", [
|
|
2581
|
+
import_zod34.z.object({
|
|
2582
|
+
kind: import_zod34.z.literal("accepted"),
|
|
2583
|
+
observedAt: import_zod34.z.string(),
|
|
2584
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional()
|
|
2585
|
+
}),
|
|
2586
|
+
import_zod34.z.object({
|
|
2587
|
+
kind: import_zod34.z.literal("worker_start_failed"),
|
|
2588
|
+
observedAt: import_zod34.z.string(),
|
|
2589
|
+
failureCandidate: FailureReasonCandidateSchema
|
|
2590
|
+
})
|
|
2591
|
+
]);
|
|
2592
|
+
var CreateSessionRequestSchema = import_zod34.z.object({
|
|
2593
|
+
/**
|
|
2594
|
+
* P4 Phase 1.5 — optional caller-supplied resource id. When present, the
|
|
2595
|
+
* control-plane uses this UUID as the new Session row's primary key
|
|
2596
|
+
* (caller-controlled pin); when omitted, the control-plane generates a
|
|
2597
|
+
* `randomUUID()` (legacy / backward-compat behavior).
|
|
2598
|
+
*
|
|
2599
|
+
* Naming note: the field is intentionally named `sessionId` (not `id`) to
|
|
2600
|
+
* align with `CreateSessionResponseSchema.sessionId`. Despite the same
|
|
2601
|
+
* name on request and response, the semantics differ:
|
|
2602
|
+
* - request.sessionId = caller-supplied PK pin (write-side)
|
|
2603
|
+
* - response.sessionId = the actual Session row id (read-side, equal to
|
|
2604
|
+
* the request pin when supplied, or to the control-plane-generated
|
|
2605
|
+
* UUID when omitted)
|
|
2606
|
+
*
|
|
2607
|
+
* Use case: portal `POST /api/agents` dispatches v2 runs via
|
|
2608
|
+
* `dispatchV2AgentSession` and needs `runId === sessionId ===
|
|
2609
|
+
* runtimeBindingId` per `pilot-v2-managed-agent-handler-contract.md`
|
|
2610
|
+
* § "Managed-agent runtime binding cohort". Caller pins this field to
|
|
2611
|
+
* the freshly created run id so the entire cohort shares one UUID.
|
|
2612
|
+
*/
|
|
2613
|
+
sessionId: import_zod34.z.string().uuid().optional(),
|
|
2614
|
+
projectId: import_zod34.z.string().uuid(),
|
|
2615
|
+
workloadId: import_zod34.z.string().uuid(),
|
|
2616
|
+
revisionId: import_zod34.z.string().uuid().optional(),
|
|
2617
|
+
idempotencyScope: import_zod34.z.string().min(1).optional(),
|
|
2618
|
+
idempotencyKey: import_zod34.z.string().min(1).optional(),
|
|
2619
|
+
configValues: SessionConfigValuesSchema.optional(),
|
|
2620
|
+
metadata: import_zod34.z.record(import_zod34.z.unknown()).optional(),
|
|
2621
|
+
/**
|
|
2622
|
+
* GAP1-B (rush-app v2 migration) — optional caller-supplied stable runtime
|
|
2623
|
+
* claim name. Forwarded to the runtime provider's `create()` as the sandbox
|
|
2624
|
+
* `claimName`, which the sandbox control plane embeds in the public ingress
|
|
2625
|
+
* host (`<hostPrefix>-<claimName>.<baseDomain>`). Supplying a stable,
|
|
2626
|
+
* project-scoped value keeps preview URLs stable across abort→recreate
|
|
2627
|
+
* (scale-to-zero) cycles; omitted → control plane generates a per-sandbox
|
|
2628
|
+
* `claim-<nanoTS>` (host drifts on every recreate).
|
|
2629
|
+
*
|
|
2630
|
+
* MUST be DNS-label safe (lowercase alphanumeric + hyphen); the sandbox
|
|
2631
|
+
* control plane truncates the `<hostPrefix>-<claimName>` first label to 63
|
|
2632
|
+
* chars, so the distinguishing portion must fit within budget. Callers
|
|
2633
|
+
* (e.g. rush-app) typically derive it from a project-scoped key such as
|
|
2634
|
+
* `rush-<normalizedProjectId>`.
|
|
2635
|
+
*/
|
|
2636
|
+
runtimeClaimName: import_zod34.z.string().min(1).max(48).regex(
|
|
2637
|
+
/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/,
|
|
2638
|
+
"runtimeClaimName must be DNS-label safe (lowercase alphanumeric and hyphens, no leading/trailing hyphen)"
|
|
2639
|
+
).optional(),
|
|
2640
|
+
/**
|
|
2641
|
+
* PR-1 / §INV-2.1 — optional list of vault `public_id` values to bind to
|
|
2642
|
+
* this Session. The control plane resolves each `vlt_*` public_id to the
|
|
2643
|
+
* internal uuid, inserts `session_vault_bindings` rows, and freezes an
|
|
2644
|
+
* `allowedMcpTargets` snapshot from the active credentials' MCP URLs.
|
|
2645
|
+
*
|
|
2646
|
+
* Constraints (PR1-E):
|
|
2647
|
+
* - Each entry MUST match `^vlt_[a-z0-9]+$` (lowercase alphanumeric).
|
|
2648
|
+
* - Maximum 64 entries per request.
|
|
2649
|
+
* - Duplicates are rejected at the Zod layer (→ 400).
|
|
2650
|
+
* Requires `vaults:read` (or `vaults:admin`) scope (PR1-B → 403 if absent).
|
|
2651
|
+
*/
|
|
2652
|
+
vault_ids: import_zod34.z.array(import_zod34.z.string().regex(/^vlt_[a-z0-9]+$/, "vault_id must match vlt_[a-z0-9]+")).max(64, "vault_ids must have at most 64 entries").optional()
|
|
2653
|
+
}).strict().refine(
|
|
2654
|
+
(data) => {
|
|
2655
|
+
if (!data.vault_ids) return true;
|
|
2656
|
+
return new Set(data.vault_ids).size === data.vault_ids.length;
|
|
2657
|
+
},
|
|
2658
|
+
{
|
|
2659
|
+
message: "vault_ids must not contain duplicates",
|
|
2660
|
+
path: ["vault_ids"]
|
|
2661
|
+
}
|
|
2662
|
+
);
|
|
2663
|
+
var CreateSessionResponseSchema = import_zod34.z.object({
|
|
2664
|
+
sessionId: import_zod34.z.string().uuid(),
|
|
2665
|
+
status: SessionStatusSchema,
|
|
2666
|
+
/**
|
|
2667
|
+
* PR-1 / §INV-2.1 — MCP target URLs frozen at Session creation time.
|
|
2668
|
+
* Present only when the request supplied `vault_ids`; absent otherwise.
|
|
2669
|
+
* Each entry is a URL string (no internal uuids exposed — INV-1.1).
|
|
2670
|
+
*/
|
|
2671
|
+
allowed_mcp_targets: import_zod34.z.array(import_zod34.z.string().url()).optional()
|
|
2672
|
+
});
|
|
2673
|
+
var RESERVED_HEADERS = /* @__PURE__ */ new Set([
|
|
2674
|
+
"authorization",
|
|
2675
|
+
"host",
|
|
2676
|
+
"content-length",
|
|
2677
|
+
"content-encoding",
|
|
2678
|
+
"transfer-encoding",
|
|
2679
|
+
"connection",
|
|
2680
|
+
"upgrade",
|
|
2681
|
+
"cookie",
|
|
2682
|
+
"set-cookie",
|
|
2683
|
+
"server",
|
|
2684
|
+
"date"
|
|
2685
|
+
]);
|
|
2686
|
+
function isReservedHeader(name) {
|
|
2687
|
+
const lower = name.toLowerCase();
|
|
2688
|
+
return RESERVED_HEADERS.has(lower) || lower.startsWith("x-pilot-");
|
|
2689
|
+
}
|
|
2690
|
+
var VaultCredentialAuthTypeSchema = import_zod36.z.enum(["mcp_oauth", "static_bearer"]);
|
|
2691
|
+
var VaultCredentialRefreshStatusSchema = import_zod36.z.enum([
|
|
2692
|
+
"success",
|
|
2693
|
+
"failed_invalid",
|
|
2694
|
+
"failed_unknown"
|
|
2695
|
+
]);
|
|
2696
|
+
var CustomHeadersSchema = import_zod36.z.record(import_zod36.z.string().min(1).max(100), import_zod36.z.string().min(0).max(2048)).refine((m) => Object.keys(m).length <= 32, {
|
|
2697
|
+
message: "vault_credential_custom_headers_too_many_entries"
|
|
2698
|
+
}).refine((m) => Object.keys(m).every((k) => !isReservedHeader(k)), {
|
|
2699
|
+
message: "vault_credential_reserved_header_conflict"
|
|
2700
|
+
});
|
|
2701
|
+
var McpOAuthCredentialSchema = import_zod36.z.object({
|
|
2702
|
+
type: import_zod36.z.literal("mcp_oauth"),
|
|
2703
|
+
mcpServerUrl: import_zod36.z.string().url(),
|
|
2704
|
+
/**
|
|
2705
|
+
* Initial access token; write-only after create — never returned
|
|
2706
|
+
* by `VaultCredentialRecord` (per INV-3 / Claude write-only
|
|
2707
|
+
* invariant).
|
|
2708
|
+
*/
|
|
2709
|
+
accessToken: import_zod36.z.string().min(1),
|
|
2710
|
+
expiresAt: import_zod36.z.string().datetime(),
|
|
2711
|
+
customHeaders: CustomHeadersSchema.optional(),
|
|
2712
|
+
refresh: import_zod36.z.object({
|
|
2713
|
+
tokenEndpoint: import_zod36.z.string().url(),
|
|
2714
|
+
clientId: import_zod36.z.string().min(1),
|
|
2715
|
+
scope: import_zod36.z.string().optional(),
|
|
2716
|
+
/** Write-only; never returned. */
|
|
2717
|
+
refreshToken: import_zod36.z.string().min(1),
|
|
2718
|
+
tokenEndpointAuth: import_zod36.z.discriminatedUnion("type", [
|
|
2719
|
+
import_zod36.z.object({ type: import_zod36.z.literal("none") }).strict(),
|
|
2720
|
+
import_zod36.z.object({
|
|
2721
|
+
type: import_zod36.z.literal("client_secret_basic"),
|
|
2722
|
+
clientSecret: import_zod36.z.string().min(1)
|
|
2723
|
+
}).strict(),
|
|
2724
|
+
import_zod36.z.object({
|
|
2725
|
+
type: import_zod36.z.literal("client_secret_post"),
|
|
2726
|
+
clientSecret: import_zod36.z.string().min(1)
|
|
2727
|
+
}).strict()
|
|
2728
|
+
])
|
|
2729
|
+
}).strict()
|
|
2730
|
+
}).strict();
|
|
2731
|
+
var StaticBearerCredentialSchema = import_zod36.z.object({
|
|
2732
|
+
type: import_zod36.z.literal("static_bearer"),
|
|
2733
|
+
mcpServerUrl: import_zod36.z.string().url(),
|
|
2734
|
+
accessToken: import_zod36.z.string().min(1),
|
|
2735
|
+
customHeaders: CustomHeadersSchema.optional()
|
|
2736
|
+
}).strict();
|
|
2737
|
+
var CreateVaultRequestSchema = import_zod36.z.object({
|
|
2738
|
+
workspaceId: import_zod36.z.string().uuid(),
|
|
2739
|
+
displayName: import_zod36.z.string().min(1).max(200),
|
|
2740
|
+
external_user_id: import_zod36.z.string().min(1).max(200),
|
|
2741
|
+
metadata: import_zod36.z.record(import_zod36.z.unknown()).optional()
|
|
2742
|
+
}).strict();
|
|
2743
|
+
var VaultRecordSchema = import_zod36.z.object({
|
|
2744
|
+
type: import_zod36.z.literal("vault"),
|
|
2745
|
+
/** INV-1.1 public_id, `vlt_*` prefix. */
|
|
2746
|
+
id: import_zod36.z.string().regex(/^vlt_[a-zA-Z0-9]+$/),
|
|
2747
|
+
workspaceId: import_zod36.z.string().uuid(),
|
|
2748
|
+
/**
|
|
2749
|
+
* INV-1 second ownership layer — Pilot Platform Token actor /
|
|
2750
|
+
* credential owner principal id (IdP-agnostic per spec round 6).
|
|
2751
|
+
* Set server-side at create time from the Platform Token actor
|
|
2752
|
+
* identity; immutable. NOT a terminal user; NOT equivalent to
|
|
2753
|
+
* `external_user_id`.
|
|
2754
|
+
*/
|
|
2755
|
+
actorId: import_zod36.z.string().min(1),
|
|
2756
|
+
/** INV-1 third ownership layer — opaque business-side identifier. */
|
|
2757
|
+
external_user_id: import_zod36.z.string().min(1),
|
|
2758
|
+
displayName: import_zod36.z.string().min(1),
|
|
2759
|
+
metadata: import_zod36.z.record(import_zod36.z.unknown()).optional(),
|
|
2760
|
+
createdAt: import_zod36.z.string().datetime(),
|
|
2761
|
+
updatedAt: import_zod36.z.string().datetime(),
|
|
2762
|
+
archivedAt: import_zod36.z.string().datetime().nullable()
|
|
2763
|
+
}).strict();
|
|
2764
|
+
var ListVaultsFilterSchema = import_zod36.z.object({
|
|
2765
|
+
/**
|
|
2766
|
+
* Business-opaque cohort filter. Pilot does not interpret the
|
|
2767
|
+
* value — it is matched verbatim against the stored
|
|
2768
|
+
* `external_user_id` column.
|
|
2769
|
+
*/
|
|
2770
|
+
external_user_id: import_zod36.z.string().min(1).optional(),
|
|
2771
|
+
/** When true, archived rows are included; default `false`. */
|
|
2772
|
+
includeArchived: import_zod36.z.boolean().optional()
|
|
2773
|
+
}).strict();
|
|
2774
|
+
var CreateCredentialRequestSchema = import_zod36.z.object({
|
|
2775
|
+
displayName: import_zod36.z.string().min(1).max(200),
|
|
2776
|
+
auth: import_zod36.z.discriminatedUnion("type", [McpOAuthCredentialSchema, StaticBearerCredentialSchema])
|
|
2777
|
+
}).strict();
|
|
2778
|
+
var UpdateCredentialRequestSchema = import_zod36.z.object({
|
|
2779
|
+
displayName: import_zod36.z.string().min(1).max(200).optional(),
|
|
2780
|
+
customHeaders: CustomHeadersSchema.optional(),
|
|
2781
|
+
auth: import_zod36.z.object({
|
|
2782
|
+
accessToken: import_zod36.z.string().min(1).optional(),
|
|
2783
|
+
expiresAt: import_zod36.z.string().datetime().optional(),
|
|
2784
|
+
refresh: import_zod36.z.object({
|
|
2785
|
+
refreshToken: import_zod36.z.string().min(1).optional()
|
|
2786
|
+
}).strict().optional()
|
|
2787
|
+
}).strict().optional()
|
|
2788
|
+
}).strict();
|
|
2789
|
+
var VaultCredentialRecordSchema = import_zod36.z.object({
|
|
2790
|
+
type: import_zod36.z.literal("vault_credential"),
|
|
2791
|
+
/** INV-1.1 public_id, `vcrd_*` prefix. */
|
|
2792
|
+
id: import_zod36.z.string().regex(/^vcrd_[a-zA-Z0-9]+$/),
|
|
2793
|
+
/** INV-1.1 public_id reference to parent vault. */
|
|
2794
|
+
vaultId: import_zod36.z.string().regex(/^vlt_[a-zA-Z0-9]+$/),
|
|
2795
|
+
displayName: import_zod36.z.string().min(1),
|
|
2796
|
+
authType: VaultCredentialAuthTypeSchema,
|
|
2797
|
+
mcpServerUrl: import_zod36.z.string().url(),
|
|
2798
|
+
expiresAt: import_zod36.z.string().datetime().nullable(),
|
|
2799
|
+
lastRefreshedAt: import_zod36.z.string().datetime().nullable(),
|
|
2800
|
+
lastRefreshStatus: VaultCredentialRefreshStatusSchema.nullable(),
|
|
2801
|
+
createdAt: import_zod36.z.string().datetime(),
|
|
2802
|
+
updatedAt: import_zod36.z.string().datetime(),
|
|
2803
|
+
archivedAt: import_zod36.z.string().datetime().nullable()
|
|
2804
|
+
}).strict();
|
|
2805
|
+
var ListCredentialsFilterSchema = import_zod36.z.object({
|
|
2806
|
+
/** Filter by upstream MCP server URL. */
|
|
2807
|
+
mcpServerUrl: import_zod36.z.string().url().optional(),
|
|
2808
|
+
includeArchived: import_zod36.z.boolean().optional()
|
|
2809
|
+
}).strict();
|
|
2810
|
+
var ResolvedCredentialSchema = import_zod36.z.object({
|
|
2811
|
+
vaultId: import_zod36.z.string().regex(/^vlt_[a-zA-Z0-9]+$/),
|
|
2812
|
+
credentialId: import_zod36.z.string().regex(/^vcrd_[a-zA-Z0-9]+$/),
|
|
2813
|
+
authType: VaultCredentialAuthTypeSchema,
|
|
2814
|
+
accessToken: import_zod36.z.string().min(1),
|
|
2815
|
+
expiresAt: import_zod36.z.string().datetime().nullable(),
|
|
2816
|
+
customHeaders: CustomHeadersSchema
|
|
2817
|
+
}).strict();
|
|
2818
|
+
var VaultCredentialValidationSchema = import_zod36.z.object({
|
|
2819
|
+
status: import_zod36.z.enum(["valid", "invalid", "unknown"]),
|
|
2820
|
+
message: import_zod36.z.string().optional(),
|
|
2821
|
+
validatedAt: import_zod36.z.string().datetime()
|
|
2822
|
+
}).strict();
|
|
2823
|
+
var ScheduleTargetKindSchema = import_zod37.z.enum(["workload", "agent", "inline_v1", "inline_v2"]);
|
|
2824
|
+
var ScheduleApiVersionPreferenceSchema = import_zod37.z.enum(["v1", "v2"]);
|
|
2825
|
+
var ScheduleLifecycleStatusSchema = import_zod37.z.enum(["active", "disabled", "deleted"]);
|
|
2826
|
+
var ScheduleConcurrencyPolicySchema = import_zod37.z.enum(["allow", "forbid"]);
|
|
2827
|
+
var ScheduleMisfirePolicySchema = import_zod37.z.enum(["skip", "fire_once_immediately"]);
|
|
2828
|
+
var ScheduleTriggerSourceSchema = import_zod37.z.enum(["cron", "manual"]);
|
|
2829
|
+
var ScheduleTriggerStatusSchema = import_zod37.z.enum([
|
|
2830
|
+
"pending",
|
|
2831
|
+
"dispatched",
|
|
2832
|
+
"skipped",
|
|
2833
|
+
"failed_to_dispatch"
|
|
2834
|
+
]);
|
|
2835
|
+
var ScheduleSkippedReasonSchema = import_zod37.z.enum([
|
|
2836
|
+
"misfire",
|
|
2837
|
+
"concurrency_forbidden",
|
|
2838
|
+
"schedule_disabled",
|
|
2839
|
+
"out_of_window"
|
|
2840
|
+
]);
|
|
2841
|
+
var ScheduleFailureReasonCodeSchema = import_zod37.z.enum([
|
|
2842
|
+
"TARGET_NOT_FOUND",
|
|
2843
|
+
"TARGET_DISABLED",
|
|
2844
|
+
"REVISION_NOT_FOUND",
|
|
2845
|
+
"PERMISSION_DENIED",
|
|
2846
|
+
"UPSTREAM_UNAVAILABLE",
|
|
2847
|
+
"DOWNSTREAM_TIMEOUT",
|
|
2848
|
+
"ORPHANED_PENDING_TRIGGER",
|
|
2849
|
+
"UNKNOWN_DISPATCH_FAILURE"
|
|
2850
|
+
]);
|
|
2851
|
+
var ScheduleApiErrorCodeSchema = import_zod37.z.enum([
|
|
2852
|
+
"INVALID_CRON",
|
|
2853
|
+
"INVALID_TIMEZONE",
|
|
2854
|
+
"INVALID_TARGET",
|
|
2855
|
+
"UNSUPPORTED_VERSION_COMBO",
|
|
2856
|
+
"PROJECT_NOT_FOUND",
|
|
2857
|
+
"WORKLOAD_NOT_FOUND",
|
|
2858
|
+
"AGENT_NOT_FOUND",
|
|
2859
|
+
"REVISION_NOT_FOUND",
|
|
2860
|
+
"REVISION_NOT_FOR_TARGET_WORKLOAD",
|
|
2861
|
+
"TARGET_NOT_IN_PROJECT",
|
|
2862
|
+
"SCHEDULE_NOT_FOUND",
|
|
2863
|
+
"SCHEDULE_DISABLED",
|
|
2864
|
+
"CONCURRENCY_FORBIDDEN",
|
|
2865
|
+
"SCHEDULE_TRIGGER_CONFLICT",
|
|
2866
|
+
"FORBIDDEN_FIELD",
|
|
2867
|
+
"PERMISSION_DENIED",
|
|
2868
|
+
// P1.2: inline_v2 schedule references a workload slug that cannot be
|
|
2869
|
+
// resolved to any (workloadId, revisionId). Distinct from
|
|
2870
|
+
// WORKLOAD_NOT_FOUND (which is keyed by ID) — slug resolution is
|
|
2871
|
+
// dispatcher-time and surfaces a different remediation path.
|
|
2872
|
+
"WORKLOAD_SLUG_NOT_FOUND",
|
|
2873
|
+
// P1.2: project-or-owner anchor missing — caller submitted neither
|
|
2874
|
+
// projectId nor ownerLdap (or ownerLdap was empty for an inline
|
|
2875
|
+
// kind). 400.
|
|
2876
|
+
"MISSING_PROJECT_OR_OWNER",
|
|
2877
|
+
// Server-side internal error (DB returned no row, dispatcher failed
|
|
2878
|
+
// synchronously, etc.). Surfaces as HTTP 500 / SDK ScheduleClientError
|
|
2879
|
+
// category=platform_error. Distinct from `PERMISSION_DENIED` which
|
|
2880
|
+
// signals "the user is not authorized" — internal errors are not the
|
|
2881
|
+
// caller's fault. Spec §"API Error Codes".
|
|
2882
|
+
"INTERNAL_ERROR"
|
|
2883
|
+
]);
|
|
2884
|
+
var SCHEDULE_DISPLAY_NAME_MAX_LENGTH = 200;
|
|
2885
|
+
var SCHEDULE_DESCRIPTION_MAX_LENGTH = 1e3;
|
|
2886
|
+
var SCHEDULE_FAILURE_REASON_MESSAGE_MAX_LENGTH = 2e3;
|
|
2887
|
+
var SCHEDULE_MISFIRE_GRACE_SECONDS_MIN = 0;
|
|
2888
|
+
var SCHEDULE_MISFIRE_GRACE_SECONDS_MAX = 3600;
|
|
2889
|
+
var SCHEDULE_MISFIRE_GRACE_SECONDS_DEFAULT = 60;
|
|
2890
|
+
var SCHEDULE_FAILURE_THRESHOLD_MIN = 1;
|
|
2891
|
+
var SCHEDULE_FAILURE_THRESHOLD_MAX = 100;
|
|
2892
|
+
var SCHEDULE_FAILURE_THRESHOLD_DEFAULT = 5;
|
|
2893
|
+
function isValidIanaTimezone(value) {
|
|
2894
|
+
if (!value || value.length > 100) return false;
|
|
2895
|
+
try {
|
|
2896
|
+
new Intl.DateTimeFormat("en-US", { timeZone: value });
|
|
2897
|
+
return true;
|
|
2898
|
+
} catch (e) {
|
|
2899
|
+
return false;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
function isCronStructurallyValid(value) {
|
|
2903
|
+
const trimmed = value.trim();
|
|
2904
|
+
if (!trimmed) return false;
|
|
2905
|
+
const segments = trimmed.split(/\s+/);
|
|
2906
|
+
return segments.length === 5 || segments.length === 6;
|
|
2907
|
+
}
|
|
2908
|
+
var TimezoneStringSchema = import_zod37.z.string().min(1, "timezone must be a non-empty IANA identifier").refine(isValidIanaTimezone, "timezone must be a valid IANA identifier");
|
|
2909
|
+
var CronExpressionSchema = import_zod37.z.string().min(1, "cronExpression must be non-empty").max(200, "cronExpression must be at most 200 characters").refine(isCronStructurallyValid, "cronExpression must have 5 or 6 whitespace-separated segments");
|
|
2910
|
+
var IsoDatetimeSchema = import_zod37.z.string().datetime({ offset: true });
|
|
2911
|
+
var SCHEDULE_PAYLOAD_PROMPT_MAX_LENGTH = 5e4;
|
|
2912
|
+
var SchedulePayloadV1Schema = import_zod37.z.object({
|
|
2913
|
+
/** Required for v1 — `RunService.createRun` rejects empty prompts. */
|
|
2914
|
+
prompt: import_zod37.z.string().min(1).max(SCHEDULE_PAYLOAD_PROMPT_MAX_LENGTH),
|
|
2915
|
+
repo: import_zod37.z.string().max(2048).optional(),
|
|
2916
|
+
ref: import_zod37.z.string().max(255).optional(),
|
|
2917
|
+
model: import_zod37.z.string().max(255).optional(),
|
|
2918
|
+
/**
|
|
2919
|
+
* P1.6: tightened from `z.string().max(64).optional()` to
|
|
2920
|
+
* `ProviderTypeSchema.optional()`. Catches invalid provider strings
|
|
2921
|
+
* at schedule create / update time rather than letting the
|
|
2922
|
+
* dispatcher cast them through `RunSpec` and surface as a generic
|
|
2923
|
+
* Zod error on fire (P1.3 review [CONSIDER]).
|
|
2924
|
+
*/
|
|
2925
|
+
provider: ProviderTypeSchema.optional(),
|
|
2926
|
+
/**
|
|
2927
|
+
* LDAP of the user whose action created this schedule. Forwarded
|
|
2928
|
+
* verbatim to `runs.triggerUserLdap` so per-user Bedrock credentials
|
|
2929
|
+
* (specs/features/user-bedrock-credentials.md) resolve correctly on
|
|
2930
|
+
* cron-triggered runs. Null / undefined falls back to the
|
|
2931
|
+
* service-level Bedrock key.
|
|
2932
|
+
*/
|
|
2933
|
+
triggerUserLdap: import_zod37.z.string().min(1).max(255).optional()
|
|
2934
|
+
}).strict();
|
|
2935
|
+
var SchedulePayloadV2Schema = import_zod37.z.object({
|
|
2936
|
+
/**
|
|
2937
|
+
* Sandbox-environment overrides forwarded to
|
|
2938
|
+
* `CreateSessionRequest.configValues`. Reserved-env-key sanitization
|
|
2939
|
+
* is enforced at the SessionStartupService boundary; the schema
|
|
2940
|
+
* here keeps the shape opaque to avoid duplicating that policy.
|
|
2941
|
+
*/
|
|
2942
|
+
configValues: import_zod37.z.record(import_zod37.z.string(), import_zod37.z.string()).optional(),
|
|
2943
|
+
/** Free-form audit metadata; non-functional. */
|
|
2944
|
+
metadata: import_zod37.z.record(import_zod37.z.string(), import_zod37.z.unknown()).optional()
|
|
2945
|
+
}).strict();
|
|
2946
|
+
var ScheduleInlineV1PayloadSchema = import_zod37.z.object({
|
|
2947
|
+
prompt: import_zod37.z.string().min(1).max(SCHEDULE_PAYLOAD_PROMPT_MAX_LENGTH),
|
|
2948
|
+
repo: import_zod37.z.string().min(1).max(2048).optional(),
|
|
2949
|
+
ref: import_zod37.z.string().min(1).max(255).optional(),
|
|
2950
|
+
model: import_zod37.z.string().max(255).optional(),
|
|
2951
|
+
/**
|
|
2952
|
+
* P1.6: see `SchedulePayloadV1Schema.provider` — same rationale.
|
|
2953
|
+
* Closes the unsafe `as RunSpec["provider"]` cast in
|
|
2954
|
+
* `schedule-dispatcher.ts dispatchInlineV1` (P1.3 review [CONSIDER]).
|
|
2955
|
+
*/
|
|
2956
|
+
provider: ProviderTypeSchema.optional(),
|
|
2957
|
+
triggerUserLdap: import_zod37.z.string().min(1).max(255).optional(),
|
|
2958
|
+
/**
|
|
2959
|
+
* Per-fire MCP / Skills enable lists — same wire shape the home
|
|
2960
|
+
* composer sends to `POST /api/agents` (run-level override, spec
|
|
2961
|
+
* §4.3 "对话级别"). The dispatcher forwards these onto the
|
|
2962
|
+
* synthesised `RunSpec` so each cron-created Run resolves the same
|
|
2963
|
+
* MCPs / skills the user would get by clicking "新建任务" with the
|
|
2964
|
+
* same toggles. Omitted ⇒ no customization (empty resolution).
|
|
2965
|
+
*
|
|
2966
|
+
* Stored verbatim in `payload_json`; refs are resolved against the
|
|
2967
|
+
* owner's global credential store at run start, so a schedule keeps
|
|
2968
|
+
* working as long as the owner keeps the referenced MCP/skill
|
|
2969
|
+
* installed.
|
|
2970
|
+
*/
|
|
2971
|
+
enabledMcpServers: EnabledMcpEntryListSchema.optional(),
|
|
2972
|
+
enabledSkills: EnabledSkillEntryListSchema.optional(),
|
|
2973
|
+
/**
|
|
2974
|
+
* User-uploaded attachments — same wire shape the home composer
|
|
2975
|
+
* sends to `POST /api/agents` (`RunSpec.attachments`). Files are
|
|
2976
|
+
* uploaded once at schedule-authoring time to the owner's project
|
|
2977
|
+
* OSS space; the dispatcher forwards the stored `ossUrl` references
|
|
2978
|
+
* onto every synthesised `RunSpec`, so each cron-created Run sees
|
|
2979
|
+
* the same attachments. Capped at 5 to match `RunSpec.attachments`.
|
|
2980
|
+
*/
|
|
2981
|
+
attachments: import_zod37.z.array(AttachmentMetaSchema).max(5).optional()
|
|
2982
|
+
}).strict();
|
|
2983
|
+
var SCHEDULE_INLINE_V2_WORKLOAD_SLUG_REGEX = /^[a-z0-9][a-z0-9-]{0,127}$/;
|
|
2984
|
+
var ScheduleInlineV2PayloadSchema = import_zod37.z.object({
|
|
2985
|
+
workloadSlug: import_zod37.z.string().min(1).max(128).refine(
|
|
2986
|
+
(s) => SCHEDULE_INLINE_V2_WORKLOAD_SLUG_REGEX.test(s),
|
|
2987
|
+
"workloadSlug must be lowercase alphanumeric / dashes (1..128 chars)"
|
|
2988
|
+
),
|
|
2989
|
+
/** Default `"latest"`; UUID strings are treated as revision pin. */
|
|
2990
|
+
revisionSelector: import_zod37.z.union([import_zod37.z.literal("latest"), import_zod37.z.string().uuid()]).default("latest"),
|
|
2991
|
+
configValues: import_zod37.z.record(import_zod37.z.string(), import_zod37.z.string()).optional(),
|
|
2992
|
+
metadata: import_zod37.z.record(import_zod37.z.string(), import_zod37.z.unknown()).optional()
|
|
2993
|
+
}).strict();
|
|
2994
|
+
var RawPayloadSchema = import_zod37.z.record(import_zod37.z.string(), import_zod37.z.unknown());
|
|
2995
|
+
var ADMISSIBLE_TARGET_VERSION_COMBOS = ["workload:v2", "agent:v1", "inline_v1:v1", "inline_v1:v2", "inline_v2:v2"];
|
|
2996
|
+
function refineTargetFields(schema) {
|
|
2997
|
+
return schema.superRefine((value, ctx) => {
|
|
2998
|
+
switch (value.targetKind) {
|
|
2999
|
+
case "workload": {
|
|
3000
|
+
if (!value.targetWorkloadId) {
|
|
3001
|
+
ctx.addIssue({
|
|
3002
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3003
|
+
message: "targetWorkloadId is required when targetKind is 'workload'",
|
|
3004
|
+
path: ["targetWorkloadId"]
|
|
3005
|
+
});
|
|
3006
|
+
}
|
|
3007
|
+
if (value.targetAgentId) {
|
|
3008
|
+
ctx.addIssue({
|
|
3009
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3010
|
+
message: "targetAgentId must be omitted when targetKind is 'workload'",
|
|
3011
|
+
path: ["targetAgentId"]
|
|
3012
|
+
});
|
|
3013
|
+
}
|
|
3014
|
+
break;
|
|
3015
|
+
}
|
|
3016
|
+
case "agent": {
|
|
3017
|
+
if (!value.targetAgentId) {
|
|
3018
|
+
ctx.addIssue({
|
|
3019
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3020
|
+
message: "targetAgentId is required when targetKind is 'agent'",
|
|
3021
|
+
path: ["targetAgentId"]
|
|
3022
|
+
});
|
|
3023
|
+
}
|
|
3024
|
+
if (value.targetWorkloadId) {
|
|
3025
|
+
ctx.addIssue({
|
|
3026
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3027
|
+
message: "targetWorkloadId must be omitted when targetKind is 'agent'",
|
|
3028
|
+
path: ["targetWorkloadId"]
|
|
3029
|
+
});
|
|
3030
|
+
}
|
|
3031
|
+
if (value.targetRevisionId) {
|
|
3032
|
+
ctx.addIssue({
|
|
3033
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3034
|
+
message: "targetRevisionId is only allowed when targetKind is 'workload'",
|
|
3035
|
+
path: ["targetRevisionId"]
|
|
3036
|
+
});
|
|
3037
|
+
}
|
|
3038
|
+
break;
|
|
3039
|
+
}
|
|
3040
|
+
case "inline_v1":
|
|
3041
|
+
case "inline_v2": {
|
|
3042
|
+
if (value.targetWorkloadId) {
|
|
3043
|
+
ctx.addIssue({
|
|
3044
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3045
|
+
message: `targetWorkloadId must be omitted when targetKind is '${value.targetKind}'`,
|
|
3046
|
+
path: ["targetWorkloadId"]
|
|
3047
|
+
});
|
|
3048
|
+
}
|
|
3049
|
+
if (value.targetAgentId) {
|
|
3050
|
+
ctx.addIssue({
|
|
3051
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3052
|
+
message: `targetAgentId must be omitted when targetKind is '${value.targetKind}'`,
|
|
3053
|
+
path: ["targetAgentId"]
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
if (value.targetRevisionId) {
|
|
3057
|
+
ctx.addIssue({
|
|
3058
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3059
|
+
message: `targetRevisionId must be omitted when targetKind is '${value.targetKind}' (use payload.revisionSelector for inline_v2)`,
|
|
3060
|
+
path: ["targetRevisionId"]
|
|
3061
|
+
});
|
|
3062
|
+
}
|
|
3063
|
+
break;
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
const combo = `${value.targetKind}:${value.pilotApiVersionPreference}`;
|
|
3067
|
+
if (!ADMISSIBLE_TARGET_VERSION_COMBOS.includes(combo)) {
|
|
3068
|
+
ctx.addIssue({
|
|
3069
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3070
|
+
message: `Unsupported (targetKind, pilotApiVersionPreference) combination. Admissible: ${ADMISSIBLE_TARGET_VERSION_COMBOS.join(
|
|
3071
|
+
", "
|
|
3072
|
+
)}`,
|
|
3073
|
+
path: ["pilotApiVersionPreference"]
|
|
3074
|
+
});
|
|
3075
|
+
}
|
|
3076
|
+
const isInline = value.targetKind === "inline_v1" || value.targetKind === "inline_v2";
|
|
3077
|
+
if (!isInline && !value.projectId) {
|
|
3078
|
+
ctx.addIssue({
|
|
3079
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3080
|
+
message: `projectId is required when targetKind is '${value.targetKind}'`,
|
|
3081
|
+
path: ["projectId"]
|
|
3082
|
+
});
|
|
3083
|
+
}
|
|
3084
|
+
const hasProject = Boolean(value.projectId);
|
|
3085
|
+
const hasOwner = Boolean(value.ownerLdap && value.ownerLdap.length > 0);
|
|
3086
|
+
if (!hasProject && !hasOwner) {
|
|
3087
|
+
ctx.addIssue({
|
|
3088
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3089
|
+
message: "At least one of projectId / ownerLdap must be present (project-or-owner anchor)",
|
|
3090
|
+
path: ["ownerLdap"]
|
|
3091
|
+
});
|
|
3092
|
+
}
|
|
3093
|
+
});
|
|
3094
|
+
}
|
|
3095
|
+
function refineLifecycleWindow(schema) {
|
|
3096
|
+
return schema.superRefine((value, ctx) => {
|
|
3097
|
+
if (value.startAt && value.endAt) {
|
|
3098
|
+
const start = Date.parse(value.startAt);
|
|
3099
|
+
const end = Date.parse(value.endAt);
|
|
3100
|
+
if (Number.isFinite(start) && Number.isFinite(end) && end <= start) {
|
|
3101
|
+
ctx.addIssue({
|
|
3102
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3103
|
+
message: "endAt must be strictly later than startAt",
|
|
3104
|
+
path: ["endAt"]
|
|
3105
|
+
});
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
});
|
|
3109
|
+
}
|
|
3110
|
+
var CreateScheduleRequestBaseSchema = import_zod37.z.object({
|
|
3111
|
+
/**
|
|
3112
|
+
* Host project. Required for `targetKind ∈ {workload, agent}` (P0
|
|
3113
|
+
* shape); MAY be null for `inline_v1` / `inline_v2`. When null, the
|
|
3114
|
+
* `ownerLdap` field becomes the sole authorization anchor.
|
|
3115
|
+
*/
|
|
3116
|
+
projectId: import_zod37.z.string().uuid().nullable().optional(),
|
|
3117
|
+
/**
|
|
3118
|
+
* LDAP of the schedule owner (P1.2). Distinct from the implicit
|
|
3119
|
+
* `createdBy` which is captured server-side from the auth context.
|
|
3120
|
+
* MUST be non-empty when `projectId` is null. The route handler is
|
|
3121
|
+
* authoritative for enforcing "createdBy === ownerLdap" on create
|
|
3122
|
+
* (delegation / ownership transfer is an explicit follow-up).
|
|
3123
|
+
*/
|
|
3124
|
+
ownerLdap: import_zod37.z.string().min(1).max(255).optional(),
|
|
3125
|
+
displayName: import_zod37.z.string().min(1, "displayName must be non-empty").max(SCHEDULE_DISPLAY_NAME_MAX_LENGTH),
|
|
3126
|
+
description: import_zod37.z.string().max(SCHEDULE_DESCRIPTION_MAX_LENGTH).optional(),
|
|
3127
|
+
cronExpression: CronExpressionSchema,
|
|
3128
|
+
timezone: TimezoneStringSchema,
|
|
3129
|
+
targetKind: ScheduleTargetKindSchema,
|
|
3130
|
+
targetWorkloadId: import_zod37.z.string().uuid().optional(),
|
|
3131
|
+
targetRevisionId: import_zod37.z.string().uuid().optional(),
|
|
3132
|
+
targetAgentId: import_zod37.z.string().uuid().optional(),
|
|
3133
|
+
pilotApiVersionPreference: ScheduleApiVersionPreferenceSchema,
|
|
3134
|
+
concurrencyPolicy: ScheduleConcurrencyPolicySchema.default("allow"),
|
|
3135
|
+
misfirePolicy: ScheduleMisfirePolicySchema.default("skip"),
|
|
3136
|
+
misfireGraceSeconds: import_zod37.z.number().int().min(SCHEDULE_MISFIRE_GRACE_SECONDS_MIN).max(SCHEDULE_MISFIRE_GRACE_SECONDS_MAX).default(SCHEDULE_MISFIRE_GRACE_SECONDS_DEFAULT),
|
|
3137
|
+
consecutiveFailureThreshold: import_zod37.z.number().int().min(SCHEDULE_FAILURE_THRESHOLD_MIN).max(SCHEDULE_FAILURE_THRESHOLD_MAX).default(SCHEDULE_FAILURE_THRESHOLD_DEFAULT),
|
|
3138
|
+
startAt: IsoDatetimeSchema.optional(),
|
|
3139
|
+
endAt: IsoDatetimeSchema.optional(),
|
|
3140
|
+
/**
|
|
3141
|
+
* Dispatch parameter payload. Shape is determined by
|
|
3142
|
+
* `pilotApiVersionPreference` and validated by `refinePayload` (see
|
|
3143
|
+
* below). Stored verbatim into `schedule_definitions.payload_json`.
|
|
3144
|
+
*/
|
|
3145
|
+
payload: RawPayloadSchema
|
|
3146
|
+
}).strict();
|
|
3147
|
+
function refinePayload(schema) {
|
|
3148
|
+
return schema.superRefine((value, ctx) => {
|
|
3149
|
+
let payloadSchema;
|
|
3150
|
+
switch (value.targetKind) {
|
|
3151
|
+
case "workload":
|
|
3152
|
+
payloadSchema = SchedulePayloadV2Schema;
|
|
3153
|
+
break;
|
|
3154
|
+
case "agent":
|
|
3155
|
+
payloadSchema = SchedulePayloadV1Schema;
|
|
3156
|
+
break;
|
|
3157
|
+
case "inline_v1":
|
|
3158
|
+
payloadSchema = ScheduleInlineV1PayloadSchema;
|
|
3159
|
+
break;
|
|
3160
|
+
case "inline_v2":
|
|
3161
|
+
payloadSchema = ScheduleInlineV2PayloadSchema;
|
|
3162
|
+
break;
|
|
3163
|
+
}
|
|
3164
|
+
const result = payloadSchema.safeParse(value.payload);
|
|
3165
|
+
if (!result.success) {
|
|
3166
|
+
for (const issue of result.error.issues) {
|
|
3167
|
+
ctx.addIssue({
|
|
3168
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3169
|
+
message: issue.message,
|
|
3170
|
+
path: ["payload", ...issue.path]
|
|
3171
|
+
});
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
});
|
|
3175
|
+
}
|
|
3176
|
+
var CreateScheduleRequestSchema = refinePayload(
|
|
3177
|
+
refineLifecycleWindow(refineTargetFields(CreateScheduleRequestBaseSchema))
|
|
3178
|
+
);
|
|
3179
|
+
var UpdateScheduleRequestBaseSchema = import_zod37.z.object({
|
|
3180
|
+
displayName: import_zod37.z.string().min(1).max(SCHEDULE_DISPLAY_NAME_MAX_LENGTH).optional(),
|
|
3181
|
+
description: import_zod37.z.string().max(SCHEDULE_DESCRIPTION_MAX_LENGTH).nullable().optional(),
|
|
3182
|
+
/**
|
|
3183
|
+
* Convenience field — `true` ⇒ lifecycle_status='active',
|
|
3184
|
+
* `false` ⇒ lifecycle_status='disabled'. Cannot reach `deleted`
|
|
3185
|
+
* via PATCH (use DELETE).
|
|
3186
|
+
*/
|
|
3187
|
+
enabled: import_zod37.z.boolean().optional(),
|
|
3188
|
+
cronExpression: CronExpressionSchema.optional(),
|
|
3189
|
+
timezone: TimezoneStringSchema.optional(),
|
|
3190
|
+
concurrencyPolicy: ScheduleConcurrencyPolicySchema.optional(),
|
|
3191
|
+
misfirePolicy: ScheduleMisfirePolicySchema.optional(),
|
|
3192
|
+
misfireGraceSeconds: import_zod37.z.number().int().min(SCHEDULE_MISFIRE_GRACE_SECONDS_MIN).max(SCHEDULE_MISFIRE_GRACE_SECONDS_MAX).optional(),
|
|
3193
|
+
consecutiveFailureThreshold: import_zod37.z.number().int().min(SCHEDULE_FAILURE_THRESHOLD_MIN).max(SCHEDULE_FAILURE_THRESHOLD_MAX).optional(),
|
|
3194
|
+
endAt: IsoDatetimeSchema.nullable().optional(),
|
|
3195
|
+
/**
|
|
3196
|
+
* Replaces the entire dispatch payload. Null is forbidden — to
|
|
3197
|
+
* "clear" optional sub-fields, send a payload object that omits
|
|
3198
|
+
* them. Payload shape (v1 vs v2) is fixed at create time per
|
|
3199
|
+
* INV-5; the route handler validates against the schedule's
|
|
3200
|
+
* stored `pilotApiVersionPreference` before persisting.
|
|
3201
|
+
*/
|
|
3202
|
+
payload: RawPayloadSchema.optional()
|
|
3203
|
+
}).strict();
|
|
3204
|
+
var UpdateScheduleRequestSchema = UpdateScheduleRequestBaseSchema.refine(
|
|
3205
|
+
(data) => Object.keys(data).length > 0,
|
|
3206
|
+
{ message: "PATCH body must contain at least one field" }
|
|
3207
|
+
);
|
|
3208
|
+
var ScheduleViewBaseSchema = import_zod37.z.object({
|
|
3209
|
+
id: import_zod37.z.string().uuid(),
|
|
3210
|
+
/**
|
|
3211
|
+
* Nullable since P1.2 — only inline kinds may have null projectId in
|
|
3212
|
+
* persisted form; workload / agent kinds keep it set (enforced at
|
|
3213
|
+
* create time and by DB shape CHECK).
|
|
3214
|
+
*/
|
|
3215
|
+
projectId: import_zod37.z.string().uuid().nullable(),
|
|
3216
|
+
/**
|
|
3217
|
+
* Owner LDAP (P1.2). NOT NULL in DB; the read shape exposes it for
|
|
3218
|
+
* UI to render "owned by" labels and for permission checks on
|
|
3219
|
+
* project-less schedules.
|
|
3220
|
+
*/
|
|
3221
|
+
ownerLdap: import_zod37.z.string(),
|
|
3222
|
+
displayName: import_zod37.z.string(),
|
|
3223
|
+
description: import_zod37.z.string().nullable(),
|
|
3224
|
+
cronExpression: import_zod37.z.string(),
|
|
3225
|
+
timezone: import_zod37.z.string(),
|
|
3226
|
+
targetKind: ScheduleTargetKindSchema,
|
|
3227
|
+
targetWorkloadId: import_zod37.z.string().uuid().nullable(),
|
|
3228
|
+
targetRevisionId: import_zod37.z.string().uuid().nullable(),
|
|
3229
|
+
targetAgentId: import_zod37.z.string().uuid().nullable(),
|
|
3230
|
+
pilotApiVersionPreference: ScheduleApiVersionPreferenceSchema,
|
|
3231
|
+
lifecycleStatus: ScheduleLifecycleStatusSchema,
|
|
3232
|
+
concurrencyPolicy: ScheduleConcurrencyPolicySchema,
|
|
3233
|
+
misfirePolicy: ScheduleMisfirePolicySchema,
|
|
3234
|
+
misfireGraceSeconds: import_zod37.z.number().int().nonnegative(),
|
|
3235
|
+
startAt: IsoDatetimeSchema.nullable(),
|
|
3236
|
+
endAt: IsoDatetimeSchema.nullable(),
|
|
3237
|
+
payload: RawPayloadSchema,
|
|
3238
|
+
consecutiveFailureCount: import_zod37.z.number().int().nonnegative(),
|
|
3239
|
+
consecutiveFailureThreshold: import_zod37.z.number().int().positive(),
|
|
3240
|
+
lastTriggerAt: IsoDatetimeSchema.nullable(),
|
|
3241
|
+
nextFireAt: IsoDatetimeSchema.nullable(),
|
|
3242
|
+
createdBy: import_zod37.z.string(),
|
|
3243
|
+
createdAt: IsoDatetimeSchema,
|
|
3244
|
+
updatedAt: IsoDatetimeSchema,
|
|
3245
|
+
deletedAt: IsoDatetimeSchema.nullable()
|
|
3246
|
+
});
|
|
3247
|
+
var ScheduleViewSchema = refineTargetFields(
|
|
3248
|
+
ScheduleViewBaseSchema
|
|
3249
|
+
);
|
|
3250
|
+
var ScheduleListItemSchema = ScheduleViewBaseSchema.pick({
|
|
3251
|
+
id: true,
|
|
3252
|
+
projectId: true,
|
|
3253
|
+
ownerLdap: true,
|
|
3254
|
+
displayName: true,
|
|
3255
|
+
cronExpression: true,
|
|
3256
|
+
timezone: true,
|
|
3257
|
+
targetKind: true,
|
|
3258
|
+
targetWorkloadId: true,
|
|
3259
|
+
targetAgentId: true,
|
|
3260
|
+
pilotApiVersionPreference: true,
|
|
3261
|
+
lifecycleStatus: true,
|
|
3262
|
+
lastTriggerAt: true,
|
|
3263
|
+
nextFireAt: true,
|
|
3264
|
+
createdAt: true,
|
|
3265
|
+
updatedAt: true
|
|
3266
|
+
});
|
|
3267
|
+
var ScheduleListResponseSchema = import_zod37.z.object({
|
|
3268
|
+
items: import_zod37.z.array(ScheduleListItemSchema),
|
|
3269
|
+
nextCursor: import_zod37.z.string().optional()
|
|
3270
|
+
});
|
|
3271
|
+
var ScheduleTriggerViewSchema = import_zod37.z.object({
|
|
3272
|
+
id: import_zod37.z.string().uuid(),
|
|
3273
|
+
scheduleId: import_zod37.z.string().uuid(),
|
|
3274
|
+
firedAt: IsoDatetimeSchema,
|
|
3275
|
+
triggerSource: ScheduleTriggerSourceSchema,
|
|
3276
|
+
status: ScheduleTriggerStatusSchema,
|
|
3277
|
+
dispatchedAt: IsoDatetimeSchema.nullable(),
|
|
3278
|
+
dispatchedRunId: import_zod37.z.string().uuid().nullable(),
|
|
3279
|
+
dispatchedSessionId: import_zod37.z.string().uuid().nullable(),
|
|
3280
|
+
/**
|
|
3281
|
+
* Owning agent of the dispatched Run / Session, when one exists.
|
|
3282
|
+
* Resolved by joining `runs.agent_id` on the dispatched run/session id
|
|
3283
|
+
* (cohort invariant: `run.id === session.id`). Lets the UI deep-link
|
|
3284
|
+
* the trigger to `/agents/:agentId`. Null for pure-workload v2
|
|
3285
|
+
* dispatches (no agent) and for non-dispatched triggers.
|
|
3286
|
+
*/
|
|
3287
|
+
dispatchedAgentId: import_zod37.z.string().uuid().nullable(),
|
|
3288
|
+
skippedReason: ScheduleSkippedReasonSchema.nullable(),
|
|
3289
|
+
failureReasonCode: ScheduleFailureReasonCodeSchema.nullable(),
|
|
3290
|
+
failureReasonMessage: import_zod37.z.string().max(SCHEDULE_FAILURE_REASON_MESSAGE_MAX_LENGTH).nullable(),
|
|
3291
|
+
idempotencyKey: import_zod37.z.string(),
|
|
3292
|
+
attemptCount: import_zod37.z.number().int().nonnegative(),
|
|
3293
|
+
blockingTriggerId: import_zod37.z.string().uuid().nullable(),
|
|
3294
|
+
createdAt: IsoDatetimeSchema
|
|
3295
|
+
}).superRefine((trigger, ctx) => {
|
|
3296
|
+
if (trigger.status === "dispatched") {
|
|
3297
|
+
if (!trigger.dispatchedAt) {
|
|
3298
|
+
ctx.addIssue({
|
|
3299
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3300
|
+
message: "dispatchedAt is required when status is 'dispatched'",
|
|
3301
|
+
path: ["dispatchedAt"]
|
|
3302
|
+
});
|
|
3303
|
+
}
|
|
3304
|
+
const hasRun = trigger.dispatchedRunId !== null;
|
|
3305
|
+
const hasSession = trigger.dispatchedSessionId !== null;
|
|
3306
|
+
if (hasRun === hasSession) {
|
|
3307
|
+
ctx.addIssue({
|
|
3308
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3309
|
+
message: "Exactly one of dispatchedRunId / dispatchedSessionId must be set when status is 'dispatched'",
|
|
3310
|
+
path: ["dispatchedRunId"]
|
|
3311
|
+
});
|
|
3312
|
+
}
|
|
3313
|
+
} else {
|
|
3314
|
+
if (trigger.dispatchedAt !== null) {
|
|
3315
|
+
ctx.addIssue({
|
|
3316
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3317
|
+
message: "dispatchedAt must be null when status is not 'dispatched'",
|
|
3318
|
+
path: ["dispatchedAt"]
|
|
3319
|
+
});
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
if (trigger.status === "skipped" && trigger.skippedReason === null) {
|
|
3323
|
+
ctx.addIssue({
|
|
3324
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3325
|
+
message: "skippedReason is required when status is 'skipped'",
|
|
3326
|
+
path: ["skippedReason"]
|
|
3327
|
+
});
|
|
3328
|
+
}
|
|
3329
|
+
if (trigger.status !== "skipped" && trigger.skippedReason !== null) {
|
|
3330
|
+
ctx.addIssue({
|
|
3331
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3332
|
+
message: "skippedReason must be null when status is not 'skipped'",
|
|
3333
|
+
path: ["skippedReason"]
|
|
3334
|
+
});
|
|
3335
|
+
}
|
|
3336
|
+
if (trigger.status === "failed_to_dispatch" && trigger.failureReasonCode === null) {
|
|
3337
|
+
ctx.addIssue({
|
|
3338
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3339
|
+
message: "failureReasonCode is required when status is 'failed_to_dispatch'",
|
|
3340
|
+
path: ["failureReasonCode"]
|
|
3341
|
+
});
|
|
3342
|
+
}
|
|
3343
|
+
if (trigger.status !== "failed_to_dispatch" && trigger.failureReasonCode !== null) {
|
|
3344
|
+
ctx.addIssue({
|
|
3345
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3346
|
+
message: "failureReasonCode must be null when status is not 'failed_to_dispatch'",
|
|
3347
|
+
path: ["failureReasonCode"]
|
|
3348
|
+
});
|
|
3349
|
+
}
|
|
3350
|
+
if (trigger.blockingTriggerId !== null && !(trigger.status === "skipped" && trigger.skippedReason === "concurrency_forbidden")) {
|
|
3351
|
+
ctx.addIssue({
|
|
3352
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3353
|
+
message: "blockingTriggerId is only meaningful for skipped+concurrency_forbidden rows",
|
|
3354
|
+
path: ["blockingTriggerId"]
|
|
3355
|
+
});
|
|
3356
|
+
}
|
|
3357
|
+
});
|
|
3358
|
+
var ScheduleTriggerListResponseSchema = import_zod37.z.object({
|
|
3359
|
+
items: import_zod37.z.array(ScheduleTriggerViewSchema),
|
|
3360
|
+
nextCursor: import_zod37.z.string().optional()
|
|
3361
|
+
});
|
|
3362
|
+
var RunScheduleResponseSchema = import_zod37.z.object({
|
|
3363
|
+
triggerId: import_zod37.z.string().uuid(),
|
|
3364
|
+
dispatchedRunId: import_zod37.z.string().uuid().optional(),
|
|
3365
|
+
dispatchedSessionId: import_zod37.z.string().uuid().optional()
|
|
3366
|
+
}).superRefine((value, ctx) => {
|
|
3367
|
+
const hasRun = value.dispatchedRunId !== void 0;
|
|
3368
|
+
const hasSession = value.dispatchedSessionId !== void 0;
|
|
3369
|
+
if (hasRun === hasSession) {
|
|
3370
|
+
ctx.addIssue({
|
|
3371
|
+
code: import_zod37.z.ZodIssueCode.custom,
|
|
3372
|
+
message: "Exactly one of dispatchedRunId / dispatchedSessionId must be present in run-now response"
|
|
3373
|
+
});
|
|
3374
|
+
}
|
|
3375
|
+
});
|
|
3376
|
+
var ScheduleApiErrorBodySchema = import_zod37.z.object({
|
|
3377
|
+
error: import_zod37.z.object({
|
|
3378
|
+
code: ScheduleApiErrorCodeSchema,
|
|
3379
|
+
message: import_zod37.z.string(),
|
|
3380
|
+
details: import_zod37.z.record(import_zod37.z.unknown()).optional()
|
|
3381
|
+
})
|
|
3382
|
+
});
|
|
3383
|
+
var RevisionWorkerContractRefSchema = WorkerContractRefSchema.pick({
|
|
3384
|
+
kind: true,
|
|
3385
|
+
name: true,
|
|
3386
|
+
version: true
|
|
3387
|
+
}).strict();
|
|
3388
|
+
var PILOT_WORKLOAD_MANIFEST_API_VERSION = "pilot.zhenguanyu.com/v0alpha1";
|
|
3389
|
+
var PILOT_WORKLOAD_MANIFEST_LEGACY_API_VERSION = "pilot.kanyun.ai/v0alpha1";
|
|
3390
|
+
var PILOT_WORKLOAD_MANIFEST_API_VERSIONS = [
|
|
3391
|
+
PILOT_WORKLOAD_MANIFEST_API_VERSION,
|
|
3392
|
+
PILOT_WORKLOAD_MANIFEST_LEGACY_API_VERSION
|
|
3393
|
+
];
|
|
3394
|
+
var PilotWorkloadManifestApiVersionSchema = import_zod39.z.enum(PILOT_WORKLOAD_MANIFEST_API_VERSIONS);
|
|
3395
|
+
var WORKLOAD_MANIFEST_NAME_MAX_LENGTH = 100;
|
|
3396
|
+
var WORKLOAD_MANIFEST_DISPLAY_NAME_MAX_LENGTH = 255;
|
|
3397
|
+
var WORKLOAD_MANIFEST_REF_NAME_MAX_LENGTH = 255;
|
|
3398
|
+
var WorkloadManifestErrorCodeSchema = import_zod39.z.enum([
|
|
3399
|
+
"MANIFEST_UNSUPPORTED_API_VERSION",
|
|
3400
|
+
"MANIFEST_UNSUPPORTED_KIND",
|
|
3401
|
+
"MANIFEST_VALIDATION_ERROR",
|
|
3402
|
+
"WORKLOAD_KIND_UNSUPPORTED",
|
|
3403
|
+
"WORKLOAD_NOT_FOUND",
|
|
3404
|
+
"WORKLOAD_KIND_MISMATCH",
|
|
3405
|
+
"PROJECT_DEFAULT_RUNTIME_MISSING",
|
|
3406
|
+
"RUNTIME_TEMPLATE_NOT_FOUND",
|
|
3407
|
+
"REVISION_REGISTRATION_CONFLICT",
|
|
3408
|
+
// Cross-project safety: thrown when `applyRevisionManifest` resolves a
|
|
3409
|
+
// workload and a runtime template that live in different projects.
|
|
3410
|
+
// Mirrors the `revisions_project_consistency` DB trigger; the
|
|
3411
|
+
// application-layer check exits early with a friendlier error code
|
|
3412
|
+
// before the trigger fires raw `check_violation` SQLSTATE 23514.
|
|
3413
|
+
// Plan: plans/admin-ui-project-namespacing.md §C2.
|
|
3414
|
+
"REVISION_CROSS_PROJECT",
|
|
3415
|
+
"IMAGE_PROVENANCE_REQUIRED",
|
|
3416
|
+
"IMAGE_PROVENANCE_INVALID",
|
|
3417
|
+
"LEGACY_PROVENANCE_NOT_ALLOWED"
|
|
3418
|
+
]);
|
|
3419
|
+
var ActiveWorkloadKindSchema = import_zod39.z.enum(["managed_agent", "self_managed"]);
|
|
3420
|
+
var DeferredWorkloadKindSchema = import_zod39.z.enum(["external_worker", "batch_task"]);
|
|
3421
|
+
var DNS_LABEL_STYLE_PATTERN = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/;
|
|
3422
|
+
var WorkloadManifestNameSchema = import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_NAME_MAX_LENGTH).regex(DNS_LABEL_STYLE_PATTERN, "Name must be DNS-label-style");
|
|
3423
|
+
var WorkloadManifestDisplayNameSchema = import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_DISPLAY_NAME_MAX_LENGTH);
|
|
3424
|
+
var WorkloadManifestRefNameSchema = import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_REF_NAME_MAX_LENGTH);
|
|
3425
|
+
var WorkloadManifestObjectRefSchema = import_zod39.z.object({
|
|
3426
|
+
name: WorkloadManifestRefNameSchema
|
|
3427
|
+
}).strict();
|
|
3428
|
+
var WorkloadManifestMetadataBaseSchema = import_zod39.z.object({
|
|
3429
|
+
name: WorkloadManifestNameSchema,
|
|
3430
|
+
labels: import_zod39.z.record(import_zod39.z.string()).optional(),
|
|
3431
|
+
annotations: import_zod39.z.record(import_zod39.z.string()).optional()
|
|
3432
|
+
}).strict();
|
|
3433
|
+
var WorkloadManifestMetadataSchema = WorkloadManifestMetadataBaseSchema.extend({
|
|
3434
|
+
displayName: WorkloadManifestDisplayNameSchema
|
|
3435
|
+
}).strict();
|
|
3436
|
+
var RevisionManifestMetadataSchema = WorkloadManifestMetadataBaseSchema.extend({
|
|
3437
|
+
workload: WorkloadManifestNameSchema
|
|
3438
|
+
}).strict();
|
|
3439
|
+
var WorkloadManifestCapabilityRefsSchema = import_zod39.z.object({
|
|
3440
|
+
modelRef: WorkloadManifestObjectRefSchema.optional(),
|
|
3441
|
+
toolRefs: import_zod39.z.array(WorkloadManifestObjectRefSchema).optional(),
|
|
3442
|
+
mcpRefs: import_zod39.z.array(WorkloadManifestObjectRefSchema).optional()
|
|
3443
|
+
}).strict();
|
|
3444
|
+
var WorkloadManifestPolicyRefsSchema = import_zod39.z.object({
|
|
3445
|
+
credentialPolicyRef: WorkloadManifestObjectRefSchema.optional(),
|
|
3446
|
+
readinessPolicyRef: WorkloadManifestObjectRefSchema.optional(),
|
|
3447
|
+
actionPolicyRef: WorkloadManifestObjectRefSchema.optional(),
|
|
3448
|
+
trafficPolicyRef: WorkloadManifestObjectRefSchema.optional()
|
|
3449
|
+
}).strict();
|
|
3450
|
+
var WorkloadManifestWorkerContractDefaultsSchema = import_zod39.z.object({
|
|
3451
|
+
name: WorkloadManifestRefNameSchema.optional(),
|
|
3452
|
+
version: import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_NAME_MAX_LENGTH).optional()
|
|
3453
|
+
}).strict();
|
|
3454
|
+
var WORKLOAD_MANIFEST_MODEL_MAX_LENGTH = 255;
|
|
3455
|
+
var WorkloadManifestModelSchema = import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_MODEL_MAX_LENGTH);
|
|
3456
|
+
var WORKLOAD_MANIFEST_SYSTEM_PROMPT_MAX_LENGTH = 32768;
|
|
3457
|
+
var WorkloadManifestSystemPromptSchema = import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_SYSTEM_PROMPT_MAX_LENGTH);
|
|
3458
|
+
var ManagedAgentProfileSnapshotSchema = import_zod39.z.object({
|
|
3459
|
+
model: WorkloadManifestModelSchema.optional(),
|
|
3460
|
+
systemPrompt: WorkloadManifestSystemPromptSchema.optional(),
|
|
3461
|
+
enabledSkills: EnabledSkillEntryListSchema.optional(),
|
|
3462
|
+
enabledMcpServers: EnabledMcpEntryListSchema.optional(),
|
|
3463
|
+
configValues: SessionConfigValuesSchema.optional()
|
|
3464
|
+
}).strict();
|
|
3465
|
+
var ManagedAgentOverridesSchema = import_zod39.z.object({
|
|
3466
|
+
model: WorkloadManifestModelSchema.nullable().optional(),
|
|
3467
|
+
systemPrompt: WorkloadManifestSystemPromptSchema.nullable().optional(),
|
|
3468
|
+
enabledSkills: EnabledSkillEntryListSchema.optional(),
|
|
3469
|
+
enabledMcpServers: EnabledMcpEntryListSchema.optional()
|
|
3470
|
+
}).strict();
|
|
3471
|
+
var WorkloadManifestDefaultsSchema = import_zod39.z.object({
|
|
3472
|
+
runtimeTemplateRef: WorkloadManifestObjectRefSchema.optional(),
|
|
3473
|
+
workerContract: WorkloadManifestWorkerContractDefaultsSchema.optional(),
|
|
3474
|
+
capabilityRefs: WorkloadManifestCapabilityRefsSchema.optional(),
|
|
3475
|
+
configValues: SessionConfigValuesSchema.optional(),
|
|
3476
|
+
model: WorkloadManifestModelSchema.optional(),
|
|
3477
|
+
/**
|
|
3478
|
+
* Workload-level **default system prompt** (managed_agent profile
|
|
3479
|
+
* Phase D). Seeded onto `agents.system_prompt` at agent creation and
|
|
3480
|
+
* forwarded per-run as `PilotCoderRunConfigV1.systemPrompt`. See
|
|
3481
|
+
* `specs/features/pilot-v2-managed-agent-profile.md` §"Phase D".
|
|
3482
|
+
*/
|
|
3483
|
+
systemPrompt: WorkloadManifestSystemPromptSchema.optional(),
|
|
3484
|
+
/**
|
|
3485
|
+
* Workload-level **default enabled skills** (managed_agent profile
|
|
3486
|
+
* Phase C). Persisted into `workloads.manifest_defaults_json` and
|
|
3487
|
+
* seeded into `agents.enabled_skills` at agent creation when the
|
|
3488
|
+
* caller does not supply explicit skills. Accepts the snapshot-or-ref
|
|
3489
|
+
* union (same write contract as `projects.enabled_skills`); the
|
|
3490
|
+
* `POST /api/workloads` route resolves any refs into full
|
|
3491
|
+
* `EnabledSkill` snapshots via the rush registry before persisting so
|
|
3492
|
+
* the workload default is self-contained (no per-user install
|
|
3493
|
+
* dependency). See `specs/features/pilot-v2-managed-agent-profile.md`
|
|
3494
|
+
* §"Phase C".
|
|
3495
|
+
*/
|
|
3496
|
+
enabledSkills: EnabledSkillEntryListSchema.optional(),
|
|
3497
|
+
/**
|
|
3498
|
+
* Workload-level **default enabled MCP servers** (managed_agent
|
|
3499
|
+
* profile Phase C2). Persisted into `workloads.manifest_defaults_json`
|
|
3500
|
+
* and seeded into `agents.enabled_mcp_servers` at agent creation when
|
|
3501
|
+
* the caller does not supply explicit MCP servers. Accepts the
|
|
3502
|
+
* snapshot-or-ref union (same write contract as
|
|
3503
|
+
* `projects.enabled_mcp_servers`); the `POST /api/workloads` route
|
|
3504
|
+
* resolves any refs into full `EnabledMcpServer` snapshots via the
|
|
3505
|
+
* rush registry before persisting so the workload default is
|
|
3506
|
+
* self-contained.
|
|
3507
|
+
*
|
|
3508
|
+
* Resolution at `POST /api/workloads` produces a mix:
|
|
3509
|
+
* - **credential-free** MCP (rush `requiredVars` empty, Phase C2) →
|
|
3510
|
+
* frozen `EnabledMcpServer` snapshot (self-contained, cross-user
|
|
3511
|
+
* identical).
|
|
3512
|
+
* - **credentialed** MCP (rush `requiredVars` non-empty, Phase C3) →
|
|
3513
|
+
* bare `EnabledMcpRef { rushMcpId }`; the credential is NOT frozen
|
|
3514
|
+
* here, it resolves per running user from `user_mcp_installs` at
|
|
3515
|
+
* bootstrap (ref-resolver), with per-MCP failure isolation when an
|
|
3516
|
+
* install is missing (`mcp-and-skills.md` §4.2).
|
|
3517
|
+
*
|
|
3518
|
+
* Inline plaintext credentials (`extraConfigValues` /
|
|
3519
|
+
* `extraConfigValuesOverride`) are rejected at resolution — a
|
|
3520
|
+
* cross-user workload default never stores one user's secret. See
|
|
3521
|
+
* `specs/features/pilot-v2-managed-agent-profile.md` §"Phase C".
|
|
3522
|
+
*/
|
|
3523
|
+
enabledMcpServers: EnabledMcpEntryListSchema.optional()
|
|
3524
|
+
}).strict();
|
|
3525
|
+
var WORKLOAD_MANIFEST_UI_DISPLAY_NAME_MAX_LENGTH = 255;
|
|
3526
|
+
var WORKLOAD_MANIFEST_UI_PROMPT_PLACEHOLDER_MAX_LENGTH = 500;
|
|
3527
|
+
var WorkloadManifestUiHintSchema = import_zod39.z.object({
|
|
3528
|
+
displayName: import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_UI_DISPLAY_NAME_MAX_LENGTH).optional(),
|
|
3529
|
+
promptPlaceholder: import_zod39.z.string().min(1).max(WORKLOAD_MANIFEST_UI_PROMPT_PLACEHOLDER_MAX_LENGTH).optional(),
|
|
3530
|
+
enableAttachments: import_zod39.z.boolean().optional(),
|
|
3531
|
+
artifactsView: import_zod39.z.enum(["none", "panel"]).optional()
|
|
3532
|
+
}).strict();
|
|
3533
|
+
var WorkloadManifestSchema = import_zod39.z.object({
|
|
3534
|
+
apiVersion: PilotWorkloadManifestApiVersionSchema,
|
|
3535
|
+
kind: import_zod39.z.literal("Workload"),
|
|
3536
|
+
metadata: WorkloadManifestMetadataSchema,
|
|
3537
|
+
spec: import_zod39.z.object({
|
|
3538
|
+
contract: import_zod39.z.object({
|
|
3539
|
+
kind: WorkloadKindSchema
|
|
3540
|
+
}).strict(),
|
|
3541
|
+
defaults: WorkloadManifestDefaultsSchema.optional(),
|
|
3542
|
+
policyRefs: WorkloadManifestPolicyRefsSchema.optional(),
|
|
3543
|
+
ui: WorkloadManifestUiHintSchema.optional()
|
|
3544
|
+
}).strict()
|
|
3545
|
+
}).strict();
|
|
3546
|
+
var RevisionManifestStartupSchema = import_zod39.z.object({
|
|
3547
|
+
requiredGates: import_zod39.z.array(import_zod39.z.string().min(1)).optional(),
|
|
3548
|
+
optionalGates: import_zod39.z.array(import_zod39.z.string().min(1)).optional()
|
|
3549
|
+
}).strict();
|
|
3550
|
+
var RevisionManifestPublishSchema = import_zod39.z.object({
|
|
3551
|
+
setDefault: import_zod39.z.boolean().default(true)
|
|
3552
|
+
}).strict();
|
|
3553
|
+
var RevisionRuntimeEnvironmentInputSchema = RuntimeTemplateSnapshotSchema.omit({
|
|
3554
|
+
defaultWorkerEndpoint: true
|
|
3555
|
+
}).strict();
|
|
3556
|
+
var RevisionRuntimeEnvironmentOverridesSchema = RevisionRuntimeEnvironmentInputSchema.partial().strict();
|
|
3557
|
+
var RevisionRuntimeSchema = import_zod39.z.object({
|
|
3558
|
+
/**
|
|
3559
|
+
* Complete publish-time Runtime Environment input. Control-plane resolves
|
|
3560
|
+
* and freezes this into `revisions.runtime_template_snapshot_json`; DB
|
|
3561
|
+
* compatibility still records a runtime source/profile id separately.
|
|
3562
|
+
*/
|
|
3563
|
+
environment: RevisionRuntimeEnvironmentInputSchema.optional(),
|
|
3564
|
+
/**
|
|
3565
|
+
* Runtime source/profile reference. During the RuntimeTemplate
|
|
3566
|
+
* compatibility window this maps to `runtime_templates.name`.
|
|
3567
|
+
*/
|
|
3568
|
+
profileRef: WorkloadManifestObjectRefSchema.optional(),
|
|
3569
|
+
/**
|
|
3570
|
+
* Publish-time overrides applied to `profileRef`'s resolved environment.
|
|
3571
|
+
*/
|
|
3572
|
+
overrides: RevisionRuntimeEnvironmentOverridesSchema.optional()
|
|
3573
|
+
}).strict().superRefine((runtime, ctx) => {
|
|
3574
|
+
if (!runtime.environment && !runtime.profileRef) {
|
|
3575
|
+
ctx.addIssue({
|
|
3576
|
+
code: import_zod39.z.ZodIssueCode.custom,
|
|
3577
|
+
path: ["environment"],
|
|
3578
|
+
message: "runtime must provide environment or profileRef"
|
|
3579
|
+
});
|
|
3580
|
+
}
|
|
3581
|
+
if (runtime.environment && runtime.overrides) {
|
|
3582
|
+
ctx.addIssue({
|
|
3583
|
+
code: import_zod39.z.ZodIssueCode.custom,
|
|
3584
|
+
path: ["overrides"],
|
|
3585
|
+
message: "runtime.overrides is only allowed with runtime.profileRef"
|
|
3586
|
+
});
|
|
3587
|
+
}
|
|
3588
|
+
if (runtime.overrides && !runtime.profileRef) {
|
|
3589
|
+
ctx.addIssue({
|
|
3590
|
+
code: import_zod39.z.ZodIssueCode.custom,
|
|
3591
|
+
path: ["profileRef"],
|
|
3592
|
+
message: "runtime.profileRef is required when runtime.overrides is provided"
|
|
3593
|
+
});
|
|
3594
|
+
}
|
|
3595
|
+
});
|
|
3596
|
+
var RevisionManifestSpecSchema = import_zod39.z.object({
|
|
3597
|
+
runtimeTemplateRef: WorkloadManifestObjectRefSchema.optional(),
|
|
3598
|
+
runtime: RevisionRuntimeSchema.optional(),
|
|
3599
|
+
workerContract: RevisionWorkerContractRefSchema,
|
|
3600
|
+
capabilityRefs: WorkloadManifestCapabilityRefsSchema.optional(),
|
|
3601
|
+
startup: RevisionManifestStartupSchema.optional(),
|
|
3602
|
+
publish: RevisionManifestPublishSchema.default({ setDefault: true }),
|
|
3603
|
+
configValues: SessionConfigValuesSchema.optional(),
|
|
3604
|
+
policyRefs: WorkloadManifestPolicyRefsSchema.optional(),
|
|
3605
|
+
managedAgentProfileSnapshot: ManagedAgentProfileSnapshotSchema.optional()
|
|
3606
|
+
}).strict().superRefine((spec, ctx) => {
|
|
3607
|
+
var _a, _b, _c;
|
|
3608
|
+
const profileRefName = (_b = (_a = spec.runtime) == null ? void 0 : _a.profileRef) == null ? void 0 : _b.name;
|
|
3609
|
+
const legacyRuntimeTemplateRefName = (_c = spec.runtimeTemplateRef) == null ? void 0 : _c.name;
|
|
3610
|
+
if (profileRefName && legacyRuntimeTemplateRefName && profileRefName !== legacyRuntimeTemplateRefName) {
|
|
3611
|
+
ctx.addIssue({
|
|
3612
|
+
code: import_zod39.z.ZodIssueCode.custom,
|
|
3613
|
+
path: ["runtimeTemplateRef"],
|
|
3614
|
+
message: "runtimeTemplateRef must match runtime.profileRef when both compatibility refs are provided"
|
|
3615
|
+
});
|
|
3616
|
+
}
|
|
3617
|
+
if (spec.managedAgentProfileSnapshot !== void 0 && spec.workerContract.kind !== "managed_agent") {
|
|
3618
|
+
ctx.addIssue({
|
|
3619
|
+
code: import_zod39.z.ZodIssueCode.custom,
|
|
3620
|
+
path: ["managedAgentProfileSnapshot"],
|
|
3621
|
+
message: "managedAgentProfileSnapshot is only allowed for managed_agent revisions"
|
|
3622
|
+
});
|
|
3623
|
+
}
|
|
3624
|
+
});
|
|
3625
|
+
var RevisionManifestSchema = import_zod39.z.object({
|
|
3626
|
+
apiVersion: PilotWorkloadManifestApiVersionSchema,
|
|
3627
|
+
kind: import_zod39.z.literal("Revision"),
|
|
3628
|
+
metadata: RevisionManifestMetadataSchema,
|
|
3629
|
+
spec: RevisionManifestSpecSchema
|
|
3630
|
+
}).strict();
|
|
3631
|
+
var PilotWorkloadManifestSchema = import_zod39.z.discriminatedUnion("kind", [
|
|
3632
|
+
WorkloadManifestSchema,
|
|
3633
|
+
RevisionManifestSchema
|
|
3634
|
+
]);
|
|
3635
|
+
var MANAGED_AGENT_PROFILE_KIND = "ManagedAgentProfile";
|
|
3636
|
+
var ManagedAgentProfileMetadataSchema = import_zod38.z.object({
|
|
3637
|
+
name: WorkloadManifestNameSchema,
|
|
3638
|
+
displayName: WorkloadManifestDisplayNameSchema,
|
|
3639
|
+
labels: import_zod38.z.record(import_zod38.z.string()).optional(),
|
|
3640
|
+
annotations: import_zod38.z.record(import_zod38.z.string()).optional()
|
|
3641
|
+
}).strict();
|
|
3642
|
+
var ManagedAgentProfileSpecSchema = import_zod38.z.object({
|
|
3643
|
+
runtimeTemplateRef: WorkloadManifestObjectRefSchema,
|
|
3644
|
+
env: SessionConfigValuesSchema.optional(),
|
|
3645
|
+
ui: WorkloadManifestUiHintSchema.optional(),
|
|
3646
|
+
// Phase B (🟡): workload-level default model id. Projected to
|
|
3647
|
+
// `manifest.spec.defaults.model`, persisted in
|
|
3648
|
+
// `workloads.manifest_defaults_json`, and read at session creation as
|
|
3649
|
+
// the default for `sessions.metadata.model` when the caller does not
|
|
3650
|
+
// pin one. See `specs/features/pilot-v2-managed-agent-profile.md`
|
|
3651
|
+
// §"Phase B" for the resolution order.
|
|
3652
|
+
model: WorkloadManifestModelSchema.optional(),
|
|
3653
|
+
// Phase C (🟡): workload-level default enabled skills as friendly rush
|
|
3654
|
+
// skill names (e.g. `@kanyun/data-analysis-skills`). Projected to
|
|
3655
|
+
// `manifest.spec.defaults.enabledSkills` as `EnabledSkillRef[]`,
|
|
3656
|
+
// resolved to full snapshots at `POST /api/workloads`, and seeded into
|
|
3657
|
+
// `agents.enabled_skills` at agent creation when the caller omits
|
|
3658
|
+
// skills. See `specs/features/pilot-v2-managed-agent-profile.md`
|
|
3659
|
+
// §"Phase C".
|
|
3660
|
+
skills: import_zod38.z.array(import_zod38.z.string().min(1)).optional(),
|
|
3661
|
+
// Phase C2/C3 (🟡): workload-level default MCP servers as friendly rush
|
|
3662
|
+
// MCP ids (e.g. `github`). Projected to
|
|
3663
|
+
// `manifest.spec.defaults.enabledMcpServers` as `EnabledMcpRef[]`. At
|
|
3664
|
+
// `POST /api/workloads` each ref resolves by credential need:
|
|
3665
|
+
// credential-free templates freeze into `EnabledMcpServer` snapshots
|
|
3666
|
+
// (C2); credentialed templates persist as bare refs resolved per running
|
|
3667
|
+
// user at bootstrap (C3). Seeded into `agents.enabled_mcp_servers` at
|
|
3668
|
+
// agent creation when the caller omits MCP servers. See
|
|
3669
|
+
// `specs/features/pilot-v2-managed-agent-profile.md` §"Phase C".
|
|
3670
|
+
mcpServers: import_zod38.z.array(import_zod38.z.string().min(1)).optional(),
|
|
3671
|
+
// Phase D: workload-level default system prompt. Projected to
|
|
3672
|
+
// `manifest.spec.defaults.systemPrompt`, seeded onto
|
|
3673
|
+
// `agents.system_prompt` at agent creation, and forwarded per-run as
|
|
3674
|
+
// `PilotCoderRunConfigV1.systemPrompt`. agent-worker uses it instead of
|
|
3675
|
+
// the platform-level `SYSTEM_PROMPT` fallback. See
|
|
3676
|
+
// `specs/features/pilot-v2-managed-agent-profile.md` §"Phase D".
|
|
3677
|
+
systemPrompt: WorkloadManifestSystemPromptSchema.optional()
|
|
3678
|
+
}).strict();
|
|
3679
|
+
var ManagedAgentProfileSchema = import_zod38.z.object({
|
|
3680
|
+
apiVersion: PilotWorkloadManifestApiVersionSchema,
|
|
3681
|
+
kind: import_zod38.z.literal(MANAGED_AGENT_PROFILE_KIND),
|
|
3682
|
+
metadata: ManagedAgentProfileMetadataSchema,
|
|
3683
|
+
spec: ManagedAgentProfileSpecSchema
|
|
3684
|
+
}).strict();
|
|
3685
|
+
var PlatformProjectSchema = import_zod40.z.object({
|
|
3686
|
+
id: import_zod40.z.string().uuid(),
|
|
3687
|
+
slug: WorkloadManifestNameSchema,
|
|
3688
|
+
displayName: WorkloadManifestDisplayNameSchema,
|
|
3689
|
+
description: import_zod40.z.string().nullable().optional(),
|
|
3690
|
+
defaultRuntimeTemplateRefName: WorkloadManifestRefNameSchema.nullable().optional(),
|
|
3691
|
+
createdAt: import_zod40.z.string().optional(),
|
|
3692
|
+
updatedAt: import_zod40.z.string().optional()
|
|
3693
|
+
}).strict();
|
|
3694
|
+
var CreatePlatformProjectRequestSchema = import_zod40.z.object({
|
|
3695
|
+
slug: WorkloadManifestNameSchema,
|
|
3696
|
+
displayName: WorkloadManifestDisplayNameSchema,
|
|
3697
|
+
description: import_zod40.z.string().max(2e3).optional(),
|
|
3698
|
+
defaultRuntimeTemplateRefName: WorkloadManifestRefNameSchema.optional()
|
|
3699
|
+
}).strict();
|
|
3700
|
+
var ListPlatformProjectsResponseSchema = import_zod40.z.object({
|
|
3701
|
+
projects: import_zod40.z.array(PlatformProjectSchema)
|
|
3702
|
+
}).strict();
|
|
3703
|
+
var PlatformWorkloadDefaultsSchema = import_zod40.z.object({
|
|
3704
|
+
workerContract: WorkloadManifestWorkerContractDefaultsSchema.optional(),
|
|
3705
|
+
configValues: SessionConfigValuesSchema.optional(),
|
|
3706
|
+
model: import_zod40.z.string().min(1).max(255).optional(),
|
|
3707
|
+
systemPrompt: import_zod40.z.string().min(1).max(32768).optional(),
|
|
3708
|
+
enabledSkills: EnabledSkillEntryListSchema.optional(),
|
|
3709
|
+
enabledMcpServers: EnabledMcpEntryListSchema.optional()
|
|
3710
|
+
}).strict();
|
|
3711
|
+
var CreatePlatformWorkloadRequestSchema = import_zod40.z.object({
|
|
3712
|
+
projectId: import_zod40.z.string().uuid(),
|
|
3713
|
+
slug: WorkloadManifestNameSchema,
|
|
3714
|
+
displayName: WorkloadManifestDisplayNameSchema,
|
|
3715
|
+
kind: ActiveWorkloadKindSchema,
|
|
3716
|
+
defaults: PlatformWorkloadDefaultsSchema.optional(),
|
|
3717
|
+
ui: WorkloadManifestUiHintSchema.optional()
|
|
3718
|
+
}).strict();
|
|
3719
|
+
var PlatformWorkloadSchema = import_zod40.z.object({
|
|
3720
|
+
id: import_zod40.z.string().uuid(),
|
|
3721
|
+
projectId: import_zod40.z.string().uuid(),
|
|
3722
|
+
slug: WorkloadManifestNameSchema,
|
|
3723
|
+
displayName: WorkloadManifestDisplayNameSchema,
|
|
3724
|
+
kind: ActiveWorkloadKindSchema,
|
|
3725
|
+
defaultRevisionId: import_zod40.z.string().uuid().nullable().optional(),
|
|
3726
|
+
createdAt: import_zod40.z.string().optional(),
|
|
3727
|
+
updatedAt: import_zod40.z.string().optional()
|
|
3728
|
+
}).strict();
|
|
3729
|
+
var PublishPlatformRevisionWorkerContractSchema = import_zod40.z.object({
|
|
3730
|
+
kind: ActiveWorkloadKindSchema,
|
|
3731
|
+
name: WorkloadManifestRefNameSchema.optional(),
|
|
3732
|
+
version: import_zod40.z.string().min(1).max(100).optional()
|
|
3733
|
+
}).strict();
|
|
3734
|
+
var PublishPlatformRevisionRequestSchema = import_zod40.z.object({
|
|
3735
|
+
projectId: import_zod40.z.string().uuid(),
|
|
3736
|
+
workloadSlug: WorkloadManifestNameSchema,
|
|
3737
|
+
version: WorkloadManifestNameSchema,
|
|
3738
|
+
workerContract: PublishPlatformRevisionWorkerContractSchema,
|
|
3739
|
+
setDefault: import_zod40.z.boolean().default(true),
|
|
3740
|
+
startup: import_zod40.z.object({
|
|
3741
|
+
requiredGates: import_zod40.z.array(import_zod40.z.string().min(1)).optional(),
|
|
3742
|
+
optionalGates: import_zod40.z.array(import_zod40.z.string().min(1)).optional()
|
|
3743
|
+
}).strict().optional(),
|
|
3744
|
+
configValues: SessionConfigValuesSchema.optional(),
|
|
3745
|
+
managedAgentProfileSnapshot: ManagedAgentProfileSnapshotSchema.optional(),
|
|
3746
|
+
runtime: RevisionRuntimeSchema.optional()
|
|
3747
|
+
}).strict();
|
|
3748
|
+
var PlatformRevisionSchema = import_zod40.z.object({
|
|
3749
|
+
id: import_zod40.z.string().uuid(),
|
|
3750
|
+
projectId: import_zod40.z.string().uuid(),
|
|
3751
|
+
workloadId: import_zod40.z.string().uuid(),
|
|
3752
|
+
workloadSlug: WorkloadManifestNameSchema.optional(),
|
|
3753
|
+
version: WorkloadManifestNameSchema,
|
|
3754
|
+
runtimeSnapshotHash: import_zod40.z.string().nullable().optional(),
|
|
3755
|
+
createdAt: import_zod40.z.string().optional()
|
|
3756
|
+
}).strict();
|
|
3757
|
+
var GetPlatformSessionResponseSchema = import_zod40.z.object({
|
|
3758
|
+
id: import_zod40.z.string().uuid(),
|
|
3759
|
+
projectId: import_zod40.z.string().uuid(),
|
|
3760
|
+
workloadId: import_zod40.z.string().uuid(),
|
|
3761
|
+
revisionId: import_zod40.z.string().uuid(),
|
|
3762
|
+
status: SessionStatusSchema,
|
|
3763
|
+
createdAt: import_zod40.z.string().optional(),
|
|
3764
|
+
updatedAt: import_zod40.z.string().optional()
|
|
3765
|
+
}).strict();
|
|
3766
|
+
var CreatePlatformSessionRequestSchema = CreateSessionRequestSchema;
|
|
3767
|
+
var CreatePlatformSessionResponseSchema = CreateSessionResponseSchema;
|
|
3768
|
+
function platformWorkloadCreateToManifest(input) {
|
|
3769
|
+
const defaults = input.defaults ? omitUndefined(input.defaults) : void 0;
|
|
3770
|
+
return WorkloadManifestSchema.parse({
|
|
3771
|
+
apiVersion: PILOT_WORKLOAD_MANIFEST_API_VERSION,
|
|
3772
|
+
kind: "Workload",
|
|
3773
|
+
metadata: {
|
|
3774
|
+
name: input.slug,
|
|
3775
|
+
displayName: input.displayName
|
|
3776
|
+
},
|
|
3777
|
+
spec: __spreadValues(__spreadValues({
|
|
3778
|
+
contract: { kind: input.kind }
|
|
3779
|
+
}, defaults ? { defaults } : {}), input.ui ? { ui: input.ui } : {})
|
|
3780
|
+
});
|
|
3781
|
+
}
|
|
3782
|
+
function omitUndefined(input) {
|
|
3783
|
+
return Object.fromEntries(
|
|
3784
|
+
Object.entries(input).filter((entry) => entry[1] !== void 0)
|
|
3785
|
+
);
|
|
3786
|
+
}
|
|
3787
|
+
function platformRevisionPublishToManifest(input) {
|
|
3788
|
+
return RevisionManifestSchema.parse({
|
|
3789
|
+
apiVersion: PILOT_WORKLOAD_MANIFEST_API_VERSION,
|
|
3790
|
+
kind: "Revision",
|
|
3791
|
+
metadata: {
|
|
3792
|
+
name: input.version,
|
|
3793
|
+
workload: input.workloadSlug
|
|
3794
|
+
},
|
|
3795
|
+
spec: __spreadValues(__spreadValues(__spreadValues(__spreadProps(__spreadValues({}, input.runtime ? { runtime: input.runtime } : {}), {
|
|
3796
|
+
workerContract: input.workerContract,
|
|
3797
|
+
publish: RevisionManifestPublishSchema.parse({ setDefault: input.setDefault })
|
|
3798
|
+
}), input.startup ? { startup: input.startup } : {}), input.configValues ? { configValues: input.configValues } : {}), input.managedAgentProfileSnapshot ? { managedAgentProfileSnapshot: input.managedAgentProfileSnapshot } : {})
|
|
3799
|
+
});
|
|
3800
|
+
}
|
|
3801
|
+
var PilotCoderSkillsInstallSchema = import_zod41.z.object({
|
|
3802
|
+
gitlabDomain: import_zod41.z.string().optional(),
|
|
3803
|
+
gitlabToken: import_zod41.z.string().optional(),
|
|
3804
|
+
githubToken: import_zod41.z.string().optional()
|
|
3805
|
+
}).strict();
|
|
3806
|
+
var PilotCoderTriggerRefSchema = import_zod41.z.discriminatedUnion("type", [
|
|
3807
|
+
import_zod41.z.object({
|
|
3808
|
+
type: import_zod41.z.literal("github_issue"),
|
|
3809
|
+
number: import_zod41.z.number().int().positive(),
|
|
3810
|
+
commentId: import_zod41.z.number().int().positive().optional()
|
|
3811
|
+
}).strict(),
|
|
3812
|
+
import_zod41.z.object({
|
|
3813
|
+
type: import_zod41.z.literal("github_pr"),
|
|
3814
|
+
number: import_zod41.z.number().int().positive(),
|
|
3815
|
+
commentId: import_zod41.z.number().int().positive().optional()
|
|
3816
|
+
}).strict(),
|
|
3817
|
+
import_zod41.z.object({
|
|
3818
|
+
type: import_zod41.z.literal("gitlab_issue"),
|
|
3819
|
+
iid: import_zod41.z.number().int().positive(),
|
|
3820
|
+
noteId: import_zod41.z.number().int().positive().optional()
|
|
3821
|
+
}).strict(),
|
|
3822
|
+
import_zod41.z.object({
|
|
3823
|
+
type: import_zod41.z.literal("gitlab_mr"),
|
|
3824
|
+
iid: import_zod41.z.number().int().positive(),
|
|
3825
|
+
noteId: import_zod41.z.number().int().positive().optional()
|
|
3826
|
+
}).strict(),
|
|
3827
|
+
import_zod41.z.object({
|
|
3828
|
+
type: import_zod41.z.literal("jira_issue"),
|
|
3829
|
+
key: import_zod41.z.string().min(1)
|
|
3830
|
+
}).strict(),
|
|
3831
|
+
import_zod41.z.object({
|
|
3832
|
+
type: import_zod41.z.literal("schedule"),
|
|
3833
|
+
scheduleId: import_zod41.z.string().min(1)
|
|
3834
|
+
}).strict(),
|
|
3835
|
+
import_zod41.z.object({
|
|
3836
|
+
type: import_zod41.z.literal("opaque"),
|
|
3837
|
+
value: import_zod41.z.string().min(1)
|
|
3838
|
+
}).strict()
|
|
3839
|
+
]);
|
|
3840
|
+
var PilotCoderRunConfigV1Schema = import_zod41.z.object({
|
|
3841
|
+
runId: import_zod41.z.string().min(1),
|
|
3842
|
+
agentId: import_zod41.z.string().min(1),
|
|
3843
|
+
provider: ProviderTypeSchema.optional(),
|
|
3844
|
+
model: import_zod41.z.string().optional(),
|
|
3845
|
+
/**
|
|
3846
|
+
* Phase D — per-agent system prompt. Sourced by control-worker from
|
|
3847
|
+
* `agents.system_prompt` (seeded from a managed_agent profile's
|
|
3848
|
+
* `spec.systemPrompt` workload default). When present, agent-worker
|
|
3849
|
+
* uses it verbatim as the LLM `system` prompt **instead of** the
|
|
3850
|
+
* platform-level `SYSTEM_PROMPT` / `SYSTEM_PROMPT_GENERAL` fallback
|
|
3851
|
+
* (`getSystemPrompt(projectKind)`); when absent the platform default
|
|
3852
|
+
* is used, so v1 payloads stay backward-compatible.
|
|
3853
|
+
*
|
|
3854
|
+
* Routed per-run via the dispatch payload (not worker env) so multiple
|
|
3855
|
+
* workloads sharing a pod stay cleanly isolated. Deployment ordering:
|
|
3856
|
+
* contracts ship first (both control-worker and agent-worker must
|
|
3857
|
+
* recognize this key before control-worker starts populating it), since
|
|
3858
|
+
* `PilotCoderRunConfigV1Schema` is `.strict()`.
|
|
3859
|
+
*/
|
|
3860
|
+
systemPrompt: import_zod41.z.string().min(1).optional(),
|
|
3861
|
+
workspacePath: import_zod41.z.string().optional(),
|
|
3862
|
+
mcpConfigDir: import_zod41.z.string().optional(),
|
|
3863
|
+
attachments: import_zod41.z.array(AttachmentMetaSchema).max(5).optional(),
|
|
3864
|
+
triggerContext: WebhookTriggerContextSchema.optional(),
|
|
3865
|
+
mcpServers: McpServersMapSchema.optional(),
|
|
3866
|
+
env: import_zod41.z.record(import_zod41.z.string(), import_zod41.z.string()).optional(),
|
|
3867
|
+
projectKind: ProjectKindSchema.optional(),
|
|
3868
|
+
/**
|
|
3869
|
+
* v2-only — resolved skill artifact list, populated by
|
|
3870
|
+
* control-plane `v2McpResolve` (see `apps/control-worker/src/worker.ts`).
|
|
3871
|
+
* Each entry MUST be fully resolved (i.e. the legacy `EnabledSkill`
|
|
3872
|
+
* shape with `resolvedArtifact`) — refs (`EnabledSkillRef`) are
|
|
3873
|
+
* lookup-time-only and never travel on the wire.
|
|
3874
|
+
*
|
|
3875
|
+
* Agent-worker `run-agent-loop.ts` consumes this list and invokes
|
|
3876
|
+
* `@pilot/skills` `ensureSkillsInstalled` to materialize each
|
|
3877
|
+
* skill under `$HOME/.claude/skills/<dir>/` (claude-code provider)
|
|
3878
|
+
* or `$HOME/.codex/skills/<dir>/` (codex provider) before the LLM
|
|
3879
|
+
* loop spins up.
|
|
3880
|
+
*
|
|
3881
|
+
* In v1 this work was done by `mcpSkillsBootstrap` against the
|
|
3882
|
+
* sandbox SDK; v2 sandboxes live in a separate namespace and that
|
|
3883
|
+
* SDK 404s on them, so installation moved into the in-sandbox
|
|
3884
|
+
* agent-worker process. See `specs/features/pilot-v2-sdk-worker-substrate-api.md`
|
|
3885
|
+
* for the namespace rationale.
|
|
3886
|
+
*/
|
|
3887
|
+
skills: import_zod41.z.array(EnabledSkillSchema).optional(),
|
|
3888
|
+
skillsInstall: PilotCoderSkillsInstallSchema.optional(),
|
|
3889
|
+
/**
|
|
3890
|
+
* P3 L3.3 — delivery-related fields populated by control-worker from
|
|
3891
|
+
* `runs.*` / `agents.*` columns so the worker delivery loop can act
|
|
3892
|
+
* without re-querying control-plane. All fields are optional: v1
|
|
3893
|
+
* payloads predate L3.3 and senders without delivery (e.g. interactive
|
|
3894
|
+
* chat sessions) MUST still encode successfully.
|
|
3895
|
+
*
|
|
3896
|
+
* `repoUrl` mirrors `runs.repo_url` (nullable; omitted when null).
|
|
3897
|
+
* `baseBranch` is the PR/MR target branch (sourced from
|
|
3898
|
+
* `agents.base_ref` or `runs.target_ref` per dispatch site choice).
|
|
3899
|
+
* `triggerSource` mirrors `runs.trigger_source`. `triggerRef` is the
|
|
3900
|
+
* structured / parsed form of `runs.trigger_ref`. `prTitle` /
|
|
3901
|
+
* `prTemplate` are user / trigger-source specified overrides for the
|
|
3902
|
+
* delivery PR description; if neither column / setting exists yet on
|
|
3903
|
+
* the v1 data model, the dispatcher omits them (forward-compat).
|
|
3904
|
+
*/
|
|
3905
|
+
repoUrl: import_zod41.z.string().min(1).optional(),
|
|
3906
|
+
baseBranch: import_zod41.z.string().min(1).optional(),
|
|
3907
|
+
triggerSource: TriggerSourceSchema.optional(),
|
|
3908
|
+
triggerRef: PilotCoderTriggerRefSchema.optional(),
|
|
3909
|
+
prTitle: import_zod41.z.string().min(1).optional(),
|
|
3910
|
+
prTemplate: import_zod41.z.string().min(1).optional()
|
|
3911
|
+
}).strict();
|
|
3912
|
+
var PilotCoderPromptPayloadV1Schema = import_zod41.z.object({
|
|
3913
|
+
schemaVersion: import_zod41.z.literal("v1"),
|
|
3914
|
+
kind: import_zod41.z.literal("prompt"),
|
|
3915
|
+
prompt: import_zod41.z.string().min(1),
|
|
3916
|
+
config: PilotCoderRunConfigV1Schema
|
|
3917
|
+
}).strict();
|
|
3918
|
+
var PilotCoderFollowupPayloadV1Schema = import_zod41.z.object({
|
|
3919
|
+
schemaVersion: import_zod41.z.literal("v1"),
|
|
3920
|
+
kind: import_zod41.z.literal("followup"),
|
|
3921
|
+
message: import_zod41.z.string().min(1),
|
|
3922
|
+
config: PilotCoderRunConfigV1Schema,
|
|
3923
|
+
expectedMessagesHash: import_zod41.z.string().optional(),
|
|
3924
|
+
expectedMessagesCount: import_zod41.z.number().int().nonnegative().optional()
|
|
3925
|
+
}).strict();
|
|
3926
|
+
var PilotCoderRestorePayloadV1Schema = import_zod41.z.object({
|
|
3927
|
+
schemaVersion: import_zod41.z.literal("v1"),
|
|
3928
|
+
kind: import_zod41.z.literal("restore"),
|
|
3929
|
+
config: PilotCoderRunConfigV1Schema,
|
|
3930
|
+
messages: import_zod41.z.array(import_zod41.z.unknown()),
|
|
3931
|
+
messagesHash: import_zod41.z.string().min(1),
|
|
3932
|
+
lastEventId: import_zod41.z.number().int().nonnegative().optional(),
|
|
3933
|
+
pendingToolCalls: import_zod41.z.array(import_zod41.z.unknown()).optional(),
|
|
3934
|
+
workspaceHydrationRef: import_zod41.z.string().optional(),
|
|
3935
|
+
runtimeProfileSnapshot: import_zod41.z.record(import_zod41.z.unknown()).optional(),
|
|
3936
|
+
degradedRecovery: import_zod41.z.boolean().optional()
|
|
3937
|
+
}).strict();
|
|
3938
|
+
var GatewayErrorCodeSchema = import_zod42.z.enum([
|
|
3939
|
+
"gateway_invalid_session_token",
|
|
3940
|
+
"gateway_session_not_found",
|
|
3941
|
+
"gateway_missing_mcp_target",
|
|
3942
|
+
"gateway_invalid_mcp_target",
|
|
3943
|
+
"gateway_invalid_mcp_method",
|
|
3944
|
+
"gateway_not_a_mcp_path",
|
|
3945
|
+
"gateway_mcp_target_not_allowed",
|
|
3946
|
+
"gateway_vault_unreachable",
|
|
3947
|
+
"gateway_credential_refresh_failed",
|
|
3948
|
+
"gateway_credential_refresh_timeout",
|
|
3949
|
+
"gateway_upstream_unreachable",
|
|
3950
|
+
"gateway_upstream_error",
|
|
3951
|
+
"gateway_upstream_timeout",
|
|
3952
|
+
"gateway_request_too_large",
|
|
3953
|
+
"gateway_response_too_large"
|
|
3954
|
+
]);
|
|
3955
|
+
var WebhookEventTypeSchema = import_zod43.z.enum([
|
|
3956
|
+
/** v1/v2 Run reached terminal `completed`. */
|
|
3957
|
+
"run.completed",
|
|
3958
|
+
/** v1/v2 Run reached terminal `failed`. */
|
|
3959
|
+
"run.failed",
|
|
3960
|
+
/** v2 Session startup reached terminal `ready`. */
|
|
3961
|
+
"session.status_ready",
|
|
3962
|
+
/** v2 Session startup reached terminal `failed`. */
|
|
3963
|
+
"session.status_failed",
|
|
3964
|
+
/** v2 Session post-ready lifecycle entered `idle`. */
|
|
3965
|
+
"session.lifecycle_idle",
|
|
3966
|
+
/** v2 Session post-ready lifecycle entered `terminating`. */
|
|
3967
|
+
"session.lifecycle_terminating",
|
|
3968
|
+
/** v2 Session post-ready lifecycle reached `terminated`. */
|
|
3969
|
+
"session.lifecycle_terminated"
|
|
3970
|
+
]);
|
|
3971
|
+
var WEBHOOK_EVENT_TYPES = WebhookEventTypeSchema.options;
|
|
3972
|
+
var WebhookEventPayloadSchema = import_zod43.z.object({
|
|
3973
|
+
event_id: import_zod43.z.string().min(1).max(255),
|
|
3974
|
+
event_type: WebhookEventTypeSchema,
|
|
3975
|
+
/** ISO-8601 instant at which the transition was recorded. */
|
|
3976
|
+
occurred_at: import_zod43.z.string(),
|
|
3977
|
+
project_id: import_zod43.z.string().uuid(),
|
|
3978
|
+
run_id: import_zod43.z.string().uuid().optional(),
|
|
3979
|
+
agent_id: import_zod43.z.string().uuid().optional(),
|
|
3980
|
+
session_id: import_zod43.z.string().uuid().optional(),
|
|
3981
|
+
lifecycle_phase: import_zod43.z.enum(["idle", "terminating", "terminated"]).optional(),
|
|
3982
|
+
lifecycle_transition_id: import_zod43.z.string().uuid().optional(),
|
|
3983
|
+
idle_since: import_zod43.z.string().optional(),
|
|
3984
|
+
grace_deadline: import_zod43.z.string().optional(),
|
|
3985
|
+
reason: import_zod43.z.string().optional(),
|
|
3986
|
+
terminate_deadline: import_zod43.z.string().optional()
|
|
3987
|
+
}).strict();
|
|
3988
|
+
var WebhookSubscriptionStatusSchema = import_zod43.z.enum(["active", "disabled"]);
|
|
3989
|
+
var CreateWebhookSubscriptionRequestSchema = import_zod43.z.object({
|
|
3990
|
+
projectId: import_zod43.z.string().uuid(),
|
|
3991
|
+
/** Subscriber endpoint. https required outside dev; SSRF-validated. */
|
|
3992
|
+
url: import_zod43.z.string().url().max(1024),
|
|
3993
|
+
/** Event types to deliver. At least one. */
|
|
3994
|
+
events: import_zod43.z.array(WebhookEventTypeSchema).min(1).max(WEBHOOK_EVENT_TYPES.length),
|
|
3995
|
+
/** Optional operator note shown in list responses. */
|
|
3996
|
+
description: import_zod43.z.string().max(512).optional()
|
|
3997
|
+
}).strict();
|
|
3998
|
+
var UpdateWebhookSubscriptionRequestSchema = import_zod43.z.object({
|
|
3999
|
+
url: import_zod43.z.string().url().max(1024).optional(),
|
|
4000
|
+
events: import_zod43.z.array(WebhookEventTypeSchema).min(1).max(WEBHOOK_EVENT_TYPES.length).optional(),
|
|
4001
|
+
description: import_zod43.z.string().max(512).nullable().optional(),
|
|
4002
|
+
/**
|
|
4003
|
+
* `active` re-enables a subscription that was auto-disabled after
|
|
4004
|
+
* consecutive failures (resets the failure counter); `disabled`
|
|
4005
|
+
* pauses delivery without deleting history.
|
|
4006
|
+
*/
|
|
4007
|
+
status: WebhookSubscriptionStatusSchema.optional()
|
|
4008
|
+
}).strict().refine(
|
|
4009
|
+
(data) => data.url !== void 0 || data.events !== void 0 || data.description !== void 0 || data.status !== void 0,
|
|
4010
|
+
{ message: "At least one of url / events / description / status MUST be provided" }
|
|
4011
|
+
);
|
|
4012
|
+
var WebhookSubscriptionSchema = import_zod43.z.object({
|
|
4013
|
+
id: import_zod43.z.string().uuid(),
|
|
4014
|
+
projectId: import_zod43.z.string().uuid(),
|
|
4015
|
+
url: import_zod43.z.string(),
|
|
4016
|
+
events: import_zod43.z.array(WebhookEventTypeSchema),
|
|
4017
|
+
description: import_zod43.z.string().nullable(),
|
|
4018
|
+
status: WebhookSubscriptionStatusSchema,
|
|
4019
|
+
consecutiveFailures: import_zod43.z.number().int().nonnegative(),
|
|
4020
|
+
createdBy: import_zod43.z.string(),
|
|
4021
|
+
createdAt: import_zod43.z.string(),
|
|
4022
|
+
updatedAt: import_zod43.z.string()
|
|
4023
|
+
});
|
|
4024
|
+
var WebhookSubscriptionWithSecretSchema = import_zod43.z.object({
|
|
4025
|
+
subscription: WebhookSubscriptionSchema,
|
|
4026
|
+
secret: import_zod43.z.string()
|
|
4027
|
+
});
|
|
4028
|
+
var WebhookSubscriptionErrorCodeSchema = import_zod43.z.enum([
|
|
4029
|
+
// 400
|
|
4030
|
+
"VALIDATION_ERROR",
|
|
4031
|
+
/** URL failed SSRF policy (non-https, private/loopback/link-local IP…). */
|
|
4032
|
+
"WEBHOOK_URL_FORBIDDEN",
|
|
4033
|
+
// 404
|
|
4034
|
+
"SUBSCRIPTION_NOT_FOUND",
|
|
4035
|
+
"PROJECT_NOT_FOUND",
|
|
4036
|
+
// 409
|
|
4037
|
+
"SUBSCRIPTION_LIMIT_EXCEEDED",
|
|
4038
|
+
// 500
|
|
4039
|
+
"INTERNAL_ERROR"
|
|
4040
|
+
]);
|
|
4041
|
+
var SessionPrewarmingIdentitySchema = import_zod44.z.object({
|
|
4042
|
+
projectIdGenerator: import_zod44.z.literal("nanoid"),
|
|
4043
|
+
claimNameTemplate: import_zod44.z.string().min(1),
|
|
4044
|
+
idempotencyScopePrefix: import_zod44.z.string().min(1)
|
|
4045
|
+
}).strict();
|
|
4046
|
+
var SessionPrewarmingSessionTemplateSchema = import_zod44.z.object({
|
|
4047
|
+
configValues: import_zod44.z.record(import_zod44.z.string(), import_zod44.z.string()),
|
|
4048
|
+
metadata: import_zod44.z.record(import_zod44.z.string(), import_zod44.z.unknown()).optional()
|
|
4049
|
+
}).strict();
|
|
4050
|
+
var BusinessReadyProbeSchema = import_zod44.z.object({
|
|
4051
|
+
endpointName: import_zod44.z.enum(["api", "preview"]),
|
|
4052
|
+
path: import_zod44.z.string().min(1),
|
|
4053
|
+
successCodes: import_zod44.z.array(import_zod44.z.number().int().min(100).max(599)).min(1),
|
|
4054
|
+
timeoutMs: import_zod44.z.number().int().min(500).max(3e4)
|
|
4055
|
+
}).strict();
|
|
4056
|
+
var SessionPrewarmingSpecSchema = import_zod44.z.object({
|
|
4057
|
+
targetReadyCount: import_zod44.z.number().int().min(1).max(50),
|
|
4058
|
+
reVerifyIntervalSeconds: import_zod44.z.number().int().min(60).max(3600),
|
|
4059
|
+
warmingTimeoutSeconds: import_zod44.z.number().int().min(60).max(600),
|
|
4060
|
+
claimingLeaseTtlSeconds: import_zod44.z.number().int().min(10).max(120),
|
|
4061
|
+
replenishIntervalSeconds: import_zod44.z.number().int().min(5).max(300),
|
|
4062
|
+
maxConcurrentWarming: import_zod44.z.number().int().min(1).max(10),
|
|
4063
|
+
identity: SessionPrewarmingIdentitySchema,
|
|
4064
|
+
sessionTemplate: SessionPrewarmingSessionTemplateSchema,
|
|
4065
|
+
businessReadyProbe: BusinessReadyProbeSchema.optional()
|
|
4066
|
+
}).strict();
|
|
4067
|
+
var AcquireSessionRequestSchema = import_zod44.z.object({
|
|
4068
|
+
workloadId: import_zod44.z.string().uuid(),
|
|
4069
|
+
clientMutationId: import_zod44.z.string().min(1).max(255)
|
|
4070
|
+
}).strict();
|
|
4071
|
+
var AcquireSessionResponseSchema = import_zod44.z.object({
|
|
4072
|
+
leaseToken: import_zod44.z.string().min(1),
|
|
4073
|
+
leaseExpiresAt: import_zod44.z.string().datetime(),
|
|
4074
|
+
sessionId: import_zod44.z.string().uuid(),
|
|
4075
|
+
projectId: import_zod44.z.string().min(1),
|
|
4076
|
+
runtimeClaimName: import_zod44.z.string().min(1),
|
|
4077
|
+
configValues: import_zod44.z.record(import_zod44.z.string(), import_zod44.z.string()),
|
|
4078
|
+
apiUrl: import_zod44.z.string().url(),
|
|
4079
|
+
previewUrl: import_zod44.z.string().url().optional()
|
|
4080
|
+
}).strict();
|
|
4081
|
+
var FinalizeAcquireRequestSchema = import_zod44.z.object({
|
|
4082
|
+
leaseToken: import_zod44.z.string().min(1),
|
|
4083
|
+
sessionId: import_zod44.z.string().uuid(),
|
|
4084
|
+
clientMutationId: import_zod44.z.string().min(1).max(255).optional()
|
|
4085
|
+
}).strict();
|
|
4086
|
+
var AbortAcquireRequestSchema = import_zod44.z.object({
|
|
4087
|
+
leaseToken: import_zod44.z.string().min(1),
|
|
4088
|
+
sessionId: import_zod44.z.string().uuid()
|
|
4089
|
+
}).strict();
|
|
4090
|
+
var WorkloadLifecycleKindSchema = import_zod45.z.enum(["managed_agent", "self_managed"]);
|
|
4091
|
+
var WorkloadLifecycleConfigSchema = import_zod45.z.object({
|
|
4092
|
+
idleEnabled: import_zod45.z.boolean().nullable(),
|
|
4093
|
+
idleAfterSeconds: import_zod45.z.number().int().min(300).max(86400).nullable(),
|
|
4094
|
+
idleGraceSeconds: import_zod45.z.number().int().min(60).max(3600).nullable(),
|
|
4095
|
+
maxSessionLifetimeMs: import_zod45.z.number().int().min(36e5).max(6048e5).nullable()
|
|
4096
|
+
}).strict();
|
|
4097
|
+
var WorkloadLifecycleConfigUpdateSchema = WorkloadLifecycleConfigSchema.partial().strict();
|
|
4098
|
+
var EffectiveWorkloadLifecycleConfigSchema = import_zod45.z.object({
|
|
4099
|
+
idleEnabled: import_zod45.z.boolean(),
|
|
4100
|
+
idleAfterSeconds: import_zod45.z.number().int().min(300).max(86400),
|
|
4101
|
+
idleGraceSeconds: import_zod45.z.number().int().min(60).max(3600),
|
|
4102
|
+
maxSessionLifetimeMs: import_zod45.z.number().int().min(36e5).max(6048e5)
|
|
4103
|
+
}).strict();
|
|
4104
|
+
var WorkloadLifecycleConfigResponseSchema = import_zod45.z.object({
|
|
4105
|
+
workloadId: import_zod45.z.string().uuid(),
|
|
4106
|
+
kind: WorkloadLifecycleKindSchema,
|
|
4107
|
+
config: WorkloadLifecycleConfigSchema,
|
|
4108
|
+
effective: EffectiveWorkloadLifecycleConfigSchema
|
|
4109
|
+
}).strict();
|
|
4110
|
+
var UuidSchema = import_zod46.z.string().uuid();
|
|
4111
|
+
var NonEmptyUuidArraySchema = import_zod46.z.array(UuidSchema).min(1).max(200);
|
|
4112
|
+
var CleanupPrefixSchema = import_zod46.z.string().trim().min(5).max(128).regex(
|
|
4113
|
+
/^(?:e2e|tmp|test|cc)-[A-Za-z0-9][A-Za-z0-9._:-]*$/,
|
|
4114
|
+
"prefix must start with an allowed cleanup namespace: e2e-, tmp-, test-, or cc-"
|
|
4115
|
+
);
|
|
4116
|
+
var SessionTerminateRequestSchema = import_zod46.z.object({
|
|
4117
|
+
reason: import_zod46.z.string().trim().min(1).max(50).default("api"),
|
|
4118
|
+
deadlineAt: import_zod46.z.string().datetime().optional(),
|
|
4119
|
+
requireNoActiveWork: import_zod46.z.boolean().default(true)
|
|
4120
|
+
}).strict();
|
|
4121
|
+
var ResourceCleanupSelectorSchema = import_zod46.z.object({
|
|
4122
|
+
projectId: UuidSchema,
|
|
4123
|
+
prefix: CleanupPrefixSchema.optional(),
|
|
4124
|
+
workloadIds: NonEmptyUuidArraySchema.optional(),
|
|
4125
|
+
runtimeTemplateIds: NonEmptyUuidArraySchema.optional(),
|
|
4126
|
+
sessionIds: NonEmptyUuidArraySchema.optional()
|
|
4127
|
+
}).strict().superRefine((value, ctx) => {
|
|
4128
|
+
var _a, _b, _c;
|
|
4129
|
+
if (!value.prefix && !((_a = value.workloadIds) == null ? void 0 : _a.length) && !((_b = value.runtimeTemplateIds) == null ? void 0 : _b.length) && !((_c = value.sessionIds) == null ? void 0 : _c.length)) {
|
|
4130
|
+
ctx.addIssue({
|
|
4131
|
+
code: import_zod46.z.ZodIssueCode.custom,
|
|
4132
|
+
message: "cleanup selector must include prefix or explicit ids",
|
|
4133
|
+
path: ["prefix"]
|
|
4134
|
+
});
|
|
4135
|
+
}
|
|
4136
|
+
});
|
|
4137
|
+
var ResourceCleanupPlanRequestSchema = import_zod46.z.object({
|
|
4138
|
+
selector: ResourceCleanupSelectorSchema
|
|
4139
|
+
}).strict();
|
|
4140
|
+
var ResourceCleanupExecuteRequestSchema = import_zod46.z.object({
|
|
4141
|
+
selector: ResourceCleanupSelectorSchema,
|
|
4142
|
+
expectedCleanupId: import_zod46.z.string().min(16).max(64),
|
|
4143
|
+
confirm: import_zod46.z.literal(true),
|
|
4144
|
+
terminateActiveSessions: import_zod46.z.boolean().default(true),
|
|
4145
|
+
requireNoActiveWork: import_zod46.z.boolean().default(true)
|
|
4146
|
+
}).strict();
|
|
4147
|
+
var ResourceCleanupResourceTypeSchema = import_zod46.z.enum([
|
|
4148
|
+
"agents_session_refs",
|
|
4149
|
+
"runs_session_refs",
|
|
4150
|
+
"session_pool_slots",
|
|
4151
|
+
"session_pool_configs",
|
|
4152
|
+
"worker_protocol_jobs",
|
|
4153
|
+
"schedule_triggers",
|
|
4154
|
+
"schedule_definitions",
|
|
4155
|
+
"session_vault_bindings",
|
|
4156
|
+
"session_config_values",
|
|
4157
|
+
"session_tokens",
|
|
4158
|
+
"session_events",
|
|
4159
|
+
"session_startup_jobs",
|
|
4160
|
+
"session_failure_reasons",
|
|
4161
|
+
"startup_gate_conditions",
|
|
4162
|
+
"runtime_bindings",
|
|
4163
|
+
"sessions",
|
|
4164
|
+
"revision_config_values",
|
|
4165
|
+
"revisions",
|
|
4166
|
+
"workloads",
|
|
4167
|
+
"runtime_templates"
|
|
4168
|
+
]);
|
|
4169
|
+
var ResourceCleanupBlockerSchema = import_zod46.z.object({
|
|
4170
|
+
code: import_zod46.z.string(),
|
|
4171
|
+
resourceType: import_zod46.z.string(),
|
|
4172
|
+
resourceId: import_zod46.z.string(),
|
|
4173
|
+
message: import_zod46.z.string()
|
|
4174
|
+
}).strict();
|
|
4175
|
+
var ResourceCleanupStepSchema = import_zod46.z.object({
|
|
4176
|
+
resourceType: ResourceCleanupResourceTypeSchema,
|
|
4177
|
+
action: import_zod46.z.enum(["delete", "update_null"]),
|
|
4178
|
+
count: import_zod46.z.number().int().nonnegative(),
|
|
4179
|
+
ids: import_zod46.z.array(import_zod46.z.string())
|
|
4180
|
+
}).strict();
|
|
4181
|
+
var ResourceCleanupResourceIdsSchema = import_zod46.z.object({
|
|
4182
|
+
workloadIds: import_zod46.z.array(UuidSchema),
|
|
4183
|
+
runtimeTemplateIds: import_zod46.z.array(UuidSchema),
|
|
4184
|
+
revisionIds: import_zod46.z.array(UuidSchema),
|
|
4185
|
+
sessionIds: import_zod46.z.array(UuidSchema),
|
|
4186
|
+
runtimeBindingIds: import_zod46.z.array(UuidSchema),
|
|
4187
|
+
sessionPoolSlotIds: import_zod46.z.array(UuidSchema),
|
|
4188
|
+
sessionPoolConfigWorkloadIds: import_zod46.z.array(UuidSchema),
|
|
4189
|
+
scheduleDefinitionIds: import_zod46.z.array(UuidSchema),
|
|
4190
|
+
scheduleTriggerIds: import_zod46.z.array(UuidSchema),
|
|
4191
|
+
runSessionRefIds: import_zod46.z.array(UuidSchema),
|
|
4192
|
+
agentSessionRefIds: import_zod46.z.array(UuidSchema),
|
|
4193
|
+
workerProtocolJobIds: import_zod46.z.array(UuidSchema)
|
|
4194
|
+
}).strict();
|
|
4195
|
+
var ResourceCleanupPlanSchema = import_zod46.z.object({
|
|
4196
|
+
cleanupId: import_zod46.z.string(),
|
|
4197
|
+
generatedAt: import_zod46.z.string().datetime(),
|
|
4198
|
+
selector: ResourceCleanupSelectorSchema,
|
|
4199
|
+
resources: ResourceCleanupResourceIdsSchema,
|
|
4200
|
+
counts: import_zod46.z.record(ResourceCleanupResourceTypeSchema, import_zod46.z.number().int().nonnegative()),
|
|
4201
|
+
steps: import_zod46.z.array(ResourceCleanupStepSchema),
|
|
4202
|
+
blockers: import_zod46.z.array(ResourceCleanupBlockerSchema)
|
|
4203
|
+
}).strict();
|
|
4204
|
+
var ResourceCleanupExecuteResultSchema = import_zod46.z.object({
|
|
4205
|
+
cleanupId: import_zod46.z.string(),
|
|
4206
|
+
deletedCounts: import_zod46.z.record(ResourceCleanupResourceTypeSchema, import_zod46.z.number().int().nonnegative()),
|
|
4207
|
+
updatedCounts: import_zod46.z.record(ResourceCleanupResourceTypeSchema, import_zod46.z.number().int().nonnegative()),
|
|
4208
|
+
terminatedSessions: import_zod46.z.array(UuidSchema),
|
|
4209
|
+
readback: ResourceCleanupPlanSchema
|
|
4210
|
+
}).strict();
|
|
4211
|
+
|
|
4212
|
+
// src/errors.ts
|
|
4213
|
+
var PilotPlatformApiError = class extends Error {
|
|
4214
|
+
constructor(options) {
|
|
4215
|
+
super(options.message ?? `${options.code} (HTTP ${options.status})`, {
|
|
4216
|
+
cause: options.cause
|
|
4217
|
+
});
|
|
4218
|
+
this.name = "PilotPlatformApiError";
|
|
4219
|
+
this.status = options.status;
|
|
4220
|
+
this.code = options.code;
|
|
4221
|
+
this.requestId = options.requestId;
|
|
4222
|
+
}
|
|
4223
|
+
};
|
|
4224
|
+
var PilotPlatformUnauthenticatedError = class extends PilotPlatformApiError {
|
|
4225
|
+
constructor(options) {
|
|
4226
|
+
super({ ...options, status: 401 });
|
|
4227
|
+
this.name = "PilotPlatformUnauthenticatedError";
|
|
4228
|
+
}
|
|
4229
|
+
};
|
|
4230
|
+
var PilotPlatformForbiddenError = class extends PilotPlatformApiError {
|
|
4231
|
+
constructor(options) {
|
|
4232
|
+
super({ ...options, status: 403 });
|
|
4233
|
+
this.name = "PilotPlatformForbiddenError";
|
|
4234
|
+
}
|
|
4235
|
+
};
|
|
4236
|
+
var PilotPlatformNotFoundError = class extends PilotPlatformApiError {
|
|
4237
|
+
constructor(options) {
|
|
4238
|
+
super({ ...options, status: 404 });
|
|
4239
|
+
this.name = "PilotPlatformNotFoundError";
|
|
4240
|
+
}
|
|
4241
|
+
};
|
|
4242
|
+
var PilotPlatformServerError = class extends PilotPlatformApiError {
|
|
4243
|
+
constructor(options) {
|
|
4244
|
+
super(options);
|
|
4245
|
+
this.name = "PilotPlatformServerError";
|
|
4246
|
+
}
|
|
4247
|
+
};
|
|
4248
|
+
function pilotPlatformErrorFromResponse(params) {
|
|
4249
|
+
const parsed = extractErrorBody(params.body);
|
|
4250
|
+
const code = parsed.code ?? defaultCodeForStatus(params.status);
|
|
4251
|
+
const message = parsed.message ?? parsed.error;
|
|
4252
|
+
const base = { code, message, requestId: params.requestId };
|
|
4253
|
+
if (params.status === 401) return new PilotPlatformUnauthenticatedError(base);
|
|
4254
|
+
if (params.status === 403) return new PilotPlatformForbiddenError(base);
|
|
4255
|
+
if (params.status === 404) return new PilotPlatformNotFoundError(base);
|
|
4256
|
+
if (params.status >= 500 && params.status < 600) {
|
|
4257
|
+
return new PilotPlatformServerError({ ...base, status: params.status });
|
|
4258
|
+
}
|
|
4259
|
+
return new PilotPlatformApiError({ ...base, status: params.status });
|
|
4260
|
+
}
|
|
4261
|
+
function extractErrorBody(body) {
|
|
4262
|
+
if (!body || typeof body !== "object") return {};
|
|
4263
|
+
const record = body;
|
|
4264
|
+
return {
|
|
4265
|
+
error: typeof record.error === "string" ? record.error : void 0,
|
|
4266
|
+
code: typeof record.code === "string" ? record.code : void 0,
|
|
4267
|
+
message: typeof record.message === "string" ? record.message : void 0
|
|
4268
|
+
};
|
|
4269
|
+
}
|
|
4270
|
+
function defaultCodeForStatus(status) {
|
|
4271
|
+
if (status === 401) return "UNAUTHENTICATED";
|
|
4272
|
+
if (status === 403) return "FORBIDDEN";
|
|
4273
|
+
if (status === 404) return "NOT_FOUND";
|
|
4274
|
+
if (status >= 500) return "SERVER_ERROR";
|
|
4275
|
+
return "REQUEST_FAILED";
|
|
4276
|
+
}
|
|
4277
|
+
|
|
4278
|
+
// src/resources/projects.ts
|
|
4279
|
+
var ProjectsResource = class {
|
|
4280
|
+
constructor(client) {
|
|
4281
|
+
this.client = client;
|
|
4282
|
+
}
|
|
4283
|
+
async create(request, options = {}) {
|
|
4284
|
+
const body = CreatePlatformProjectRequestSchema.parse(request);
|
|
4285
|
+
const response = await this.client.request("/api/projects", {
|
|
4286
|
+
method: "POST",
|
|
4287
|
+
body,
|
|
4288
|
+
signal: options.signal
|
|
4289
|
+
});
|
|
4290
|
+
return PlatformProjectSchema.parse(response);
|
|
4291
|
+
}
|
|
4292
|
+
async list(options = {}) {
|
|
4293
|
+
const response = await this.client.request("/api/projects", {
|
|
4294
|
+
method: "GET",
|
|
4295
|
+
signal: options.signal
|
|
4296
|
+
});
|
|
4297
|
+
return ListPlatformProjectsResponseSchema.parse(response).projects;
|
|
4298
|
+
}
|
|
4299
|
+
async get(projectId, options = {}) {
|
|
4300
|
+
const response = await this.client.request(
|
|
4301
|
+
`/api/projects/${encodeURIComponent(projectId)}`,
|
|
4302
|
+
{
|
|
4303
|
+
method: "GET",
|
|
4304
|
+
signal: options.signal,
|
|
4305
|
+
cache: "no-store"
|
|
4306
|
+
}
|
|
4307
|
+
);
|
|
4308
|
+
return PlatformProjectSchema.parse(response);
|
|
4309
|
+
}
|
|
4310
|
+
};
|
|
4311
|
+
|
|
4312
|
+
// src/resources/sessions.ts
|
|
4313
|
+
var SessionsResource = class {
|
|
4314
|
+
constructor(client) {
|
|
4315
|
+
this.client = client;
|
|
4316
|
+
}
|
|
4317
|
+
async create(request, options = {}) {
|
|
4318
|
+
const body = CreatePlatformSessionRequestSchema.parse(request);
|
|
4319
|
+
const envelope = await this.client.request("/api/sessions", {
|
|
4320
|
+
method: "POST",
|
|
4321
|
+
body,
|
|
4322
|
+
signal: options.signal
|
|
4323
|
+
});
|
|
4324
|
+
return CreatePlatformSessionResponseSchema.parse(envelope?.data);
|
|
4325
|
+
}
|
|
4326
|
+
async get(sessionId, options = {}) {
|
|
4327
|
+
const envelope = await this.client.request(
|
|
4328
|
+
`/api/sessions/${encodeURIComponent(sessionId)}`,
|
|
4329
|
+
{
|
|
4330
|
+
method: "GET",
|
|
4331
|
+
signal: options.signal,
|
|
4332
|
+
cache: "no-store",
|
|
4333
|
+
headers: {
|
|
4334
|
+
"Cache-Control": "no-cache",
|
|
4335
|
+
Pragma: "no-cache"
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
);
|
|
4339
|
+
if (!envelope?.data || typeof envelope.data !== "object") {
|
|
4340
|
+
throw new PilotPlatformApiError({
|
|
4341
|
+
status: 0,
|
|
4342
|
+
code: "MALFORMED_SESSION_RESPONSE",
|
|
4343
|
+
message: "GET /api/sessions/:id did not return a {data: ...} envelope."
|
|
4344
|
+
});
|
|
4345
|
+
}
|
|
4346
|
+
return envelope.data;
|
|
4347
|
+
}
|
|
4348
|
+
async wait(sessionId, options = {}) {
|
|
4349
|
+
const intervalMs = options.intervalMs ?? 1e3;
|
|
4350
|
+
const timeoutMs = options.timeoutMs ?? 12e4;
|
|
4351
|
+
const startedAt = Date.now();
|
|
4352
|
+
while (true) {
|
|
4353
|
+
if (options.signal?.aborted) throw options.signal.reason;
|
|
4354
|
+
const snapshot = await this.get(sessionId, { signal: options.signal });
|
|
4355
|
+
const status = snapshot.session?.status;
|
|
4356
|
+
if (status === "ready") return snapshot;
|
|
4357
|
+
if (status === "failed") {
|
|
4358
|
+
throw new PilotPlatformApiError({
|
|
4359
|
+
status: 0,
|
|
4360
|
+
code: "SESSION_FAILED",
|
|
4361
|
+
message: `Session ${sessionId} failed while waiting for readiness.`
|
|
4362
|
+
});
|
|
4363
|
+
}
|
|
4364
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
4365
|
+
throw new PilotPlatformApiError({
|
|
4366
|
+
status: 0,
|
|
4367
|
+
code: "SESSION_WAIT_TIMEOUT",
|
|
4368
|
+
message: `Timed out waiting for session ${sessionId} to become ready.`
|
|
4369
|
+
});
|
|
4370
|
+
}
|
|
4371
|
+
await sleep(intervalMs, options.signal);
|
|
4372
|
+
}
|
|
4373
|
+
}
|
|
4374
|
+
};
|
|
4375
|
+
function sleep(ms, signal) {
|
|
4376
|
+
if (ms <= 0) return Promise.resolve();
|
|
4377
|
+
return new Promise((resolve, reject) => {
|
|
4378
|
+
const timer = setTimeout(resolve, ms);
|
|
4379
|
+
signal?.addEventListener(
|
|
4380
|
+
"abort",
|
|
4381
|
+
() => {
|
|
4382
|
+
clearTimeout(timer);
|
|
4383
|
+
reject(signal.reason);
|
|
4384
|
+
},
|
|
4385
|
+
{ once: true }
|
|
4386
|
+
);
|
|
4387
|
+
});
|
|
4388
|
+
}
|
|
4389
|
+
|
|
4390
|
+
// src/resources/workloads.ts
|
|
4391
|
+
var WorkloadsResource = class {
|
|
4392
|
+
constructor(client) {
|
|
4393
|
+
this.client = client;
|
|
4394
|
+
}
|
|
4395
|
+
async create(request, options = {}) {
|
|
4396
|
+
const body = CreatePlatformWorkloadRequestSchema.parse(request);
|
|
4397
|
+
const envelope = await this.client.request("/api/workloads", {
|
|
4398
|
+
method: "POST",
|
|
4399
|
+
body,
|
|
4400
|
+
signal: options.signal,
|
|
4401
|
+
query: options.dryRun ? { dryRun: true } : void 0
|
|
4402
|
+
});
|
|
4403
|
+
return unwrapEnvelope(envelope, "POST /api/workloads", ["status", "workload"]);
|
|
4404
|
+
}
|
|
4405
|
+
async publishRevision(request, options = {}) {
|
|
4406
|
+
const body = PublishPlatformRevisionRequestSchema.parse(request);
|
|
4407
|
+
const path = `/api/workloads/${encodeURIComponent(body.workloadSlug)}/revisions`;
|
|
4408
|
+
const envelope = await this.client.request(path, {
|
|
4409
|
+
method: "POST",
|
|
4410
|
+
body,
|
|
4411
|
+
signal: options.signal,
|
|
4412
|
+
query: options.dryRun ? { dryRun: true } : void 0
|
|
4413
|
+
});
|
|
4414
|
+
return unwrapEnvelope(envelope, `POST ${path}`, [
|
|
4415
|
+
"status",
|
|
4416
|
+
"workloadId",
|
|
4417
|
+
"runtimeTemplateId",
|
|
4418
|
+
"resolved"
|
|
4419
|
+
]);
|
|
4420
|
+
}
|
|
4421
|
+
async applyManifest(options) {
|
|
4422
|
+
const envelope = await this.client.request(
|
|
4423
|
+
"/api/workloads",
|
|
4424
|
+
buildManifestRequest(options.manifest, options)
|
|
4425
|
+
);
|
|
4426
|
+
return unwrapEnvelope(envelope, "POST /api/workloads", ["status", "workload"]);
|
|
4427
|
+
}
|
|
4428
|
+
async applyRevisionManifest(options) {
|
|
4429
|
+
const path = `/api/workloads/${encodeURIComponent(options.workloadSlug)}/revisions`;
|
|
4430
|
+
const envelope = await this.client.request(
|
|
4431
|
+
path,
|
|
4432
|
+
buildManifestRequest(options.manifest, options)
|
|
4433
|
+
);
|
|
4434
|
+
return unwrapEnvelope(envelope, `POST ${path}`, [
|
|
4435
|
+
"status",
|
|
4436
|
+
"workloadId",
|
|
4437
|
+
"runtimeTemplateId",
|
|
4438
|
+
"resolved"
|
|
4439
|
+
]);
|
|
4440
|
+
}
|
|
4441
|
+
};
|
|
4442
|
+
function buildManifestRequest(manifest, options) {
|
|
4443
|
+
const init = {
|
|
4444
|
+
method: "POST",
|
|
4445
|
+
signal: options.signal,
|
|
4446
|
+
query: {
|
|
4447
|
+
projectId: options.projectId,
|
|
4448
|
+
...options.dryRun ? { dryRun: true } : {}
|
|
4449
|
+
}
|
|
4450
|
+
};
|
|
4451
|
+
if (isYamlInput(manifest)) {
|
|
4452
|
+
init.rawBody = manifest.yaml;
|
|
4453
|
+
init.headers = { "Content-Type": "application/yaml" };
|
|
4454
|
+
} else if (isJsonStringInput(manifest)) {
|
|
4455
|
+
init.rawBody = manifest.json;
|
|
4456
|
+
init.headers = { "Content-Type": "application/json" };
|
|
4457
|
+
} else {
|
|
4458
|
+
init.body = manifest;
|
|
4459
|
+
}
|
|
4460
|
+
return init;
|
|
4461
|
+
}
|
|
4462
|
+
function isYamlInput(value) {
|
|
4463
|
+
return typeof value === "object" && value !== null && "yaml" in value && typeof value.yaml === "string";
|
|
4464
|
+
}
|
|
4465
|
+
function isJsonStringInput(value) {
|
|
4466
|
+
return typeof value === "object" && value !== null && "json" in value && typeof value.json === "string";
|
|
4467
|
+
}
|
|
4468
|
+
function unwrapEnvelope(envelope, routeLabel, requiredKeys) {
|
|
4469
|
+
const data = envelope?.data;
|
|
4470
|
+
if (!data) {
|
|
4471
|
+
throw new PilotPlatformApiError({
|
|
4472
|
+
status: 0,
|
|
4473
|
+
code: "MALFORMED_PLATFORM_RESPONSE",
|
|
4474
|
+
message: `${routeLabel} did not return a {data: ...} envelope.`
|
|
4475
|
+
});
|
|
4476
|
+
}
|
|
4477
|
+
for (const key of requiredKeys) {
|
|
4478
|
+
if (!(key in data)) {
|
|
4479
|
+
throw new PilotPlatformApiError({
|
|
4480
|
+
status: 0,
|
|
4481
|
+
code: "MALFORMED_PLATFORM_RESPONSE",
|
|
4482
|
+
message: `${routeLabel} response is missing required field '${String(key)}'.`
|
|
4483
|
+
});
|
|
4484
|
+
}
|
|
4485
|
+
}
|
|
4486
|
+
return data;
|
|
4487
|
+
}
|
|
4488
|
+
|
|
4489
|
+
// src/client.ts
|
|
4490
|
+
var AGENTHUB_SDK_USER_AGENT = "@kanyun-ai-infra/agenthub/0.1.0";
|
|
4491
|
+
var _token;
|
|
4492
|
+
var PilotPlatformClient = class {
|
|
4493
|
+
constructor(config = {}) {
|
|
4494
|
+
__privateAdd(this, _token);
|
|
4495
|
+
const controlPlaneUrl = config.controlPlaneUrl ?? readEnv("PILOT_CONTROL_PLANE_URL") ?? readEnv("KANYUN_PILOT_CONTROL_PLANE_URL");
|
|
4496
|
+
const token = config.token ?? readEnv("PILOT_TOKEN");
|
|
4497
|
+
if (!controlPlaneUrl) {
|
|
4498
|
+
throw new PilotPlatformApiError({
|
|
4499
|
+
status: 0,
|
|
4500
|
+
code: "CONFIG_MISSING_CONTROL_PLANE_URL",
|
|
4501
|
+
message: "PilotPlatformClient requires `controlPlaneUrl` or PILOT_CONTROL_PLANE_URL."
|
|
4502
|
+
});
|
|
4503
|
+
}
|
|
4504
|
+
if (!token) {
|
|
4505
|
+
throw new PilotPlatformUnauthenticatedError({
|
|
4506
|
+
code: "CONFIG_MISSING_TOKEN",
|
|
4507
|
+
message: "PilotPlatformClient requires `token` or PILOT_TOKEN."
|
|
4508
|
+
});
|
|
4509
|
+
}
|
|
4510
|
+
const normalizedControlPlaneUrl = stripTrailingSlash(controlPlaneUrl);
|
|
4511
|
+
try {
|
|
4512
|
+
const parsed = new URL(normalizedControlPlaneUrl);
|
|
4513
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
4514
|
+
throw new Error(`Unsupported protocol: ${parsed.protocol}`);
|
|
4515
|
+
}
|
|
4516
|
+
} catch (error) {
|
|
4517
|
+
throw new PilotPlatformApiError({
|
|
4518
|
+
status: 0,
|
|
4519
|
+
code: "CONFIG_INVALID_CONTROL_PLANE_URL",
|
|
4520
|
+
message: `controlPlaneUrl is not a valid http(s) URL: ${controlPlaneUrl}`,
|
|
4521
|
+
cause: error
|
|
4522
|
+
});
|
|
4523
|
+
}
|
|
4524
|
+
this.controlPlaneUrl = normalizedControlPlaneUrl;
|
|
4525
|
+
__privateSet(this, _token, token);
|
|
4526
|
+
this.fetchImpl = config.fetch ?? globalThis.fetch.bind(globalThis);
|
|
4527
|
+
this.defaultHeaders = { ...config.defaultHeaders ?? {} };
|
|
4528
|
+
this.defaultSignal = config.signal;
|
|
4529
|
+
this.userAgent = config.userAgent ?? AGENTHUB_SDK_USER_AGENT;
|
|
4530
|
+
this.pilotApiVersion = config.pilotApiVersion ?? "v2";
|
|
4531
|
+
this.projects = new ProjectsResource(this);
|
|
4532
|
+
this.workloads = new WorkloadsResource(this);
|
|
4533
|
+
this.sessions = new SessionsResource(this);
|
|
4534
|
+
}
|
|
4535
|
+
async request(path, init = {}) {
|
|
4536
|
+
const res = await this.rawRequest(path, init);
|
|
4537
|
+
if (init.raw) return res;
|
|
4538
|
+
const text = await res.text();
|
|
4539
|
+
if (!text) return void 0;
|
|
4540
|
+
try {
|
|
4541
|
+
return JSON.parse(text);
|
|
4542
|
+
} catch (error) {
|
|
4543
|
+
throw new PilotPlatformApiError({
|
|
4544
|
+
status: res.status,
|
|
4545
|
+
code: "INVALID_JSON_RESPONSE",
|
|
4546
|
+
message: `Control Plane returned non-JSON body: ${text.slice(0, 200)}`,
|
|
4547
|
+
requestId: res.headers.get("x-request-id") ?? void 0,
|
|
4548
|
+
cause: error
|
|
4549
|
+
});
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4552
|
+
async rawRequest(path, init = {}) {
|
|
4553
|
+
if (init.rawBody !== void 0 && init.body !== void 0) {
|
|
4554
|
+
throw new PilotPlatformApiError({
|
|
4555
|
+
status: 0,
|
|
4556
|
+
code: "INVALID_REQUEST_BODY",
|
|
4557
|
+
message: "body and rawBody are mutually exclusive."
|
|
4558
|
+
});
|
|
4559
|
+
}
|
|
4560
|
+
const headers = new Headers();
|
|
4561
|
+
addHeaders(headers, { Accept: "application/json", "User-Agent": this.userAgent });
|
|
4562
|
+
addHeaders(headers, this.defaultHeaders);
|
|
4563
|
+
addHeaders(headers, init.headers);
|
|
4564
|
+
headers.delete("authorization");
|
|
4565
|
+
headers.set("Authorization", `Bearer ${__privateGet(this, _token)}`);
|
|
4566
|
+
headers.set(X_PILOT_API_VERSION_HEADER, this.pilotApiVersion);
|
|
4567
|
+
let body;
|
|
4568
|
+
if (init.rawBody !== void 0) {
|
|
4569
|
+
body = init.rawBody;
|
|
4570
|
+
} else if (init.body !== void 0) {
|
|
4571
|
+
body = JSON.stringify(init.body);
|
|
4572
|
+
headers.set("Content-Type", "application/json");
|
|
4573
|
+
}
|
|
4574
|
+
let res;
|
|
4575
|
+
const url = this.composeUrl(path, init.query);
|
|
4576
|
+
try {
|
|
4577
|
+
res = await this.fetchImpl(url, {
|
|
4578
|
+
method: init.method ?? "GET",
|
|
4579
|
+
headers,
|
|
4580
|
+
body,
|
|
4581
|
+
signal: mergeSignals(this.defaultSignal, init.signal),
|
|
4582
|
+
cache: init.cache
|
|
4583
|
+
});
|
|
4584
|
+
} catch (error) {
|
|
4585
|
+
if (isAbortError(error)) throw error;
|
|
4586
|
+
throw new PilotPlatformApiError({
|
|
4587
|
+
status: 0,
|
|
4588
|
+
code: "NETWORK_ERROR",
|
|
4589
|
+
message: `Request to ${url} failed: ${error?.message ?? String(error)}`,
|
|
4590
|
+
cause: error
|
|
4591
|
+
});
|
|
4592
|
+
}
|
|
4593
|
+
if (res.ok) return res;
|
|
4594
|
+
const text = await res.text();
|
|
4595
|
+
let parsed = void 0;
|
|
4596
|
+
if (text) {
|
|
4597
|
+
try {
|
|
4598
|
+
parsed = JSON.parse(text);
|
|
4599
|
+
} catch {
|
|
4600
|
+
parsed = { error: text };
|
|
4601
|
+
}
|
|
4602
|
+
}
|
|
4603
|
+
throw pilotPlatformErrorFromResponse({
|
|
4604
|
+
status: res.status,
|
|
4605
|
+
body: parsed,
|
|
4606
|
+
requestId: res.headers.get("x-request-id") ?? void 0
|
|
4607
|
+
});
|
|
4608
|
+
}
|
|
4609
|
+
composeUrl(path, query) {
|
|
4610
|
+
const base = new URL(`${this.controlPlaneUrl}/`);
|
|
4611
|
+
const normalized = path.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(path) ? path : path.startsWith("/") ? path : `/${path}`;
|
|
4612
|
+
let full;
|
|
4613
|
+
try {
|
|
4614
|
+
full = new URL(normalized, base);
|
|
4615
|
+
} catch (error) {
|
|
4616
|
+
throw new PilotPlatformApiError({
|
|
4617
|
+
status: 0,
|
|
4618
|
+
code: "INVALID_REQUEST_URL",
|
|
4619
|
+
message: `Could not resolve path "${path}" against controlPlaneUrl.`,
|
|
4620
|
+
cause: error
|
|
4621
|
+
});
|
|
4622
|
+
}
|
|
4623
|
+
if (full.origin !== base.origin) {
|
|
4624
|
+
throw new PilotPlatformApiError({
|
|
4625
|
+
status: 0,
|
|
4626
|
+
code: "CROSS_ORIGIN_REQUEST_BLOCKED",
|
|
4627
|
+
message: `Refusing to send Bearer token to foreign origin ${full.origin}.`
|
|
4628
|
+
});
|
|
4629
|
+
}
|
|
4630
|
+
if (query) {
|
|
4631
|
+
for (const [key, value] of Object.entries(query)) {
|
|
4632
|
+
if (value === void 0 || value === null) continue;
|
|
4633
|
+
full.searchParams.set(key, String(value));
|
|
4634
|
+
}
|
|
4635
|
+
}
|
|
4636
|
+
return full.toString();
|
|
4637
|
+
}
|
|
4638
|
+
};
|
|
4639
|
+
_token = new WeakMap();
|
|
4640
|
+
function stripTrailingSlash(url) {
|
|
4641
|
+
return url.endsWith("/") ? url.slice(0, -1) : url;
|
|
4642
|
+
}
|
|
4643
|
+
function addHeaders(target, source) {
|
|
4644
|
+
if (!source) return;
|
|
4645
|
+
for (const [key, value] of Object.entries(source)) {
|
|
4646
|
+
if (value === void 0 || value === null) continue;
|
|
4647
|
+
target.set(key, value);
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
function readEnv(key) {
|
|
4651
|
+
const env = globalThis.process?.env;
|
|
4652
|
+
const value = env?.[key];
|
|
4653
|
+
return value && value.length > 0 ? value : void 0;
|
|
4654
|
+
}
|
|
4655
|
+
function isAbortError(error) {
|
|
4656
|
+
return error instanceof Error && (error.name === "AbortError" || error.code === "ABORT_ERR");
|
|
4657
|
+
}
|
|
4658
|
+
function mergeSignals(...signals) {
|
|
4659
|
+
const active = signals.filter((signal) => !!signal);
|
|
4660
|
+
if (active.length === 0) return void 0;
|
|
4661
|
+
if (active.length === 1) return active[0];
|
|
4662
|
+
const anyFn = AbortSignal.any;
|
|
4663
|
+
if (typeof anyFn === "function") return anyFn(active);
|
|
4664
|
+
const controller = new AbortController();
|
|
4665
|
+
for (const signal of active) {
|
|
4666
|
+
if (signal.aborted) {
|
|
4667
|
+
controller.abort(signal.reason);
|
|
4668
|
+
break;
|
|
4669
|
+
}
|
|
4670
|
+
signal.addEventListener("abort", () => controller.abort(signal.reason), { once: true });
|
|
4671
|
+
}
|
|
4672
|
+
return controller.signal;
|
|
4673
|
+
}
|
|
4674
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
4675
|
+
0 && (module.exports = {
|
|
4676
|
+
AGENTHUB_SDK_USER_AGENT,
|
|
4677
|
+
CreatePlatformProjectRequestSchema,
|
|
4678
|
+
CreatePlatformSessionRequestSchema,
|
|
4679
|
+
CreatePlatformSessionResponseSchema,
|
|
4680
|
+
CreatePlatformWorkloadRequestSchema,
|
|
4681
|
+
ListPlatformProjectsResponseSchema,
|
|
4682
|
+
PILOT_WORKLOAD_MANIFEST_API_VERSION,
|
|
4683
|
+
PILOT_WORKLOAD_MANIFEST_LEGACY_API_VERSION,
|
|
4684
|
+
PilotPlatformApiError,
|
|
4685
|
+
PilotPlatformClient,
|
|
4686
|
+
PilotPlatformForbiddenError,
|
|
4687
|
+
PilotPlatformNotFoundError,
|
|
4688
|
+
PilotPlatformServerError,
|
|
4689
|
+
PilotPlatformUnauthenticatedError,
|
|
4690
|
+
PlatformProjectSchema,
|
|
4691
|
+
PlatformRevisionSchema,
|
|
4692
|
+
PlatformWorkloadSchema,
|
|
4693
|
+
ProjectsResource,
|
|
4694
|
+
PublishPlatformRevisionRequestSchema,
|
|
4695
|
+
SessionsResource,
|
|
4696
|
+
WorkloadsResource,
|
|
4697
|
+
pilotPlatformErrorFromResponse,
|
|
4698
|
+
platformRevisionPublishToManifest,
|
|
4699
|
+
platformWorkloadCreateToManifest
|
|
4700
|
+
});
|
|
4701
|
+
//# sourceMappingURL=index.cjs.map
|