@drisp/protocol 0.8.4 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/v2.d.ts +82 -6
- package/dist/v2.js +307 -252
- package/package.json +1 -1
- package/schema/v2/client.json +22 -0
- package/schema/v2/command.json +22 -0
- package/schema/v2/run.json +22 -0
package/dist/v2.d.ts
CHANGED
|
@@ -18,14 +18,78 @@ declare function classOfCap(declaredCap: number): SizeClass;
|
|
|
18
18
|
/** What a Run declaring `declaredCap` is expected to use: its class's forecast. */
|
|
19
19
|
declare function forecastOfCap(declaredCap: number): number;
|
|
20
20
|
/**
|
|
21
|
-
* What
|
|
22
|
-
*
|
|
23
|
-
* declared cap. A closed attempt whose cap is no positive number counts its forecast.
|
|
21
|
+
* What an attempt declaring `declaredCap` is expected to use: its class's forecast, never more than its own cap (so
|
|
22
|
+
* the rule stays looser than the cap sum it replaces). A cap that is no positive number counts the `S` forecast.
|
|
24
23
|
*/
|
|
25
|
-
declare function
|
|
24
|
+
declare function attemptForecast(declaredCap: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* One attempt of a child: its declared cap, whether it has closed, and the counted tokens it reported, if any. No
|
|
27
|
+
* caller passes `spent` yet: the CLI and the Hub count forecasts until reported usage feeds the rule (DRI-246).
|
|
28
|
+
*/
|
|
29
|
+
type BudgetAttempt = {
|
|
26
30
|
tokenCap: number;
|
|
27
31
|
closed: boolean;
|
|
28
|
-
|
|
32
|
+
spent?: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* What one attempt holds against the budget: a closed attempt (finished, failed, cancelled) what it reported, else its
|
|
36
|
+
* forecast; a running or queued one the larger of its forecast and what it reported, so a resumed attempt never counts
|
|
37
|
+
* the same tokens twice and an overrun counts once reported.
|
|
38
|
+
*/
|
|
39
|
+
declare function attemptCost(attempt: BudgetAttempt): number;
|
|
40
|
+
/**
|
|
41
|
+
* The budget rule the CLI and the Hub share (root ADR-0011). `used` is the sum over every attempt of every child, a
|
|
42
|
+
* retry being a new attempt; the next start, forecast at `next`, fits when `used + next` is within the budget. Issues
|
|
43
|
+
* not yet started never enter it: the app warns of them on the plan sheet (Kit `shortfallNote`) and nothing parks.
|
|
44
|
+
*/
|
|
45
|
+
declare function budgetCheck(input: {
|
|
46
|
+
tokenBudget: number;
|
|
47
|
+
attempts: readonly BudgetAttempt[];
|
|
48
|
+
next: number;
|
|
49
|
+
}): {
|
|
50
|
+
used: number;
|
|
51
|
+
fits: boolean;
|
|
52
|
+
};
|
|
53
|
+
/** A class needs this many finished Runs of a harness before its forecast is measured (DRI-244). */
|
|
54
|
+
declare const CALIBRATION_MIN_RUNS = 10;
|
|
55
|
+
/** Only Runs closed within this many days count. */
|
|
56
|
+
declare const CALIBRATION_WINDOW_DAYS = 90;
|
|
57
|
+
/** What one size class measured to: the figure the plan uses, and how many finished Runs it rests on. */
|
|
58
|
+
type ClassCalibration = Readonly<Partial<Record<SizeClass, {
|
|
59
|
+
forecast: number;
|
|
60
|
+
runs: number;
|
|
61
|
+
}>>>;
|
|
62
|
+
/** The measured classes per harness name; a harness or class with too few Runs is absent. */
|
|
63
|
+
type Calibration = Readonly<Partial<Record<string, ClassCalibration>>>;
|
|
64
|
+
/** One finished Run's final counted tokens (cache reads excluded), by its harness and the class its cap belongs to. */
|
|
65
|
+
type CalibrationSample = {
|
|
66
|
+
harness: string;
|
|
67
|
+
sizeClass: SizeClass;
|
|
68
|
+
counted: number | undefined;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* The forecast of each class and harness with at least `CALIBRATION_MIN_RUNS` samples: max(constant, p90 of the
|
|
72
|
+
* samples), the p90 by nearest rank. The constants are the floor, so calibration only raises a forecast. A sample with
|
|
73
|
+
* no figure is ignored. Which Runs are samples (completed, first attempt, in the window) is the Hub's to say.
|
|
74
|
+
*/
|
|
75
|
+
declare function calibrate(samples: readonly CalibrationSample[]): Calibration;
|
|
76
|
+
/** `GET /calibration`: the measured classes per harness name. */
|
|
77
|
+
declare const calibrationSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
78
|
+
S: z.ZodOptional<z.ZodObject<{
|
|
79
|
+
forecast: z.ZodNumber;
|
|
80
|
+
runs: z.ZodNumber;
|
|
81
|
+
}, z.core.$strict>>;
|
|
82
|
+
M: z.ZodOptional<z.ZodObject<{
|
|
83
|
+
forecast: z.ZodNumber;
|
|
84
|
+
runs: z.ZodNumber;
|
|
85
|
+
}, z.core.$strict>>;
|
|
86
|
+
L: z.ZodOptional<z.ZodObject<{
|
|
87
|
+
forecast: z.ZodNumber;
|
|
88
|
+
runs: z.ZodNumber;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
}, z.core.$strict>>;
|
|
91
|
+
/** A class's forecast: its measured figure when `calibration` has one, else the constant. */
|
|
92
|
+
declare function forecastOfClass(sizeClass: SizeClass, calibration: ClassCalibration | undefined): number;
|
|
29
93
|
|
|
30
94
|
declare const protocolVersion: {
|
|
31
95
|
readonly major: 2;
|
|
@@ -495,6 +559,10 @@ declare const commandSchema: z.ZodObject<{
|
|
|
495
559
|
kind: z.ZodLiteral<"resume">;
|
|
496
560
|
interruptionId: z.ZodString;
|
|
497
561
|
guidance: z.ZodOptional<z.ZodString>;
|
|
562
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
563
|
+
kind: z.ZodLiteral<"setBudget">;
|
|
564
|
+
tokenBudget: z.ZodNumber;
|
|
565
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
498
566
|
}, z.core.$strict>], "kind">;
|
|
499
567
|
}, z.core.$strict>;
|
|
500
568
|
declare const grantSchema: z.ZodObject<{
|
|
@@ -935,6 +1003,10 @@ declare const runViewSchema: z.ZodObject<{
|
|
|
935
1003
|
kind: z.ZodLiteral<"resume">;
|
|
936
1004
|
interruptionId: z.ZodString;
|
|
937
1005
|
guidance: z.ZodOptional<z.ZodString>;
|
|
1006
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1007
|
+
kind: z.ZodLiteral<"setBudget">;
|
|
1008
|
+
tokenBudget: z.ZodNumber;
|
|
1009
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
938
1010
|
}, z.core.$strict>], "kind">>;
|
|
939
1011
|
runnerStopped: z.ZodOptional<z.ZodBoolean>;
|
|
940
1012
|
canAbandon: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1030,6 +1102,10 @@ declare const clientFrameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1030
1102
|
kind: z.ZodLiteral<"resume">;
|
|
1031
1103
|
interruptionId: z.ZodString;
|
|
1032
1104
|
guidance: z.ZodOptional<z.ZodString>;
|
|
1105
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1106
|
+
kind: z.ZodLiteral<"setBudget">;
|
|
1107
|
+
tokenBudget: z.ZodNumber;
|
|
1108
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
1033
1109
|
}, z.core.$strict>], "kind">;
|
|
1034
1110
|
}, z.core.$strict>;
|
|
1035
1111
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -1476,4 +1552,4 @@ type ConnectPendingResponse = z.infer<typeof connectPendingResponseSchema>;
|
|
|
1476
1552
|
type TeamDefault = z.infer<typeof teamDefaultSchema>;
|
|
1477
1553
|
type RunsGoTo = z.infer<typeof runsGoToSchema>;
|
|
1478
1554
|
|
|
1479
|
-
export { type Audience, type BuildCloseReason, type Checkpoint, type Command, type ConnectAlreadyConnected, type ConnectPendingResponse, type ConnectRedeemRequest, type ConnectRedeemResponse, type ConnectStartRequest, type ConnectStartResponse, type ControlRecord, type Delegation, type ExecutionFact, type Grant, type Harness, type HarnessReadiness, type HistoryRecord, type InstalledWorkflow, type RepositoryBinding, type RepositorySource, type RunCloseReason, type RunParent, type RunUsage, type RunView, type RunnerAdoptRequest, type RunnerDisconnectPreview, type RunnerDisconnectResponse, type RunnerFrame, type RunnerList, type RunnerListEntry, type RunnerReadiness, type RunsGoTo, SIZE_CLASS_CAPS, SIZE_CLASS_FORECASTS, type Scope, type SizeClass, type TeamDefault, type WorkflowIdentity, type WorkflowInstallReference, type WorkflowReference, abandonedConversationContinuationCapability, attemptCost, audienceSchema, buildCloseReasonSchema, canonicalJson, checkpointPathSchema, checkpointSchema, classOfCap, clientFrameSchema, commandSchema, connectAlreadyConnectedSchema, connectApproveRequestSchema, connectCodeAlphabet, connectCodeRequestSchema, connectCodeResponseSchema, connectCodeSchema, connectDenyRequestSchema, connectPendingResponseSchema, connectPollRequestSchema, connectRedeemRequestSchema, connectRedeemResponseSchema, connectStartRequestSchema, connectStartResponseSchema, controlRecordSchema, conversationContinuationCapability, delegationSchema, delegationTokenPrefix, forecastOfCap, grantSchema, harnessReadinessSchema, harnessSchema, historyRecordSchema, hubEpochRequestSchema, installReference, installedWorkflowsSchema, interruptionSchema, permissionAnswerSchema, protocolVersion, readableHistory, readinessFixCommand, repositoryAccessCapability, repositoryBindingSchema, repositoryRefSchema, repositorySourceSchema, repositoryWorkingDirectorySchema, runArtifactMaxBytes, runArtifactNameSchema, runCloseReasonSchema, runDelegationCapability, runKeySchema, runParentIntentSchema, runParentSchema, runSpecSchema, runUsageCapability, runUsageSchema, runViewSchema, runnerAdoptRequestSchema, runnerDisconnectPreviewSchema, runnerDisconnectRequestSchema, runnerDisconnectResponseSchema, runnerFrameSchema, runnerListEntrySchema, runnerListSchema, runnerReadinessSchema, runnerUpdateCommand, runnerUpdateRequestSchema, runsGoToSchema, sameWorkflow, scopeSchema, secretEnvironmentSchema, sequence, teamDefaultRequestSchema, teamDefaultSchema, workflowIdentitySchema, workflowInstallCapability, workflowName, workflowReferenceSchema, workflowSourceSchema };
|
|
1555
|
+
export { type Audience, type BudgetAttempt, type BuildCloseReason, CALIBRATION_MIN_RUNS, CALIBRATION_WINDOW_DAYS, type Calibration, type CalibrationSample, type Checkpoint, type ClassCalibration, type Command, type ConnectAlreadyConnected, type ConnectPendingResponse, type ConnectRedeemRequest, type ConnectRedeemResponse, type ConnectStartRequest, type ConnectStartResponse, type ControlRecord, type Delegation, type ExecutionFact, type Grant, type Harness, type HarnessReadiness, type HistoryRecord, type InstalledWorkflow, type RepositoryBinding, type RepositorySource, type RunCloseReason, type RunParent, type RunUsage, type RunView, type RunnerAdoptRequest, type RunnerDisconnectPreview, type RunnerDisconnectResponse, type RunnerFrame, type RunnerList, type RunnerListEntry, type RunnerReadiness, type RunsGoTo, SIZE_CLASS_CAPS, SIZE_CLASS_FORECASTS, type Scope, type SizeClass, type TeamDefault, type WorkflowIdentity, type WorkflowInstallReference, type WorkflowReference, abandonedConversationContinuationCapability, attemptCost, attemptForecast, audienceSchema, budgetCheck, buildCloseReasonSchema, calibrate, calibrationSchema, canonicalJson, checkpointPathSchema, checkpointSchema, classOfCap, clientFrameSchema, commandSchema, connectAlreadyConnectedSchema, connectApproveRequestSchema, connectCodeAlphabet, connectCodeRequestSchema, connectCodeResponseSchema, connectCodeSchema, connectDenyRequestSchema, connectPendingResponseSchema, connectPollRequestSchema, connectRedeemRequestSchema, connectRedeemResponseSchema, connectStartRequestSchema, connectStartResponseSchema, controlRecordSchema, conversationContinuationCapability, delegationSchema, delegationTokenPrefix, forecastOfCap, forecastOfClass, grantSchema, harnessReadinessSchema, harnessSchema, historyRecordSchema, hubEpochRequestSchema, installReference, installedWorkflowsSchema, interruptionSchema, permissionAnswerSchema, protocolVersion, readableHistory, readinessFixCommand, repositoryAccessCapability, repositoryBindingSchema, repositoryRefSchema, repositorySourceSchema, repositoryWorkingDirectorySchema, runArtifactMaxBytes, runArtifactNameSchema, runCloseReasonSchema, runDelegationCapability, runKeySchema, runParentIntentSchema, runParentSchema, runSpecSchema, runUsageCapability, runUsageSchema, runViewSchema, runnerAdoptRequestSchema, runnerDisconnectPreviewSchema, runnerDisconnectRequestSchema, runnerDisconnectResponseSchema, runnerFrameSchema, runnerListEntrySchema, runnerListSchema, runnerReadinessSchema, runnerUpdateCommand, runnerUpdateRequestSchema, runsGoToSchema, sameWorkflow, scopeSchema, secretEnvironmentSchema, sequence, teamDefaultRequestSchema, teamDefaultSchema, workflowIdentitySchema, workflowInstallCapability, workflowName, workflowReferenceSchema, workflowSourceSchema };
|
package/dist/v2.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-HMYWICNI.js";
|
|
4
4
|
|
|
5
5
|
// src/v2.ts
|
|
6
|
-
import { z } from "zod";
|
|
6
|
+
import { z as z2 } from "zod";
|
|
7
7
|
|
|
8
8
|
// src/history.ts
|
|
9
9
|
function readableHistory(records) {
|
|
@@ -48,6 +48,7 @@ function readableHistory(records) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// src/budget.ts
|
|
51
|
+
import { z } from "zod";
|
|
51
52
|
var SIZE_CLASS_CAPS = {
|
|
52
53
|
S: 3e6,
|
|
53
54
|
M: 6e6,
|
|
@@ -66,10 +67,47 @@ function classOfCap(declaredCap) {
|
|
|
66
67
|
function forecastOfCap(declaredCap) {
|
|
67
68
|
return SIZE_CLASS_FORECASTS[classOfCap(declaredCap)];
|
|
68
69
|
}
|
|
70
|
+
function attemptForecast(declaredCap) {
|
|
71
|
+
const forecast = forecastOfCap(declaredCap);
|
|
72
|
+
return declaredCap > 0 ? Math.min(declaredCap, forecast) : forecast;
|
|
73
|
+
}
|
|
69
74
|
function attemptCost(attempt) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return
|
|
75
|
+
const forecast = attemptForecast(attempt.tokenCap);
|
|
76
|
+
if (attempt.closed) return attempt.spent ?? forecast;
|
|
77
|
+
return Math.max(forecast, attempt.spent ?? 0);
|
|
78
|
+
}
|
|
79
|
+
function budgetCheck(input) {
|
|
80
|
+
const used = input.attempts.reduce((sum, attempt) => sum + attemptCost(attempt), 0);
|
|
81
|
+
return { used, fits: used + input.next <= input.tokenBudget };
|
|
82
|
+
}
|
|
83
|
+
var CALIBRATION_MIN_RUNS = 10;
|
|
84
|
+
var CALIBRATION_WINDOW_DAYS = 90;
|
|
85
|
+
function calibrate(samples) {
|
|
86
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
87
|
+
for (const { harness, sizeClass, counted } of samples) {
|
|
88
|
+
if (counted === void 0 || !Number.isFinite(counted) || counted < 0) continue;
|
|
89
|
+
const key = `${harness}\0${sizeClass}`;
|
|
90
|
+
const group = byKey.get(key) ?? { harness, sizeClass, counted: [] };
|
|
91
|
+
group.counted.push(counted);
|
|
92
|
+
byKey.set(key, group);
|
|
93
|
+
}
|
|
94
|
+
const result = {};
|
|
95
|
+
for (const { harness, sizeClass, counted } of byKey.values()) {
|
|
96
|
+
if (counted.length < CALIBRATION_MIN_RUNS) continue;
|
|
97
|
+
const sorted = [...counted].sort((a, b) => a - b);
|
|
98
|
+
const p90 = sorted[Math.ceil(sorted.length * 0.9) - 1];
|
|
99
|
+
(result[harness] ??= {})[sizeClass] = { forecast: Math.max(SIZE_CLASS_FORECASTS[sizeClass], p90), runs: sorted.length };
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
var classCalibrationSchema = z.strictObject({
|
|
104
|
+
S: z.strictObject({ forecast: z.number(), runs: z.number() }).optional(),
|
|
105
|
+
M: z.strictObject({ forecast: z.number(), runs: z.number() }).optional(),
|
|
106
|
+
L: z.strictObject({ forecast: z.number(), runs: z.number() }).optional()
|
|
107
|
+
});
|
|
108
|
+
var calibrationSchema = z.record(z.string(), classCalibrationSchema);
|
|
109
|
+
function forecastOfClass(sizeClass, calibration) {
|
|
110
|
+
return calibration?.[sizeClass]?.forecast ?? SIZE_CLASS_FORECASTS[sizeClass];
|
|
73
111
|
}
|
|
74
112
|
|
|
75
113
|
// src/v2.ts
|
|
@@ -81,29 +119,29 @@ var workflowInstallCapability = "workflow_install_v1";
|
|
|
81
119
|
var runDelegationCapability = "run_delegation_v1";
|
|
82
120
|
var runUsageCapability = "run_usage_v1";
|
|
83
121
|
var delegationTokenPrefix = "drisp_dlg_";
|
|
84
|
-
var runArtifactNameSchema =
|
|
122
|
+
var runArtifactNameSchema = z2.string().regex(/^[a-z][a-z0-9_]{0,63}$/);
|
|
85
123
|
var runArtifactMaxBytes = 64 * 1024;
|
|
86
|
-
var secretEnvironmentSchema =
|
|
87
|
-
|
|
88
|
-
|
|
124
|
+
var secretEnvironmentSchema = z2.record(
|
|
125
|
+
z2.string().regex(/^(?:OPENAI_API_KEY|ANTHROPIC_API_KEY|CLAUDE_CODE_OAUTH_TOKEN|NPM_TOKEN|NODE_AUTH_TOKEN|PIP_INDEX_URL|PIP_EXTRA_INDEX_URL|UV_INDEX_URL|DRISP_TEST_[A-Z0-9_]+)$/),
|
|
126
|
+
z2.string().regex(/^projects\/[a-zA-Z0-9-]+\/secrets\/[a-zA-Z0-9_-]+\/versions\/(?:latest|[0-9]+)$/)
|
|
89
127
|
);
|
|
90
|
-
var permissionAnswerSchema =
|
|
91
|
-
kind:
|
|
92
|
-
decision:
|
|
93
|
-
reason:
|
|
128
|
+
var permissionAnswerSchema = z2.strictObject({
|
|
129
|
+
kind: z2.literal("permission"),
|
|
130
|
+
decision: z2.enum(["allow", "deny"]),
|
|
131
|
+
reason: z2.string().max(4096).optional()
|
|
94
132
|
});
|
|
95
|
-
var id =
|
|
96
|
-
var sequence =
|
|
133
|
+
var id = z2.string().min(1).max(160);
|
|
134
|
+
var sequence = z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
97
135
|
var positive = sequence.refine((n) => n > 0);
|
|
98
|
-
var timestamp =
|
|
99
|
-
var scopeSchema =
|
|
100
|
-
|
|
101
|
-
|
|
136
|
+
var timestamp = z2.iso.datetime();
|
|
137
|
+
var scopeSchema = z2.discriminatedUnion("visibility", [
|
|
138
|
+
z2.strictObject({ visibility: z2.literal("organization") }),
|
|
139
|
+
z2.strictObject({ visibility: z2.literal("private"), ownerUserId: id })
|
|
102
140
|
]);
|
|
103
|
-
var installedWorkflowsSchema =
|
|
104
|
-
var harnessSchema =
|
|
105
|
-
var harnessReadinessSchema =
|
|
106
|
-
var runnerReadinessSchema =
|
|
141
|
+
var installedWorkflowsSchema = z2.array(InstalledWorkflowSchema).max(256);
|
|
142
|
+
var harnessSchema = z2.enum(["claude-code", "codex"]);
|
|
143
|
+
var harnessReadinessSchema = z2.strictObject({ installed: z2.boolean(), signedIn: z2.boolean() });
|
|
144
|
+
var runnerReadinessSchema = z2.strictObject({
|
|
107
145
|
"claude-code": harnessReadinessSchema.optional(),
|
|
108
146
|
codex: harnessReadinessSchema.optional()
|
|
109
147
|
});
|
|
@@ -118,25 +156,25 @@ function readinessFixCommand(harness, readiness) {
|
|
|
118
156
|
return void 0;
|
|
119
157
|
}
|
|
120
158
|
var runnerUpdateCommand = "npm i -g @drisp/cli";
|
|
121
|
-
var interruptionSchema =
|
|
159
|
+
var interruptionSchema = z2.strictObject({
|
|
122
160
|
interruptionId: id,
|
|
123
161
|
revision: positive,
|
|
124
162
|
/** `waiting` (root ADR-0008) is non-human: a Run parked until one of its children closes or parks. */
|
|
125
|
-
kind:
|
|
126
|
-
message:
|
|
163
|
+
kind: z2.enum(["permission", "question", "guidance", "recovery", "waiting"]),
|
|
164
|
+
message: z2.string().max(16384),
|
|
127
165
|
requestId: id.optional()
|
|
128
166
|
});
|
|
129
|
-
var workflowIdentitySchema =
|
|
130
|
-
name:
|
|
131
|
-
version:
|
|
167
|
+
var workflowIdentitySchema = z2.strictObject({
|
|
168
|
+
name: z2.string().min(1).max(128),
|
|
169
|
+
version: z2.string().min(1).max(128).optional()
|
|
132
170
|
});
|
|
133
|
-
var buildCloseReasonSchema =
|
|
171
|
+
var buildCloseReasonSchema = z2.enum([
|
|
134
172
|
"workflow_template_mismatch",
|
|
135
173
|
"child_project_dir_invalid",
|
|
136
174
|
"build_not_approved",
|
|
137
175
|
"approval_question_missing"
|
|
138
176
|
]);
|
|
139
|
-
var runCloseReasonSchema =
|
|
177
|
+
var runCloseReasonSchema = z2.enum([
|
|
140
178
|
"execution_terminal",
|
|
141
179
|
"cancelled_before_start",
|
|
142
180
|
"admission_failed",
|
|
@@ -159,48 +197,48 @@ var factIdentity = {
|
|
|
159
197
|
executionRevision: positive,
|
|
160
198
|
emittedAt: timestamp
|
|
161
199
|
};
|
|
162
|
-
var runUsageSchema =
|
|
200
|
+
var runUsageSchema = z2.strictObject({ counted: sequence, cacheRead: sequence });
|
|
163
201
|
var reportedUsage = { usage: runUsageSchema.optional() };
|
|
164
|
-
var controlRecordSchema =
|
|
202
|
+
var controlRecordSchema = z2.discriminatedUnion("kind", [
|
|
165
203
|
/** Instance-scoped, not tied to a Run: the full replacement inventory of installed Workflows. */
|
|
166
|
-
|
|
204
|
+
z2.strictObject({ kind: z2.literal("workflows.changed"), workflows: installedWorkflowsSchema }),
|
|
167
205
|
/** Instance-scoped, not tied to a Run: the Runner's full Readiness, sent when it changes after hello. */
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
kind:
|
|
206
|
+
z2.strictObject({ kind: z2.literal("readiness.changed"), readiness: runnerReadinessSchema }),
|
|
207
|
+
z2.strictObject({ kind: z2.literal("assignment.accepted"), runId: id, attemptId: id }),
|
|
208
|
+
z2.strictObject({
|
|
209
|
+
kind: z2.literal("assignment.rejected"),
|
|
172
210
|
runId: id,
|
|
173
211
|
attemptId: id,
|
|
174
|
-
reason:
|
|
212
|
+
reason: z2.string().max(1024)
|
|
175
213
|
}),
|
|
176
|
-
|
|
177
|
-
kind:
|
|
214
|
+
z2.strictObject({
|
|
215
|
+
kind: z2.literal("run.started"),
|
|
178
216
|
...factIdentity,
|
|
179
217
|
/** Absent from runners that predate Workflow reporting. */
|
|
180
218
|
workflow: workflowIdentitySchema.optional()
|
|
181
219
|
}),
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
kind:
|
|
220
|
+
z2.strictObject({ kind: z2.literal("run.resumed"), ...factIdentity }),
|
|
221
|
+
z2.strictObject({
|
|
222
|
+
kind: z2.literal("run.attention"),
|
|
185
223
|
...factIdentity,
|
|
186
224
|
interruption: interruptionSchema,
|
|
187
|
-
occupancy:
|
|
225
|
+
occupancy: z2.enum(["held", "released"]),
|
|
188
226
|
historyThrough: sequence,
|
|
189
|
-
continuation:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
227
|
+
continuation: z2.discriminatedUnion("kind", [
|
|
228
|
+
z2.strictObject({ kind: z2.literal("live_request") }),
|
|
229
|
+
z2.strictObject({ kind: z2.literal("local_checkpoint"), checkpointId: id }),
|
|
230
|
+
z2.strictObject({ kind: z2.literal("portable_checkpoint"), checkpointId: id }),
|
|
231
|
+
z2.strictObject({ kind: z2.literal("repair_required"), detail: z2.string().max(4096) })
|
|
194
232
|
]),
|
|
195
233
|
...reportedUsage
|
|
196
234
|
}),
|
|
197
|
-
|
|
198
|
-
kind:
|
|
235
|
+
z2.strictObject({
|
|
236
|
+
kind: z2.literal("run.finished"),
|
|
199
237
|
...factIdentity,
|
|
200
|
-
status:
|
|
238
|
+
status: z2.enum(["completed", "failed", "cancelled"]),
|
|
201
239
|
historyThrough: sequence,
|
|
202
240
|
/** No setup/harness executed and no workspace was produced; safe to retire without export. */
|
|
203
|
-
workspaceUnavailable:
|
|
241
|
+
workspaceUnavailable: z2.literal(true).optional(),
|
|
204
242
|
/**
|
|
205
243
|
* Why a Build Run failed, as its close reason (docs/specs/build-orchestrator.md). Sent only for a grant with
|
|
206
244
|
* `parent` or `delegationToken`, which only a Hub that knows this field issues.
|
|
@@ -212,85 +250,85 @@ var controlRecordSchema = z.discriminatedUnion("kind", [
|
|
|
212
250
|
* The usage of a Run while it executes, for a grant marked `reportUsage`. Not an execution fact: it carries no
|
|
213
251
|
* execution revision, so it never advances, parks or closes the Run, and never wakes its parent.
|
|
214
252
|
*/
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
kind:
|
|
253
|
+
z2.strictObject({ kind: z2.literal("run.usage"), runId: id, attemptId: id, ...runUsageSchema.shape }),
|
|
254
|
+
z2.strictObject({ kind: z2.literal("command.applied"), runId: id, attemptId: id, commandId: id }),
|
|
255
|
+
z2.strictObject({
|
|
256
|
+
kind: z2.literal("command.rejected"),
|
|
219
257
|
runId: id,
|
|
220
258
|
attemptId: id,
|
|
221
259
|
commandId: id,
|
|
222
|
-
reason:
|
|
260
|
+
reason: z2.string().max(1024)
|
|
223
261
|
}),
|
|
224
|
-
|
|
262
|
+
z2.strictObject({ kind: z2.literal("revoked_not_started"), runId: id, attemptId: id })
|
|
225
263
|
]);
|
|
226
|
-
var repositoryRefSchema =
|
|
264
|
+
var repositoryRefSchema = z2.string().min(1).max(512).regex(
|
|
227
265
|
/^(?![-/])(?!.*\.\.)(?!.*@\{)(?!.*(?:^|\/)\.)(?!.*\.lock(?:\/|$))(?!.*\/\/)[^\x00-\x20\x7f~^:?*\[\\]+(?<![/.])$/
|
|
228
266
|
);
|
|
229
|
-
var repositoryWorkingDirectorySchema =
|
|
267
|
+
var repositoryWorkingDirectorySchema = z2.string().min(1).max(1024).regex(
|
|
230
268
|
/^(?:\.|(?!\/)(?!.*(?:^|\/)\.\.?(?:\/|$))(?!.*(?:^|\/)\.git(?:\/|$))[^\x00-\x1f\x7f\\:]+(?<!\/))$/
|
|
231
269
|
);
|
|
232
270
|
var repositoryIdentity = {
|
|
233
|
-
repositoryId:
|
|
234
|
-
installationId:
|
|
235
|
-
owner:
|
|
236
|
-
name:
|
|
271
|
+
repositoryId: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
272
|
+
installationId: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
273
|
+
owner: z2.string().min(1).max(100).regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/),
|
|
274
|
+
name: z2.string().min(1).max(100).regex(/^(?!\.{1,2}$)[a-zA-Z0-9_.-]+$/)
|
|
237
275
|
};
|
|
238
|
-
var repositoryBindingSchema =
|
|
276
|
+
var repositoryBindingSchema = z2.strictObject({
|
|
239
277
|
id,
|
|
240
|
-
label:
|
|
278
|
+
label: z2.string().min(1).max(160),
|
|
241
279
|
...repositoryIdentity,
|
|
242
280
|
defaultRef: repositoryRefSchema,
|
|
243
281
|
workingDirectory: repositoryWorkingDirectorySchema,
|
|
244
|
-
setupCommands:
|
|
282
|
+
setupCommands: z2.array(z2.string().min(1).max(8192)).max(16),
|
|
245
283
|
revision: positive,
|
|
246
|
-
enabled:
|
|
284
|
+
enabled: z2.boolean()
|
|
247
285
|
});
|
|
248
|
-
var repositorySourceSchema =
|
|
286
|
+
var repositorySourceSchema = z2.strictObject({
|
|
249
287
|
bindingId: id,
|
|
250
288
|
...repositoryIdentity,
|
|
251
289
|
ref: repositoryRefSchema,
|
|
252
|
-
commitSha:
|
|
290
|
+
commitSha: z2.string().regex(/^[0-9a-f]{40}$/),
|
|
253
291
|
branch: repositoryRefSchema,
|
|
254
292
|
workingDirectory: repositoryWorkingDirectorySchema,
|
|
255
|
-
setupCommands:
|
|
293
|
+
setupCommands: z2.array(z2.string().min(1).max(8192)).max(16),
|
|
256
294
|
configRevision: positive
|
|
257
295
|
});
|
|
258
|
-
var workflowSourceSchema =
|
|
259
|
-
var workflowReferenceSchema =
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
name:
|
|
296
|
+
var workflowSourceSchema = z2.string().max(201).regex(/^[A-Za-z0-9][A-Za-z0-9_.-]*\/[A-Za-z0-9][A-Za-z0-9_.-]*$/);
|
|
297
|
+
var workflowReferenceSchema = z2.union([
|
|
298
|
+
z2.string().max(512),
|
|
299
|
+
z2.strictObject({
|
|
300
|
+
name: z2.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/),
|
|
263
301
|
source: workflowSourceSchema.optional(),
|
|
264
|
-
ref:
|
|
265
|
-
version:
|
|
302
|
+
ref: z2.string().min(1).max(512).optional(),
|
|
303
|
+
version: z2.string().min(1).max(128).regex(/^\d[A-Za-z0-9_.+-]*$/).optional()
|
|
266
304
|
})
|
|
267
305
|
]);
|
|
268
306
|
var workflowName = (workflow) => typeof workflow === "object" ? workflow.name : workflow;
|
|
269
307
|
var installReference = (workflow) => typeof workflow === "object" && workflow.source !== void 0 ? workflow : void 0;
|
|
270
308
|
var sameWorkflow = (a, b) => canonicalJson(a ?? null) === canonicalJson(b ?? null);
|
|
271
|
-
var runSpecSchema =
|
|
272
|
-
prompt:
|
|
273
|
-
projectDir:
|
|
309
|
+
var runSpecSchema = z2.strictObject({
|
|
310
|
+
prompt: z2.string().min(1).max(131072),
|
|
311
|
+
projectDir: z2.string().min(1).max(4096),
|
|
274
312
|
harness: harnessSchema,
|
|
275
313
|
workflow: workflowReferenceSchema.optional(),
|
|
276
314
|
repository: repositorySourceSchema.optional()
|
|
277
315
|
});
|
|
278
|
-
var runKeySchema =
|
|
279
|
-
var delegationSchema =
|
|
280
|
-
maxChildren:
|
|
281
|
-
tokenBudget:
|
|
316
|
+
var runKeySchema = z2.string().min(1).max(160);
|
|
317
|
+
var delegationSchema = z2.strictObject({
|
|
318
|
+
maxChildren: z2.number().int().min(1).max(8),
|
|
319
|
+
tokenBudget: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER)
|
|
282
320
|
});
|
|
283
|
-
var tokenCapSchema =
|
|
284
|
-
var runParentIntentSchema =
|
|
285
|
-
var runParentSchema =
|
|
286
|
-
var commandSchema =
|
|
321
|
+
var tokenCapSchema = z2.number().int().positive().max(Number.MAX_SAFE_INTEGER);
|
|
322
|
+
var runParentIntentSchema = z2.strictObject({ runId: id, tokenCap: tokenCapSchema.optional() });
|
|
323
|
+
var runParentSchema = z2.strictObject({ runId: id, tokenCap: tokenCapSchema });
|
|
324
|
+
var commandSchema = z2.strictObject({
|
|
287
325
|
commandId: id,
|
|
288
326
|
hubEpoch: id,
|
|
289
327
|
runId: id,
|
|
290
328
|
expectedRecordRevision: sequence.optional(),
|
|
291
|
-
intent:
|
|
292
|
-
|
|
293
|
-
kind:
|
|
329
|
+
intent: z2.discriminatedUnion("kind", [
|
|
330
|
+
z2.strictObject({
|
|
331
|
+
kind: z2.literal("start"),
|
|
294
332
|
sessionId: id,
|
|
295
333
|
/**
|
|
296
334
|
* Absent: the Hub resolves the Runner member-first (root ADR-0005): the Session's conversation Runner, else
|
|
@@ -306,24 +344,34 @@ var commandSchema = z.strictObject({
|
|
|
306
344
|
/** Delegated starts only, and required on them. */
|
|
307
345
|
parent: runParentIntentSchema.optional()
|
|
308
346
|
}),
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
kind:
|
|
347
|
+
z2.strictObject({ kind: z2.literal("cancel") }),
|
|
348
|
+
z2.strictObject({ kind: z2.literal("abandon") }),
|
|
349
|
+
z2.strictObject({ kind: z2.literal("steer"), text: z2.string().min(1).max(131072) }),
|
|
350
|
+
z2.strictObject({
|
|
351
|
+
kind: z2.literal("answer"),
|
|
314
352
|
interruptionId: id,
|
|
315
353
|
expectedInterruptionRevision: positive,
|
|
316
354
|
requestId: id.optional(),
|
|
317
|
-
answer:
|
|
355
|
+
answer: z2.json()
|
|
318
356
|
}),
|
|
319
|
-
|
|
320
|
-
kind:
|
|
357
|
+
z2.strictObject({
|
|
358
|
+
kind: z2.literal("resume"),
|
|
321
359
|
interruptionId: id,
|
|
322
|
-
guidance:
|
|
360
|
+
guidance: z2.string().max(131072).optional()
|
|
361
|
+
}),
|
|
362
|
+
/**
|
|
363
|
+
* A member rewrites an Orchestrator's `delegation.tokenBudget` (root ADR-0011), never below what its children
|
|
364
|
+
* used. With `resume`, a parked Orchestrator with no live child is resumed when the value is strictly greater.
|
|
365
|
+
* Hub-only: never delivered to a Runner.
|
|
366
|
+
*/
|
|
367
|
+
z2.strictObject({
|
|
368
|
+
kind: z2.literal("setBudget"),
|
|
369
|
+
tokenBudget: delegationSchema.shape.tokenBudget,
|
|
370
|
+
resume: z2.boolean().optional()
|
|
323
371
|
})
|
|
324
372
|
])
|
|
325
373
|
});
|
|
326
|
-
var grantSchema =
|
|
374
|
+
var grantSchema = z2.strictObject({
|
|
327
375
|
commandId: id,
|
|
328
376
|
hubEpoch: id,
|
|
329
377
|
runId: id,
|
|
@@ -335,121 +383,121 @@ var grantSchema = z.strictObject({
|
|
|
335
383
|
baseExecutionRevision: sequence,
|
|
336
384
|
baseHistorySeq: sequence,
|
|
337
385
|
cloudHistoryThrough: sequence,
|
|
338
|
-
purpose:
|
|
386
|
+
purpose: z2.enum(["start", "resume"]),
|
|
339
387
|
spec: runSpecSchema,
|
|
340
|
-
continuation:
|
|
388
|
+
continuation: z2.json().optional(),
|
|
341
389
|
/** A new Run in a durable conversation; never resumes the predecessor's lifecycle. */
|
|
342
|
-
previousRun:
|
|
390
|
+
previousRun: z2.strictObject({
|
|
343
391
|
runId: id,
|
|
344
392
|
executionRevision: sequence,
|
|
345
393
|
historyProduced: sequence,
|
|
346
394
|
/** Hub-confirmed administrative closure; allows an exact parked predecessor snapshot. */
|
|
347
|
-
closeReason:
|
|
348
|
-
checkpoint:
|
|
395
|
+
closeReason: z2.literal("abandoned").optional(),
|
|
396
|
+
checkpoint: z2.strictObject({ checkpointId: id, checksum: z2.string().regex(/^[a-f0-9]{64}$/) }).optional()
|
|
349
397
|
}).optional(),
|
|
350
|
-
checkpoint:
|
|
398
|
+
checkpoint: z2.strictObject({ checkpointId: id, checksum: z2.string().regex(/^[a-f0-9]{64}$/) }).optional(),
|
|
351
399
|
/** This attempt's delegation token: only for a Run started with `delegation`, only to a `run_delegation_v1` Runner. */
|
|
352
|
-
delegationToken:
|
|
400
|
+
delegationToken: z2.string().min(32).max(256).optional(),
|
|
353
401
|
/** Copied from the start intent of a delegated child. */
|
|
354
402
|
parent: runParentSchema.optional(),
|
|
355
403
|
/** The runner reports this attempt's usage: set only for a `run_usage_v1` Runner. */
|
|
356
|
-
reportUsage:
|
|
404
|
+
reportUsage: z2.literal(true).optional()
|
|
357
405
|
});
|
|
358
|
-
var historyRecordSchema =
|
|
406
|
+
var historyRecordSchema = z2.strictObject({
|
|
359
407
|
eventId: id,
|
|
360
408
|
attemptId: id,
|
|
361
409
|
emittedAt: timestamp,
|
|
362
|
-
kind:
|
|
363
|
-
data:
|
|
410
|
+
kind: z2.string().min(1).max(128),
|
|
411
|
+
data: z2.json()
|
|
364
412
|
});
|
|
365
|
-
var runnerFrameSchema =
|
|
366
|
-
|
|
367
|
-
type:
|
|
368
|
-
role:
|
|
369
|
-
protocol:
|
|
413
|
+
var runnerFrameSchema = z2.discriminatedUnion("type", [
|
|
414
|
+
z2.strictObject({
|
|
415
|
+
type: z2.literal("hello"),
|
|
416
|
+
role: z2.literal("runner"),
|
|
417
|
+
protocol: z2.strictObject({ major: z2.literal(2), minor: sequence }),
|
|
370
418
|
runnerId: id,
|
|
371
419
|
installationId: id,
|
|
372
|
-
softwareVersion:
|
|
373
|
-
capabilities:
|
|
420
|
+
softwareVersion: z2.string().max(128),
|
|
421
|
+
capabilities: z2.array(z2.string().max(128)).max(64),
|
|
374
422
|
/** Absent from older runners: the Hub treats the inventory as unknown, never as empty. */
|
|
375
423
|
workflows: installedWorkflowsSchema.optional(),
|
|
376
424
|
/** Absent from older runners, and from a runner that has not finished its first check: unknown, not "not ready". */
|
|
377
425
|
readiness: runnerReadinessSchema.optional(),
|
|
378
|
-
control:
|
|
426
|
+
control: z2.strictObject({ firstRetainedSeq: positive, lastProducedSeq: sequence })
|
|
379
427
|
}),
|
|
380
|
-
|
|
381
|
-
type:
|
|
428
|
+
z2.strictObject({
|
|
429
|
+
type: z2.literal("control.batch"),
|
|
382
430
|
firstSeq: positive,
|
|
383
|
-
records:
|
|
431
|
+
records: z2.array(controlRecordSchema).min(1).max(128)
|
|
384
432
|
}),
|
|
385
|
-
|
|
386
|
-
type:
|
|
433
|
+
z2.strictObject({
|
|
434
|
+
type: z2.literal("history.batch"),
|
|
387
435
|
runId: id,
|
|
388
436
|
firstSeq: positive,
|
|
389
|
-
records:
|
|
437
|
+
records: z2.array(historyRecordSchema).min(1).max(128)
|
|
390
438
|
}),
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
type:
|
|
439
|
+
z2.strictObject({ type: z2.literal("ping"), nonce: id }),
|
|
440
|
+
z2.strictObject({
|
|
441
|
+
type: z2.literal("reconcile.page"),
|
|
394
442
|
inventoryId: id.default("single-page"),
|
|
395
443
|
page: sequence.default(0),
|
|
396
|
-
complete:
|
|
397
|
-
runs:
|
|
398
|
-
|
|
444
|
+
complete: z2.boolean(),
|
|
445
|
+
runs: z2.array(
|
|
446
|
+
z2.strictObject({
|
|
399
447
|
runId: id,
|
|
400
448
|
attemptId: id,
|
|
401
449
|
executionRevision: sequence,
|
|
402
|
-
phase:
|
|
450
|
+
phase: z2.enum(["admitted", "prepared", "executing", "parked", "terminal", "recovery"])
|
|
403
451
|
})
|
|
404
452
|
).max(128)
|
|
405
453
|
})
|
|
406
454
|
]);
|
|
407
|
-
var runViewSchema =
|
|
455
|
+
var runViewSchema = z2.object({
|
|
408
456
|
runId: id,
|
|
409
457
|
sessionId: id,
|
|
410
458
|
runnerId: id,
|
|
411
459
|
computeProfileId: id.optional(),
|
|
412
460
|
scope: scopeSchema,
|
|
413
461
|
recordRevision: positive,
|
|
414
|
-
label:
|
|
462
|
+
label: z2.string().max(160).optional(),
|
|
415
463
|
key: runKeySchema.optional(),
|
|
416
464
|
parent: runParentSchema.optional(),
|
|
417
465
|
/**
|
|
418
466
|
* Not strict, unlike the start intent's: a Hub keeps more on the Run's delegation (`initialTokenBudget`) than it
|
|
419
467
|
* shows, and a client never refuses a view for a field it does not read.
|
|
420
468
|
*/
|
|
421
|
-
delegation:
|
|
469
|
+
delegation: z2.object(delegationSchema.shape).optional(),
|
|
422
470
|
/** The largest cumulative usage the Run's Runner reported; absent until one does (an older Runner never does). */
|
|
423
471
|
usage: runUsageSchema.optional(),
|
|
424
472
|
/** Resolved by the runner at start; absent until the Run starts and for runners that predate reporting. */
|
|
425
473
|
workflow: workflowIdentitySchema.optional(),
|
|
426
|
-
execution:
|
|
427
|
-
status:
|
|
474
|
+
execution: z2.object({
|
|
475
|
+
status: z2.enum(["running", "awaiting_attention", "completed", "failed", "cancelled"]),
|
|
428
476
|
revision: positive,
|
|
429
477
|
attemptId: id,
|
|
430
|
-
occupancy:
|
|
478
|
+
occupancy: z2.enum(["held", "released"]),
|
|
431
479
|
startedAt: timestamp.optional(),
|
|
432
480
|
endedAt: timestamp.optional(),
|
|
433
481
|
interruption: interruptionSchema.optional()
|
|
434
482
|
}).nullable(),
|
|
435
|
-
scheduling:
|
|
436
|
-
closed:
|
|
437
|
-
closeReason:
|
|
483
|
+
scheduling: z2.enum(["queued", "dispatching", "admitted", "idle"]),
|
|
484
|
+
closed: z2.boolean(),
|
|
485
|
+
closeReason: z2.string().optional(),
|
|
438
486
|
cancellation: id.optional(),
|
|
439
487
|
pendingResume: commandSchema.shape.intent.optional(),
|
|
440
488
|
/** Derived per viewer; absent on older Hubs. Never grants execution authority. */
|
|
441
|
-
runnerStopped:
|
|
442
|
-
canAbandon:
|
|
489
|
+
runnerStopped: z2.boolean().optional(),
|
|
490
|
+
canAbandon: z2.boolean().optional(),
|
|
443
491
|
historyThrough: sequence,
|
|
444
492
|
expectedHistoryThrough: sequence.optional(),
|
|
445
493
|
createdAt: sequence,
|
|
446
|
-
checkpoint:
|
|
494
|
+
checkpoint: z2.object({ id, state: z2.enum(["pending", "ready"]), checksum: z2.string().optional() }).optional()
|
|
447
495
|
});
|
|
448
|
-
var clientFrameSchema =
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
496
|
+
var clientFrameSchema = z2.discriminatedUnion("type", [
|
|
497
|
+
z2.strictObject({ type: z2.literal("watch"), hubEpoch: id, runIds: z2.array(id).max(100) }),
|
|
498
|
+
z2.strictObject({ type: z2.literal("watch.ack"), subscriptionId: id, through: sequence }),
|
|
499
|
+
z2.strictObject({ type: z2.literal("command.submit"), command: commandSchema }),
|
|
500
|
+
z2.strictObject({ type: z2.literal("ping"), nonce: id })
|
|
453
501
|
]);
|
|
454
502
|
function canonicalJson(value) {
|
|
455
503
|
if (value === null || typeof value !== "object") {
|
|
@@ -460,76 +508,76 @@ function canonicalJson(value) {
|
|
|
460
508
|
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
461
509
|
return `{${Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(",")}}`;
|
|
462
510
|
}
|
|
463
|
-
var checkpointPathSchema =
|
|
511
|
+
var checkpointPathSchema = z2.string().min(1).max(4096).refine(
|
|
464
512
|
(path) => !path.startsWith("/") && !path.includes("\\") && path.split("/").every((part) => part !== "" && part !== "." && part !== ".." && part !== ".git")
|
|
465
513
|
);
|
|
466
|
-
var checkpointSchema =
|
|
467
|
-
version:
|
|
468
|
-
checkpointId:
|
|
469
|
-
orgId:
|
|
470
|
-
phase:
|
|
471
|
-
runId:
|
|
472
|
-
sessionId:
|
|
473
|
-
sourceAttemptId:
|
|
474
|
-
executionRevision:
|
|
475
|
-
historyProduced:
|
|
476
|
-
historyAck:
|
|
514
|
+
var checkpointSchema = z2.strictObject({
|
|
515
|
+
version: z2.literal(1),
|
|
516
|
+
checkpointId: z2.string().min(1),
|
|
517
|
+
orgId: z2.string().min(1),
|
|
518
|
+
phase: z2.enum(["parked", "terminal"]),
|
|
519
|
+
runId: z2.string().min(1),
|
|
520
|
+
sessionId: z2.string().min(1),
|
|
521
|
+
sourceAttemptId: z2.string().min(1),
|
|
522
|
+
executionRevision: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
523
|
+
historyProduced: z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
524
|
+
historyAck: z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
477
525
|
grant: grantSchema,
|
|
478
|
-
gitHead:
|
|
479
|
-
gitBase:
|
|
480
|
-
gitBundle:
|
|
481
|
-
indexPatch:
|
|
482
|
-
files:
|
|
483
|
-
|
|
526
|
+
gitHead: z2.string().regex(/^[0-9a-f]{40,64}$/),
|
|
527
|
+
gitBase: z2.string().regex(/^[0-9a-f]{40,64}$/).optional(),
|
|
528
|
+
gitBundle: z2.string(),
|
|
529
|
+
indexPatch: z2.string(),
|
|
530
|
+
files: z2.array(
|
|
531
|
+
z2.strictObject({ path: checkpointPathSchema, content: z2.string(), executable: z2.boolean() })
|
|
484
532
|
).max(1e5),
|
|
485
|
-
deleted:
|
|
486
|
-
sessionRows:
|
|
487
|
-
history:
|
|
488
|
-
|
|
533
|
+
deleted: z2.array(checkpointPathSchema).max(1e5),
|
|
534
|
+
sessionRows: z2.array(z2.strictObject({ kind: z2.string(), id: z2.string(), payload: z2.string() })),
|
|
535
|
+
history: z2.array(
|
|
536
|
+
z2.strictObject({ seq: z2.number().int().positive(), record: historyRecordSchema })
|
|
489
537
|
)
|
|
490
538
|
});
|
|
491
539
|
var connectCodeAlphabet = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
|
|
492
|
-
var connectCodeSchema =
|
|
493
|
-
var connectCodeRequestSchema =
|
|
494
|
-
var connectCodeResponseSchema =
|
|
540
|
+
var connectCodeSchema = z2.string().regex(/^[A-HJKMNP-Z2-9]{8}$/);
|
|
541
|
+
var connectCodeRequestSchema = z2.strictObject({ hubEpoch: z2.string() });
|
|
542
|
+
var connectCodeResponseSchema = z2.strictObject({
|
|
495
543
|
code: connectCodeSchema,
|
|
496
544
|
expiresAt: sequence
|
|
497
545
|
});
|
|
498
|
-
var connectRedeemRequestSchema =
|
|
499
|
-
code:
|
|
546
|
+
var connectRedeemRequestSchema = z2.strictObject({
|
|
547
|
+
code: z2.string().min(8).max(16),
|
|
500
548
|
installationId: id,
|
|
501
|
-
hostname:
|
|
502
|
-
os:
|
|
503
|
-
softwareVersion:
|
|
549
|
+
hostname: z2.string().min(1).max(255),
|
|
550
|
+
os: z2.string().min(1).max(64),
|
|
551
|
+
softwareVersion: z2.string().min(1).max(128)
|
|
504
552
|
});
|
|
505
|
-
var connectRedeemResponseSchema =
|
|
553
|
+
var connectRedeemResponseSchema = z2.strictObject({
|
|
506
554
|
orgId: id,
|
|
507
|
-
hubEpoch:
|
|
555
|
+
hubEpoch: z2.string(),
|
|
508
556
|
runnerId: id,
|
|
509
557
|
installationId: id,
|
|
510
|
-
name:
|
|
511
|
-
token:
|
|
558
|
+
name: z2.string(),
|
|
559
|
+
token: z2.string().min(32),
|
|
512
560
|
credentialId: id,
|
|
513
561
|
expiresAt: sequence
|
|
514
562
|
});
|
|
515
|
-
var connectAlreadyConnectedSchema =
|
|
516
|
-
error:
|
|
563
|
+
var connectAlreadyConnectedSchema = z2.strictObject({
|
|
564
|
+
error: z2.literal("runner_already_connected"),
|
|
517
565
|
orgId: id,
|
|
518
566
|
runnerId: id,
|
|
519
|
-
name:
|
|
567
|
+
name: z2.string()
|
|
520
568
|
});
|
|
521
|
-
var audienceSchema =
|
|
522
|
-
var runnerListEntrySchema =
|
|
569
|
+
var audienceSchema = z2.enum(["personal", "team"]);
|
|
570
|
+
var runnerListEntrySchema = z2.object({
|
|
523
571
|
id,
|
|
524
|
-
online:
|
|
525
|
-
capacity:
|
|
526
|
-
managed:
|
|
527
|
-
draining:
|
|
528
|
-
stopped:
|
|
529
|
-
name:
|
|
530
|
-
connectedBy:
|
|
572
|
+
online: z2.number(),
|
|
573
|
+
capacity: z2.number(),
|
|
574
|
+
managed: z2.number(),
|
|
575
|
+
draining: z2.number(),
|
|
576
|
+
stopped: z2.number(),
|
|
577
|
+
name: z2.string().nullable(),
|
|
578
|
+
connectedBy: z2.string().nullable(),
|
|
531
579
|
audience: audienceSchema.nullable(),
|
|
532
|
-
softwareVersion:
|
|
580
|
+
softwareVersion: z2.string().nullable(),
|
|
533
581
|
/** Milliseconds since the epoch of the last hello or disconnect; null before the first connection. */
|
|
534
582
|
lastSeen: sequence.nullable(),
|
|
535
583
|
/** Absent when the runner has not reported an inventory: unknown, not none. */
|
|
@@ -539,115 +587,121 @@ var runnerListEntrySchema = z.object({
|
|
|
539
587
|
* Runner seen by an admin (who may still Disconnect it), or a Runner a member did not connect. Absent from Hubs
|
|
540
588
|
* older than Audience, like the list's `viewer`, `teamDefault` and `runsGoTo`.
|
|
541
589
|
*/
|
|
542
|
-
readOnly:
|
|
590
|
+
readOnly: z2.boolean().optional(),
|
|
543
591
|
/** What the Runner last reported; absent when it never has (an older runner, or one not yet connected). */
|
|
544
592
|
readiness: runnerReadinessSchema.optional(),
|
|
545
593
|
/**
|
|
546
594
|
* True when the Runner reported a version below the Hub's minimum: it is listed as "Update required" and takes no
|
|
547
595
|
* Runs until it is updated (`runnerUpdateCommand`). Absent from Hubs older than Readiness.
|
|
548
596
|
*/
|
|
549
|
-
updateRequired:
|
|
597
|
+
updateRequired: z2.boolean().optional(),
|
|
550
598
|
/**
|
|
551
599
|
* True while it is paused as "Needs an owner": the member who connected this Team Runner left the Team, so it
|
|
552
600
|
* takes no Runs until an admin adopts it (`/runners/{id}/adopt`) or Disconnects it. Absent from older Hubs.
|
|
553
601
|
*/
|
|
554
|
-
needsOwner:
|
|
602
|
+
needsOwner: z2.boolean().optional()
|
|
555
603
|
});
|
|
556
|
-
var teamDefaultSchema =
|
|
557
|
-
|
|
558
|
-
|
|
604
|
+
var teamDefaultSchema = z2.discriminatedUnion("kind", [
|
|
605
|
+
z2.strictObject({ kind: z2.literal("runner"), runnerId: id }),
|
|
606
|
+
z2.strictObject({ kind: z2.literal("profile"), profileId: id })
|
|
559
607
|
]);
|
|
560
|
-
var teamDefaultRequestSchema =
|
|
561
|
-
hubEpoch:
|
|
608
|
+
var teamDefaultRequestSchema = z2.strictObject({
|
|
609
|
+
hubEpoch: z2.string(),
|
|
562
610
|
teamDefault: teamDefaultSchema.nullable()
|
|
563
611
|
});
|
|
564
|
-
var runnerUpdateRequestSchema =
|
|
565
|
-
hubEpoch:
|
|
566
|
-
name:
|
|
567
|
-
capacity:
|
|
612
|
+
var runnerUpdateRequestSchema = z2.strictObject({
|
|
613
|
+
hubEpoch: z2.string(),
|
|
614
|
+
name: z2.string().max(100).optional(),
|
|
615
|
+
capacity: z2.number().int().min(1).max(64).optional(),
|
|
568
616
|
audience: audienceSchema.optional()
|
|
569
617
|
}).refine(
|
|
570
618
|
(update) => update.name !== void 0 || update.capacity !== void 0 || update.audience !== void 0,
|
|
571
619
|
{ message: "nothing to update" }
|
|
572
620
|
);
|
|
573
|
-
var runsGoToSchema =
|
|
621
|
+
var runsGoToSchema = z2.union([
|
|
574
622
|
/** The viewer's own Runner: Personal, or one they connected that was widened to Team (DRI-42). */
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
623
|
+
z2.strictObject({ via: z2.literal("personal"), runnerId: id }),
|
|
624
|
+
z2.strictObject({ via: z2.literal("team_default"), runnerId: id }),
|
|
625
|
+
z2.strictObject({ via: z2.literal("team_default"), profileId: id }),
|
|
578
626
|
/** `runner_needs_owner`: the Team default is a Runner paused because the member who connected it left. */
|
|
579
|
-
|
|
627
|
+
z2.strictObject({ via: z2.literal("none"), reason: z2.enum(["no_runner_available", "runner_needs_owner"]) })
|
|
580
628
|
]);
|
|
581
|
-
var runnerListSchema =
|
|
582
|
-
capabilities:
|
|
583
|
-
historyRetentionDays:
|
|
629
|
+
var runnerListSchema = z2.object({
|
|
630
|
+
capabilities: z2.record(z2.string(), z2.boolean()).optional(),
|
|
631
|
+
historyRetentionDays: z2.number().int().positive().nullable().optional(),
|
|
584
632
|
/** Who the list was filtered for: a member sees their own and Team Runners, an admin every Runner. */
|
|
585
|
-
viewer:
|
|
633
|
+
viewer: z2.object({ userId: z2.string(), admin: z2.boolean() }).optional(),
|
|
586
634
|
teamDefault: teamDefaultSchema.nullable().optional(),
|
|
587
635
|
runsGoTo: runsGoToSchema.optional(),
|
|
588
636
|
/** The lowest Runner version this Hub sends Runs to. Absent from Hubs older than Readiness. */
|
|
589
|
-
minimumRunnerVersion:
|
|
590
|
-
runners:
|
|
591
|
-
profiles:
|
|
592
|
-
id:
|
|
593
|
-
label:
|
|
594
|
-
projectDir:
|
|
595
|
-
repositoryRequired:
|
|
637
|
+
minimumRunnerVersion: z2.string().optional(),
|
|
638
|
+
runners: z2.array(runnerListEntrySchema),
|
|
639
|
+
profiles: z2.array(z2.object({
|
|
640
|
+
id: z2.string(),
|
|
641
|
+
label: z2.string(),
|
|
642
|
+
projectDir: z2.string(),
|
|
643
|
+
repositoryRequired: z2.boolean().optional(),
|
|
596
644
|
/** Marketplace refs baked into the profile's image; absent when the profile declares none. */
|
|
597
|
-
workflows:
|
|
598
|
-
workflowSources:
|
|
645
|
+
workflows: z2.array(z2.string()).optional(),
|
|
646
|
+
workflowSources: z2.array(z2.string()).optional()
|
|
599
647
|
}))
|
|
600
648
|
});
|
|
601
|
-
var runnerDisconnectRequestSchema =
|
|
649
|
+
var runnerDisconnectRequestSchema = z2.strictObject({ hubEpoch: z2.string() });
|
|
602
650
|
var hubEpochRequestSchema = runnerDisconnectRequestSchema;
|
|
603
|
-
var runnerDisconnectPreviewSchema =
|
|
651
|
+
var runnerDisconnectPreviewSchema = z2.object({
|
|
604
652
|
runnerId: id,
|
|
605
|
-
name:
|
|
606
|
-
runs:
|
|
653
|
+
name: z2.string().nullable(),
|
|
654
|
+
runs: z2.array(z2.object({
|
|
607
655
|
runId: id,
|
|
608
|
-
label:
|
|
656
|
+
label: z2.string().optional(),
|
|
609
657
|
/** Working: executing now. Parked: waiting for a person, Runner released. Queued: not started yet. */
|
|
610
|
-
state:
|
|
658
|
+
state: z2.enum(["working", "parked", "queued"])
|
|
611
659
|
})),
|
|
612
|
-
hiddenRuns:
|
|
660
|
+
hiddenRuns: z2.number().int().nonnegative()
|
|
613
661
|
});
|
|
614
|
-
var runnerDisconnectResponseSchema =
|
|
615
|
-
disconnected:
|
|
662
|
+
var runnerDisconnectResponseSchema = z2.object({
|
|
663
|
+
disconnected: z2.literal(true),
|
|
616
664
|
/** How many Runs were Stopped with the reason `runner_disconnected`. */
|
|
617
|
-
stoppedRuns:
|
|
665
|
+
stoppedRuns: z2.number().int().nonnegative()
|
|
618
666
|
});
|
|
619
667
|
var runnerAdoptRequestSchema = hubEpochRequestSchema;
|
|
620
668
|
var connectStartRequestSchema = connectRedeemRequestSchema.omit({ code: true });
|
|
621
|
-
var connectStartResponseSchema =
|
|
669
|
+
var connectStartResponseSchema = z2.strictObject({
|
|
622
670
|
/** The machine's secret for polling; never shown. */
|
|
623
|
-
deviceCode:
|
|
671
|
+
deviceCode: z2.string().min(32).max(160),
|
|
624
672
|
code: connectCodeSchema,
|
|
625
673
|
expiresAt: sequence,
|
|
626
|
-
intervalSec:
|
|
674
|
+
intervalSec: z2.number().int().positive(),
|
|
627
675
|
/** The web console page that approves `code`. */
|
|
628
|
-
verificationUrl:
|
|
676
|
+
verificationUrl: z2.string().url()
|
|
629
677
|
});
|
|
630
|
-
var connectPollRequestSchema =
|
|
631
|
-
var connectPendingResponseSchema =
|
|
632
|
-
hostname:
|
|
633
|
-
os:
|
|
634
|
-
softwareVersion:
|
|
678
|
+
var connectPollRequestSchema = z2.strictObject({ deviceCode: z2.string().min(32).max(160) });
|
|
679
|
+
var connectPendingResponseSchema = z2.strictObject({
|
|
680
|
+
hostname: z2.string(),
|
|
681
|
+
os: z2.string(),
|
|
682
|
+
softwareVersion: z2.string(),
|
|
635
683
|
requestedAt: sequence,
|
|
636
684
|
expiresAt: sequence
|
|
637
685
|
});
|
|
638
|
-
var connectApproveRequestSchema =
|
|
639
|
-
code:
|
|
686
|
+
var connectApproveRequestSchema = z2.strictObject({
|
|
687
|
+
code: z2.string().min(8).max(16),
|
|
640
688
|
audience: audienceSchema,
|
|
641
|
-
hubEpoch:
|
|
689
|
+
hubEpoch: z2.string().optional()
|
|
642
690
|
});
|
|
643
|
-
var connectDenyRequestSchema =
|
|
691
|
+
var connectDenyRequestSchema = z2.strictObject({ code: z2.string().min(8).max(16) });
|
|
644
692
|
export {
|
|
693
|
+
CALIBRATION_MIN_RUNS,
|
|
694
|
+
CALIBRATION_WINDOW_DAYS,
|
|
645
695
|
SIZE_CLASS_CAPS,
|
|
646
696
|
SIZE_CLASS_FORECASTS,
|
|
647
697
|
abandonedConversationContinuationCapability,
|
|
648
698
|
attemptCost,
|
|
699
|
+
attemptForecast,
|
|
649
700
|
audienceSchema,
|
|
701
|
+
budgetCheck,
|
|
650
702
|
buildCloseReasonSchema,
|
|
703
|
+
calibrate,
|
|
704
|
+
calibrationSchema,
|
|
651
705
|
canonicalJson,
|
|
652
706
|
checkpointPathSchema,
|
|
653
707
|
checkpointSchema,
|
|
@@ -672,6 +726,7 @@ export {
|
|
|
672
726
|
delegationSchema,
|
|
673
727
|
delegationTokenPrefix,
|
|
674
728
|
forecastOfCap,
|
|
729
|
+
forecastOfClass,
|
|
675
730
|
grantSchema,
|
|
676
731
|
harnessReadinessSchema,
|
|
677
732
|
harnessSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drisp/protocol",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.6",
|
|
4
4
|
"description": "Wire contract between a drisp runner and the hub: zod schemas, inferred types, and JSON Schema for the instance-socket frames, Run, Turn, Interruption, and the event stream",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
package/schema/v2/client.json
CHANGED
|
@@ -448,6 +448,28 @@
|
|
|
448
448
|
"interruptionId"
|
|
449
449
|
],
|
|
450
450
|
"additionalProperties": false
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"type": "object",
|
|
454
|
+
"properties": {
|
|
455
|
+
"kind": {
|
|
456
|
+
"type": "string",
|
|
457
|
+
"const": "setBudget"
|
|
458
|
+
},
|
|
459
|
+
"tokenBudget": {
|
|
460
|
+
"type": "integer",
|
|
461
|
+
"exclusiveMinimum": 0,
|
|
462
|
+
"maximum": 9007199254740991
|
|
463
|
+
},
|
|
464
|
+
"resume": {
|
|
465
|
+
"type": "boolean"
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
"required": [
|
|
469
|
+
"kind",
|
|
470
|
+
"tokenBudget"
|
|
471
|
+
],
|
|
472
|
+
"additionalProperties": false
|
|
451
473
|
}
|
|
452
474
|
]
|
|
453
475
|
}
|
package/schema/v2/command.json
CHANGED
|
@@ -385,6 +385,28 @@
|
|
|
385
385
|
"interruptionId"
|
|
386
386
|
],
|
|
387
387
|
"additionalProperties": false
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"type": "object",
|
|
391
|
+
"properties": {
|
|
392
|
+
"kind": {
|
|
393
|
+
"type": "string",
|
|
394
|
+
"const": "setBudget"
|
|
395
|
+
},
|
|
396
|
+
"tokenBudget": {
|
|
397
|
+
"type": "integer",
|
|
398
|
+
"exclusiveMinimum": 0,
|
|
399
|
+
"maximum": 9007199254740991
|
|
400
|
+
},
|
|
401
|
+
"resume": {
|
|
402
|
+
"type": "boolean"
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
"required": [
|
|
406
|
+
"kind",
|
|
407
|
+
"tokenBudget"
|
|
408
|
+
],
|
|
409
|
+
"additionalProperties": false
|
|
388
410
|
}
|
|
389
411
|
]
|
|
390
412
|
}
|
package/schema/v2/run.json
CHANGED
|
@@ -631,6 +631,28 @@
|
|
|
631
631
|
"interruptionId"
|
|
632
632
|
],
|
|
633
633
|
"additionalProperties": false
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
"type": "object",
|
|
637
|
+
"properties": {
|
|
638
|
+
"kind": {
|
|
639
|
+
"type": "string",
|
|
640
|
+
"const": "setBudget"
|
|
641
|
+
},
|
|
642
|
+
"tokenBudget": {
|
|
643
|
+
"type": "integer",
|
|
644
|
+
"exclusiveMinimum": 0,
|
|
645
|
+
"maximum": 9007199254740991
|
|
646
|
+
},
|
|
647
|
+
"resume": {
|
|
648
|
+
"type": "boolean"
|
|
649
|
+
}
|
|
650
|
+
},
|
|
651
|
+
"required": [
|
|
652
|
+
"kind",
|
|
653
|
+
"tokenBudget"
|
|
654
|
+
],
|
|
655
|
+
"additionalProperties": false
|
|
634
656
|
}
|
|
635
657
|
]
|
|
636
658
|
},
|