@drisp/protocol 0.8.3 → 0.8.5

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 CHANGED
@@ -26,10 +26,50 @@ declare function attemptCost(attempt: {
26
26
  tokenCap: number;
27
27
  closed: boolean;
28
28
  }): number;
29
+ /** A class needs this many finished Runs of a harness before its forecast is measured (DRI-244). */
30
+ declare const CALIBRATION_MIN_RUNS = 10;
31
+ /** Only Runs closed within this many days count. */
32
+ declare const CALIBRATION_WINDOW_DAYS = 90;
33
+ /** What one size class measured to: the figure the plan uses, and how many finished Runs it rests on. */
34
+ type ClassCalibration = Readonly<Partial<Record<SizeClass, {
35
+ forecast: number;
36
+ runs: number;
37
+ }>>>;
38
+ /** The measured classes per harness name; a harness or class with too few Runs is absent. */
39
+ type Calibration = Readonly<Partial<Record<string, ClassCalibration>>>;
40
+ /** One finished Run's final counted tokens (cache reads excluded), by its harness and the class its cap belongs to. */
41
+ type CalibrationSample = {
42
+ harness: string;
43
+ sizeClass: SizeClass;
44
+ counted: number | undefined;
45
+ };
46
+ /**
47
+ * The forecast of each class and harness with at least `CALIBRATION_MIN_RUNS` samples: max(constant, p90 of the
48
+ * samples), the p90 by nearest rank. The constants are the floor, so calibration only raises a forecast. A sample with
49
+ * no figure is ignored. Which Runs are samples (completed, first attempt, in the window) is the Hub's to say.
50
+ */
51
+ declare function calibrate(samples: readonly CalibrationSample[]): Calibration;
52
+ /** `GET /calibration`: the measured classes per harness name. */
53
+ declare const calibrationSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
54
+ S: z.ZodOptional<z.ZodObject<{
55
+ forecast: z.ZodNumber;
56
+ runs: z.ZodNumber;
57
+ }, z.core.$strict>>;
58
+ M: z.ZodOptional<z.ZodObject<{
59
+ forecast: z.ZodNumber;
60
+ runs: z.ZodNumber;
61
+ }, z.core.$strict>>;
62
+ L: z.ZodOptional<z.ZodObject<{
63
+ forecast: z.ZodNumber;
64
+ runs: z.ZodNumber;
65
+ }, z.core.$strict>>;
66
+ }, z.core.$strict>>;
67
+ /** A class's forecast: its measured figure when `calibration` has one, else the constant. */
68
+ declare function forecastOfClass(sizeClass: SizeClass, calibration: ClassCalibration | undefined): number;
29
69
 
30
70
  declare const protocolVersion: {
31
71
  readonly major: 2;
32
- readonly minor: 2;
72
+ readonly minor: 3;
33
73
  };
34
74
  declare const conversationContinuationCapability = "conversation_continuation";
35
75
  declare const abandonedConversationContinuationCapability = "abandoned_conversation_continuation";
@@ -41,6 +81,12 @@ declare const workflowInstallCapability = "workflow_install_v1";
41
81
  * token to the agent as `DRISP_RUN_TOKEN`. A start with `delegation` is never sent to a runner without it.
42
82
  */
43
83
  declare const runDelegationCapability = "run_delegation_v1";
84
+ /**
85
+ * The runner takes grants marked `reportUsage` (protocol minor 3, root ADR-0011) and, for those only, reports the
86
+ * Run's usage: on `run.attention` and `run.finished`, and as `run.usage` while it executes. A Hub that does not know
87
+ * these fields never marks a grant, so it never receives them.
88
+ */
89
+ declare const runUsageCapability = "run_usage_v1";
44
90
  /** The prefix of every delegation token; the Hub keeps only its digest. */
45
91
  declare const delegationTokenPrefix = "drisp_dlg_";
46
92
  /** A `run.artifact` history record's `name`, and the most its `json` may take serialized. */
@@ -168,6 +214,15 @@ declare const runCloseReasonSchema: z.ZodEnum<{
168
214
  legacy_force_failed: "legacy_force_failed";
169
215
  }>;
170
216
  type RunCloseReason = z.infer<typeof runCloseReasonSchema>;
217
+ /**
218
+ * A Run's cumulative usage (root ADR-0011): `counted` is its tokens without cache reads (`total − cacheRead`), the unit
219
+ * the Run cap counts on every harness, and `cacheRead` the cache reads left out of it.
220
+ */
221
+ declare const runUsageSchema: z.ZodObject<{
222
+ counted: z.ZodNumber;
223
+ cacheRead: z.ZodNumber;
224
+ }, z.core.$strict>;
225
+ type RunUsage = z.infer<typeof runUsageSchema>;
171
226
  declare const controlRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
172
227
  kind: z.ZodLiteral<"workflows.changed">;
173
228
  workflows: z.ZodArray<z.ZodObject<{
@@ -227,6 +282,10 @@ declare const controlRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
227
282
  emittedAt: z.ZodISODateTime;
228
283
  kind: z.ZodLiteral<"run.resumed">;
229
284
  }, z.core.$strict>, z.ZodObject<{
285
+ usage: z.ZodOptional<z.ZodObject<{
286
+ counted: z.ZodNumber;
287
+ cacheRead: z.ZodNumber;
288
+ }, z.core.$strict>>;
230
289
  interruption: z.ZodObject<{
231
290
  interruptionId: z.ZodString;
232
291
  revision: z.ZodNumber;
@@ -263,6 +322,10 @@ declare const controlRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
263
322
  emittedAt: z.ZodISODateTime;
264
323
  kind: z.ZodLiteral<"run.attention">;
265
324
  }, z.core.$strict>, z.ZodObject<{
325
+ usage: z.ZodOptional<z.ZodObject<{
326
+ counted: z.ZodNumber;
327
+ cacheRead: z.ZodNumber;
328
+ }, z.core.$strict>>;
266
329
  status: z.ZodEnum<{
267
330
  completed: "completed";
268
331
  failed: "failed";
@@ -281,6 +344,12 @@ declare const controlRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
281
344
  executionRevision: z.ZodNumber;
282
345
  emittedAt: z.ZodISODateTime;
283
346
  kind: z.ZodLiteral<"run.finished">;
347
+ }, z.core.$strict>, z.ZodObject<{
348
+ counted: z.ZodNumber;
349
+ cacheRead: z.ZodNumber;
350
+ kind: z.ZodLiteral<"run.usage">;
351
+ runId: z.ZodString;
352
+ attemptId: z.ZodString;
284
353
  }, z.core.$strict>, z.ZodObject<{
285
354
  kind: z.ZodLiteral<"command.applied">;
286
355
  runId: z.ZodString;
@@ -531,6 +600,7 @@ declare const grantSchema: z.ZodObject<{
531
600
  runId: z.ZodString;
532
601
  tokenCap: z.ZodNumber;
533
602
  }, z.core.$strict>>;
603
+ reportUsage: z.ZodOptional<z.ZodLiteral<true>>;
534
604
  }, z.core.$strict>;
535
605
  declare const historyRecordSchema: z.ZodObject<{
536
606
  eventId: z.ZodString;
@@ -645,6 +715,10 @@ declare const runnerFrameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
645
715
  emittedAt: z.ZodISODateTime;
646
716
  kind: z.ZodLiteral<"run.resumed">;
647
717
  }, z.core.$strict>, z.ZodObject<{
718
+ usage: z.ZodOptional<z.ZodObject<{
719
+ counted: z.ZodNumber;
720
+ cacheRead: z.ZodNumber;
721
+ }, z.core.$strict>>;
648
722
  interruption: z.ZodObject<{
649
723
  interruptionId: z.ZodString;
650
724
  revision: z.ZodNumber;
@@ -681,6 +755,10 @@ declare const runnerFrameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
681
755
  emittedAt: z.ZodISODateTime;
682
756
  kind: z.ZodLiteral<"run.attention">;
683
757
  }, z.core.$strict>, z.ZodObject<{
758
+ usage: z.ZodOptional<z.ZodObject<{
759
+ counted: z.ZodNumber;
760
+ cacheRead: z.ZodNumber;
761
+ }, z.core.$strict>>;
684
762
  status: z.ZodEnum<{
685
763
  completed: "completed";
686
764
  failed: "failed";
@@ -699,6 +777,12 @@ declare const runnerFrameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
699
777
  executionRevision: z.ZodNumber;
700
778
  emittedAt: z.ZodISODateTime;
701
779
  kind: z.ZodLiteral<"run.finished">;
780
+ }, z.core.$strict>, z.ZodObject<{
781
+ counted: z.ZodNumber;
782
+ cacheRead: z.ZodNumber;
783
+ kind: z.ZodLiteral<"run.usage">;
784
+ runId: z.ZodString;
785
+ attemptId: z.ZodString;
702
786
  }, z.core.$strict>, z.ZodObject<{
703
787
  kind: z.ZodLiteral<"command.applied">;
704
788
  runId: z.ZodString;
@@ -779,6 +863,10 @@ declare const runViewSchema: z.ZodObject<{
779
863
  delegation: z.ZodOptional<z.ZodObject<{
780
864
  maxChildren: z.ZodNumber;
781
865
  tokenBudget: z.ZodNumber;
866
+ }, z.core.$strip>>;
867
+ usage: z.ZodOptional<z.ZodObject<{
868
+ counted: z.ZodNumber;
869
+ cacheRead: z.ZodNumber;
782
870
  }, z.core.$strict>>;
783
871
  workflow: z.ZodOptional<z.ZodObject<{
784
872
  name: z.ZodString;
@@ -1068,6 +1156,7 @@ declare const checkpointSchema: z.ZodObject<{
1068
1156
  runId: z.ZodString;
1069
1157
  tokenCap: z.ZodNumber;
1070
1158
  }, z.core.$strict>>;
1159
+ reportUsage: z.ZodOptional<z.ZodLiteral<true>>;
1071
1160
  }, z.core.$strict>;
1072
1161
  gitHead: z.ZodString;
1073
1162
  gitBase: z.ZodOptional<z.ZodString>;
@@ -1427,4 +1516,4 @@ type ConnectPendingResponse = z.infer<typeof connectPendingResponseSchema>;
1427
1516
  type TeamDefault = z.infer<typeof teamDefaultSchema>;
1428
1517
  type RunsGoTo = z.infer<typeof runsGoToSchema>;
1429
1518
 
1430
- 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 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, runViewSchema, runnerAdoptRequestSchema, runnerDisconnectPreviewSchema, runnerDisconnectRequestSchema, runnerDisconnectResponseSchema, runnerFrameSchema, runnerListEntrySchema, runnerListSchema, runnerReadinessSchema, runnerUpdateCommand, runnerUpdateRequestSchema, runsGoToSchema, sameWorkflow, scopeSchema, secretEnvironmentSchema, sequence, teamDefaultRequestSchema, teamDefaultSchema, workflowIdentitySchema, workflowInstallCapability, workflowName, workflowReferenceSchema, workflowSourceSchema };
1519
+ export { type Audience, 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, audienceSchema, 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,
@@ -71,38 +72,68 @@ function attemptCost(attempt) {
71
72
  const forecast = forecastOfCap(attempt.tokenCap);
72
73
  return attempt.tokenCap > 0 ? Math.min(attempt.tokenCap, forecast) : forecast;
73
74
  }
75
+ var CALIBRATION_MIN_RUNS = 10;
76
+ var CALIBRATION_WINDOW_DAYS = 90;
77
+ function calibrate(samples) {
78
+ const byKey = /* @__PURE__ */ new Map();
79
+ for (const { harness, sizeClass, counted } of samples) {
80
+ if (counted === void 0 || !Number.isFinite(counted) || counted < 0) continue;
81
+ const key = `${harness}\0${sizeClass}`;
82
+ const group = byKey.get(key) ?? { harness, sizeClass, counted: [] };
83
+ group.counted.push(counted);
84
+ byKey.set(key, group);
85
+ }
86
+ const result = {};
87
+ for (const { harness, sizeClass, counted } of byKey.values()) {
88
+ if (counted.length < CALIBRATION_MIN_RUNS) continue;
89
+ const sorted = [...counted].sort((a, b) => a - b);
90
+ const p90 = sorted[Math.ceil(sorted.length * 0.9) - 1];
91
+ (result[harness] ??= {})[sizeClass] = { forecast: Math.max(SIZE_CLASS_FORECASTS[sizeClass], p90), runs: sorted.length };
92
+ }
93
+ return result;
94
+ }
95
+ var classCalibrationSchema = z.strictObject({
96
+ S: z.strictObject({ forecast: z.number(), runs: z.number() }).optional(),
97
+ M: z.strictObject({ forecast: z.number(), runs: z.number() }).optional(),
98
+ L: z.strictObject({ forecast: z.number(), runs: z.number() }).optional()
99
+ });
100
+ var calibrationSchema = z.record(z.string(), classCalibrationSchema);
101
+ function forecastOfClass(sizeClass, calibration) {
102
+ return calibration?.[sizeClass]?.forecast ?? SIZE_CLASS_FORECASTS[sizeClass];
103
+ }
74
104
 
75
105
  // src/v2.ts
76
- var protocolVersion = { major: 2, minor: 2 };
106
+ var protocolVersion = { major: 2, minor: 3 };
77
107
  var conversationContinuationCapability = "conversation_continuation";
78
108
  var abandonedConversationContinuationCapability = "abandoned_conversation_continuation";
79
109
  var repositoryAccessCapability = "repository_checkout_v1";
80
110
  var workflowInstallCapability = "workflow_install_v1";
81
111
  var runDelegationCapability = "run_delegation_v1";
112
+ var runUsageCapability = "run_usage_v1";
82
113
  var delegationTokenPrefix = "drisp_dlg_";
83
- var runArtifactNameSchema = z.string().regex(/^[a-z][a-z0-9_]{0,63}$/);
114
+ var runArtifactNameSchema = z2.string().regex(/^[a-z][a-z0-9_]{0,63}$/);
84
115
  var runArtifactMaxBytes = 64 * 1024;
85
- var secretEnvironmentSchema = z.record(
86
- z.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_]+)$/),
87
- z.string().regex(/^projects\/[a-zA-Z0-9-]+\/secrets\/[a-zA-Z0-9_-]+\/versions\/(?:latest|[0-9]+)$/)
116
+ var secretEnvironmentSchema = z2.record(
117
+ 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_]+)$/),
118
+ z2.string().regex(/^projects\/[a-zA-Z0-9-]+\/secrets\/[a-zA-Z0-9_-]+\/versions\/(?:latest|[0-9]+)$/)
88
119
  );
89
- var permissionAnswerSchema = z.strictObject({
90
- kind: z.literal("permission"),
91
- decision: z.enum(["allow", "deny"]),
92
- reason: z.string().max(4096).optional()
120
+ var permissionAnswerSchema = z2.strictObject({
121
+ kind: z2.literal("permission"),
122
+ decision: z2.enum(["allow", "deny"]),
123
+ reason: z2.string().max(4096).optional()
93
124
  });
94
- var id = z.string().min(1).max(160);
95
- var sequence = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
125
+ var id = z2.string().min(1).max(160);
126
+ var sequence = z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
96
127
  var positive = sequence.refine((n) => n > 0);
97
- var timestamp = z.iso.datetime();
98
- var scopeSchema = z.discriminatedUnion("visibility", [
99
- z.strictObject({ visibility: z.literal("organization") }),
100
- z.strictObject({ visibility: z.literal("private"), ownerUserId: id })
128
+ var timestamp = z2.iso.datetime();
129
+ var scopeSchema = z2.discriminatedUnion("visibility", [
130
+ z2.strictObject({ visibility: z2.literal("organization") }),
131
+ z2.strictObject({ visibility: z2.literal("private"), ownerUserId: id })
101
132
  ]);
102
- var installedWorkflowsSchema = z.array(InstalledWorkflowSchema).max(256);
103
- var harnessSchema = z.enum(["claude-code", "codex"]);
104
- var harnessReadinessSchema = z.strictObject({ installed: z.boolean(), signedIn: z.boolean() });
105
- var runnerReadinessSchema = z.strictObject({
133
+ var installedWorkflowsSchema = z2.array(InstalledWorkflowSchema).max(256);
134
+ var harnessSchema = z2.enum(["claude-code", "codex"]);
135
+ var harnessReadinessSchema = z2.strictObject({ installed: z2.boolean(), signedIn: z2.boolean() });
136
+ var runnerReadinessSchema = z2.strictObject({
106
137
  "claude-code": harnessReadinessSchema.optional(),
107
138
  codex: harnessReadinessSchema.optional()
108
139
  });
@@ -117,25 +148,25 @@ function readinessFixCommand(harness, readiness) {
117
148
  return void 0;
118
149
  }
119
150
  var runnerUpdateCommand = "npm i -g @drisp/cli";
120
- var interruptionSchema = z.strictObject({
151
+ var interruptionSchema = z2.strictObject({
121
152
  interruptionId: id,
122
153
  revision: positive,
123
154
  /** `waiting` (root ADR-0008) is non-human: a Run parked until one of its children closes or parks. */
124
- kind: z.enum(["permission", "question", "guidance", "recovery", "waiting"]),
125
- message: z.string().max(16384),
155
+ kind: z2.enum(["permission", "question", "guidance", "recovery", "waiting"]),
156
+ message: z2.string().max(16384),
126
157
  requestId: id.optional()
127
158
  });
128
- var workflowIdentitySchema = z.strictObject({
129
- name: z.string().min(1).max(128),
130
- version: z.string().min(1).max(128).optional()
159
+ var workflowIdentitySchema = z2.strictObject({
160
+ name: z2.string().min(1).max(128),
161
+ version: z2.string().min(1).max(128).optional()
131
162
  });
132
- var buildCloseReasonSchema = z.enum([
163
+ var buildCloseReasonSchema = z2.enum([
133
164
  "workflow_template_mismatch",
134
165
  "child_project_dir_invalid",
135
166
  "build_not_approved",
136
167
  "approval_question_missing"
137
168
  ]);
138
- var runCloseReasonSchema = z.enum([
169
+ var runCloseReasonSchema = z2.enum([
139
170
  "execution_terminal",
140
171
  "cancelled_before_start",
141
172
  "admission_failed",
@@ -158,129 +189,138 @@ var factIdentity = {
158
189
  executionRevision: positive,
159
190
  emittedAt: timestamp
160
191
  };
161
- var controlRecordSchema = z.discriminatedUnion("kind", [
192
+ var runUsageSchema = z2.strictObject({ counted: sequence, cacheRead: sequence });
193
+ var reportedUsage = { usage: runUsageSchema.optional() };
194
+ var controlRecordSchema = z2.discriminatedUnion("kind", [
162
195
  /** Instance-scoped, not tied to a Run: the full replacement inventory of installed Workflows. */
163
- z.strictObject({ kind: z.literal("workflows.changed"), workflows: installedWorkflowsSchema }),
196
+ z2.strictObject({ kind: z2.literal("workflows.changed"), workflows: installedWorkflowsSchema }),
164
197
  /** Instance-scoped, not tied to a Run: the Runner's full Readiness, sent when it changes after hello. */
165
- z.strictObject({ kind: z.literal("readiness.changed"), readiness: runnerReadinessSchema }),
166
- z.strictObject({ kind: z.literal("assignment.accepted"), runId: id, attemptId: id }),
167
- z.strictObject({
168
- kind: z.literal("assignment.rejected"),
198
+ z2.strictObject({ kind: z2.literal("readiness.changed"), readiness: runnerReadinessSchema }),
199
+ z2.strictObject({ kind: z2.literal("assignment.accepted"), runId: id, attemptId: id }),
200
+ z2.strictObject({
201
+ kind: z2.literal("assignment.rejected"),
169
202
  runId: id,
170
203
  attemptId: id,
171
- reason: z.string().max(1024)
204
+ reason: z2.string().max(1024)
172
205
  }),
173
- z.strictObject({
174
- kind: z.literal("run.started"),
206
+ z2.strictObject({
207
+ kind: z2.literal("run.started"),
175
208
  ...factIdentity,
176
209
  /** Absent from runners that predate Workflow reporting. */
177
210
  workflow: workflowIdentitySchema.optional()
178
211
  }),
179
- z.strictObject({ kind: z.literal("run.resumed"), ...factIdentity }),
180
- z.strictObject({
181
- kind: z.literal("run.attention"),
212
+ z2.strictObject({ kind: z2.literal("run.resumed"), ...factIdentity }),
213
+ z2.strictObject({
214
+ kind: z2.literal("run.attention"),
182
215
  ...factIdentity,
183
216
  interruption: interruptionSchema,
184
- occupancy: z.enum(["held", "released"]),
217
+ occupancy: z2.enum(["held", "released"]),
185
218
  historyThrough: sequence,
186
- continuation: z.discriminatedUnion("kind", [
187
- z.strictObject({ kind: z.literal("live_request") }),
188
- z.strictObject({ kind: z.literal("local_checkpoint"), checkpointId: id }),
189
- z.strictObject({ kind: z.literal("portable_checkpoint"), checkpointId: id }),
190
- z.strictObject({ kind: z.literal("repair_required"), detail: z.string().max(4096) })
191
- ])
219
+ continuation: z2.discriminatedUnion("kind", [
220
+ z2.strictObject({ kind: z2.literal("live_request") }),
221
+ z2.strictObject({ kind: z2.literal("local_checkpoint"), checkpointId: id }),
222
+ z2.strictObject({ kind: z2.literal("portable_checkpoint"), checkpointId: id }),
223
+ z2.strictObject({ kind: z2.literal("repair_required"), detail: z2.string().max(4096) })
224
+ ]),
225
+ ...reportedUsage
192
226
  }),
193
- z.strictObject({
194
- kind: z.literal("run.finished"),
227
+ z2.strictObject({
228
+ kind: z2.literal("run.finished"),
195
229
  ...factIdentity,
196
- status: z.enum(["completed", "failed", "cancelled"]),
230
+ status: z2.enum(["completed", "failed", "cancelled"]),
197
231
  historyThrough: sequence,
198
232
  /** No setup/harness executed and no workspace was produced; safe to retire without export. */
199
- workspaceUnavailable: z.literal(true).optional(),
233
+ workspaceUnavailable: z2.literal(true).optional(),
200
234
  /**
201
235
  * Why a Build Run failed, as its close reason (docs/specs/build-orchestrator.md). Sent only for a grant with
202
236
  * `parent` or `delegationToken`, which only a Hub that knows this field issues.
203
237
  */
204
- reason: buildCloseReasonSchema.optional()
238
+ reason: buildCloseReasonSchema.optional(),
239
+ ...reportedUsage
205
240
  }),
206
- z.strictObject({ kind: z.literal("command.applied"), runId: id, attemptId: id, commandId: id }),
207
- z.strictObject({
208
- kind: z.literal("command.rejected"),
241
+ /**
242
+ * The usage of a Run while it executes, for a grant marked `reportUsage`. Not an execution fact: it carries no
243
+ * execution revision, so it never advances, parks or closes the Run, and never wakes its parent.
244
+ */
245
+ z2.strictObject({ kind: z2.literal("run.usage"), runId: id, attemptId: id, ...runUsageSchema.shape }),
246
+ z2.strictObject({ kind: z2.literal("command.applied"), runId: id, attemptId: id, commandId: id }),
247
+ z2.strictObject({
248
+ kind: z2.literal("command.rejected"),
209
249
  runId: id,
210
250
  attemptId: id,
211
251
  commandId: id,
212
- reason: z.string().max(1024)
252
+ reason: z2.string().max(1024)
213
253
  }),
214
- z.strictObject({ kind: z.literal("revoked_not_started"), runId: id, attemptId: id })
254
+ z2.strictObject({ kind: z2.literal("revoked_not_started"), runId: id, attemptId: id })
215
255
  ]);
216
- var repositoryRefSchema = z.string().min(1).max(512).regex(
256
+ var repositoryRefSchema = z2.string().min(1).max(512).regex(
217
257
  /^(?![-/])(?!.*\.\.)(?!.*@\{)(?!.*(?:^|\/)\.)(?!.*\.lock(?:\/|$))(?!.*\/\/)[^\x00-\x20\x7f~^:?*\[\\]+(?<![/.])$/
218
258
  );
219
- var repositoryWorkingDirectorySchema = z.string().min(1).max(1024).regex(
259
+ var repositoryWorkingDirectorySchema = z2.string().min(1).max(1024).regex(
220
260
  /^(?:\.|(?!\/)(?!.*(?:^|\/)\.\.?(?:\/|$))(?!.*(?:^|\/)\.git(?:\/|$))[^\x00-\x1f\x7f\\:]+(?<!\/))$/
221
261
  );
222
262
  var repositoryIdentity = {
223
- repositoryId: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
224
- installationId: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
225
- owner: z.string().min(1).max(100).regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/),
226
- name: z.string().min(1).max(100).regex(/^(?!\.{1,2}$)[a-zA-Z0-9_.-]+$/)
263
+ repositoryId: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
264
+ installationId: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
265
+ owner: z2.string().min(1).max(100).regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/),
266
+ name: z2.string().min(1).max(100).regex(/^(?!\.{1,2}$)[a-zA-Z0-9_.-]+$/)
227
267
  };
228
- var repositoryBindingSchema = z.strictObject({
268
+ var repositoryBindingSchema = z2.strictObject({
229
269
  id,
230
- label: z.string().min(1).max(160),
270
+ label: z2.string().min(1).max(160),
231
271
  ...repositoryIdentity,
232
272
  defaultRef: repositoryRefSchema,
233
273
  workingDirectory: repositoryWorkingDirectorySchema,
234
- setupCommands: z.array(z.string().min(1).max(8192)).max(16),
274
+ setupCommands: z2.array(z2.string().min(1).max(8192)).max(16),
235
275
  revision: positive,
236
- enabled: z.boolean()
276
+ enabled: z2.boolean()
237
277
  });
238
- var repositorySourceSchema = z.strictObject({
278
+ var repositorySourceSchema = z2.strictObject({
239
279
  bindingId: id,
240
280
  ...repositoryIdentity,
241
281
  ref: repositoryRefSchema,
242
- commitSha: z.string().regex(/^[0-9a-f]{40}$/),
282
+ commitSha: z2.string().regex(/^[0-9a-f]{40}$/),
243
283
  branch: repositoryRefSchema,
244
284
  workingDirectory: repositoryWorkingDirectorySchema,
245
- setupCommands: z.array(z.string().min(1).max(8192)).max(16),
285
+ setupCommands: z2.array(z2.string().min(1).max(8192)).max(16),
246
286
  configRevision: positive
247
287
  });
248
- var workflowSourceSchema = z.string().max(201).regex(/^[A-Za-z0-9][A-Za-z0-9_.-]*\/[A-Za-z0-9][A-Za-z0-9_.-]*$/);
249
- var workflowReferenceSchema = z.union([
250
- z.string().max(512),
251
- z.strictObject({
252
- name: z.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/),
288
+ var workflowSourceSchema = z2.string().max(201).regex(/^[A-Za-z0-9][A-Za-z0-9_.-]*\/[A-Za-z0-9][A-Za-z0-9_.-]*$/);
289
+ var workflowReferenceSchema = z2.union([
290
+ z2.string().max(512),
291
+ z2.strictObject({
292
+ name: z2.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/),
253
293
  source: workflowSourceSchema.optional(),
254
- ref: z.string().min(1).max(512).optional(),
255
- version: z.string().min(1).max(128).regex(/^\d[A-Za-z0-9_.+-]*$/).optional()
294
+ ref: z2.string().min(1).max(512).optional(),
295
+ version: z2.string().min(1).max(128).regex(/^\d[A-Za-z0-9_.+-]*$/).optional()
256
296
  })
257
297
  ]);
258
298
  var workflowName = (workflow) => typeof workflow === "object" ? workflow.name : workflow;
259
299
  var installReference = (workflow) => typeof workflow === "object" && workflow.source !== void 0 ? workflow : void 0;
260
300
  var sameWorkflow = (a, b) => canonicalJson(a ?? null) === canonicalJson(b ?? null);
261
- var runSpecSchema = z.strictObject({
262
- prompt: z.string().min(1).max(131072),
263
- projectDir: z.string().min(1).max(4096),
301
+ var runSpecSchema = z2.strictObject({
302
+ prompt: z2.string().min(1).max(131072),
303
+ projectDir: z2.string().min(1).max(4096),
264
304
  harness: harnessSchema,
265
305
  workflow: workflowReferenceSchema.optional(),
266
306
  repository: repositorySourceSchema.optional()
267
307
  });
268
- var runKeySchema = z.string().min(1).max(160);
269
- var delegationSchema = z.strictObject({
270
- maxChildren: z.number().int().min(1).max(8),
271
- tokenBudget: z.number().int().positive().max(Number.MAX_SAFE_INTEGER)
308
+ var runKeySchema = z2.string().min(1).max(160);
309
+ var delegationSchema = z2.strictObject({
310
+ maxChildren: z2.number().int().min(1).max(8),
311
+ tokenBudget: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER)
272
312
  });
273
- var tokenCapSchema = z.number().int().positive().max(Number.MAX_SAFE_INTEGER);
274
- var runParentIntentSchema = z.strictObject({ runId: id, tokenCap: tokenCapSchema.optional() });
275
- var runParentSchema = z.strictObject({ runId: id, tokenCap: tokenCapSchema });
276
- var commandSchema = z.strictObject({
313
+ var tokenCapSchema = z2.number().int().positive().max(Number.MAX_SAFE_INTEGER);
314
+ var runParentIntentSchema = z2.strictObject({ runId: id, tokenCap: tokenCapSchema.optional() });
315
+ var runParentSchema = z2.strictObject({ runId: id, tokenCap: tokenCapSchema });
316
+ var commandSchema = z2.strictObject({
277
317
  commandId: id,
278
318
  hubEpoch: id,
279
319
  runId: id,
280
320
  expectedRecordRevision: sequence.optional(),
281
- intent: z.discriminatedUnion("kind", [
282
- z.strictObject({
283
- kind: z.literal("start"),
321
+ intent: z2.discriminatedUnion("kind", [
322
+ z2.strictObject({
323
+ kind: z2.literal("start"),
284
324
  sessionId: id,
285
325
  /**
286
326
  * Absent: the Hub resolves the Runner member-first (root ADR-0005): the Session's conversation Runner, else
@@ -296,24 +336,24 @@ var commandSchema = z.strictObject({
296
336
  /** Delegated starts only, and required on them. */
297
337
  parent: runParentIntentSchema.optional()
298
338
  }),
299
- z.strictObject({ kind: z.literal("cancel") }),
300
- z.strictObject({ kind: z.literal("abandon") }),
301
- z.strictObject({ kind: z.literal("steer"), text: z.string().min(1).max(131072) }),
302
- z.strictObject({
303
- kind: z.literal("answer"),
339
+ z2.strictObject({ kind: z2.literal("cancel") }),
340
+ z2.strictObject({ kind: z2.literal("abandon") }),
341
+ z2.strictObject({ kind: z2.literal("steer"), text: z2.string().min(1).max(131072) }),
342
+ z2.strictObject({
343
+ kind: z2.literal("answer"),
304
344
  interruptionId: id,
305
345
  expectedInterruptionRevision: positive,
306
346
  requestId: id.optional(),
307
- answer: z.json()
347
+ answer: z2.json()
308
348
  }),
309
- z.strictObject({
310
- kind: z.literal("resume"),
349
+ z2.strictObject({
350
+ kind: z2.literal("resume"),
311
351
  interruptionId: id,
312
- guidance: z.string().max(131072).optional()
352
+ guidance: z2.string().max(131072).optional()
313
353
  })
314
354
  ])
315
355
  });
316
- var grantSchema = z.strictObject({
356
+ var grantSchema = z2.strictObject({
317
357
  commandId: id,
318
358
  hubEpoch: id,
319
359
  runId: id,
@@ -325,113 +365,121 @@ var grantSchema = z.strictObject({
325
365
  baseExecutionRevision: sequence,
326
366
  baseHistorySeq: sequence,
327
367
  cloudHistoryThrough: sequence,
328
- purpose: z.enum(["start", "resume"]),
368
+ purpose: z2.enum(["start", "resume"]),
329
369
  spec: runSpecSchema,
330
- continuation: z.json().optional(),
370
+ continuation: z2.json().optional(),
331
371
  /** A new Run in a durable conversation; never resumes the predecessor's lifecycle. */
332
- previousRun: z.strictObject({
372
+ previousRun: z2.strictObject({
333
373
  runId: id,
334
374
  executionRevision: sequence,
335
375
  historyProduced: sequence,
336
376
  /** Hub-confirmed administrative closure; allows an exact parked predecessor snapshot. */
337
- closeReason: z.literal("abandoned").optional(),
338
- checkpoint: z.strictObject({ checkpointId: id, checksum: z.string().regex(/^[a-f0-9]{64}$/) }).optional()
377
+ closeReason: z2.literal("abandoned").optional(),
378
+ checkpoint: z2.strictObject({ checkpointId: id, checksum: z2.string().regex(/^[a-f0-9]{64}$/) }).optional()
339
379
  }).optional(),
340
- checkpoint: z.strictObject({ checkpointId: id, checksum: z.string().regex(/^[a-f0-9]{64}$/) }).optional(),
380
+ checkpoint: z2.strictObject({ checkpointId: id, checksum: z2.string().regex(/^[a-f0-9]{64}$/) }).optional(),
341
381
  /** This attempt's delegation token: only for a Run started with `delegation`, only to a `run_delegation_v1` Runner. */
342
- delegationToken: z.string().min(32).max(256).optional(),
382
+ delegationToken: z2.string().min(32).max(256).optional(),
343
383
  /** Copied from the start intent of a delegated child. */
344
- parent: runParentSchema.optional()
384
+ parent: runParentSchema.optional(),
385
+ /** The runner reports this attempt's usage: set only for a `run_usage_v1` Runner. */
386
+ reportUsage: z2.literal(true).optional()
345
387
  });
346
- var historyRecordSchema = z.strictObject({
388
+ var historyRecordSchema = z2.strictObject({
347
389
  eventId: id,
348
390
  attemptId: id,
349
391
  emittedAt: timestamp,
350
- kind: z.string().min(1).max(128),
351
- data: z.json()
392
+ kind: z2.string().min(1).max(128),
393
+ data: z2.json()
352
394
  });
353
- var runnerFrameSchema = z.discriminatedUnion("type", [
354
- z.strictObject({
355
- type: z.literal("hello"),
356
- role: z.literal("runner"),
357
- protocol: z.strictObject({ major: z.literal(2), minor: sequence }),
395
+ var runnerFrameSchema = z2.discriminatedUnion("type", [
396
+ z2.strictObject({
397
+ type: z2.literal("hello"),
398
+ role: z2.literal("runner"),
399
+ protocol: z2.strictObject({ major: z2.literal(2), minor: sequence }),
358
400
  runnerId: id,
359
401
  installationId: id,
360
- softwareVersion: z.string().max(128),
361
- capabilities: z.array(z.string().max(128)).max(64),
402
+ softwareVersion: z2.string().max(128),
403
+ capabilities: z2.array(z2.string().max(128)).max(64),
362
404
  /** Absent from older runners: the Hub treats the inventory as unknown, never as empty. */
363
405
  workflows: installedWorkflowsSchema.optional(),
364
406
  /** Absent from older runners, and from a runner that has not finished its first check: unknown, not "not ready". */
365
407
  readiness: runnerReadinessSchema.optional(),
366
- control: z.strictObject({ firstRetainedSeq: positive, lastProducedSeq: sequence })
408
+ control: z2.strictObject({ firstRetainedSeq: positive, lastProducedSeq: sequence })
367
409
  }),
368
- z.strictObject({
369
- type: z.literal("control.batch"),
410
+ z2.strictObject({
411
+ type: z2.literal("control.batch"),
370
412
  firstSeq: positive,
371
- records: z.array(controlRecordSchema).min(1).max(128)
413
+ records: z2.array(controlRecordSchema).min(1).max(128)
372
414
  }),
373
- z.strictObject({
374
- type: z.literal("history.batch"),
415
+ z2.strictObject({
416
+ type: z2.literal("history.batch"),
375
417
  runId: id,
376
418
  firstSeq: positive,
377
- records: z.array(historyRecordSchema).min(1).max(128)
419
+ records: z2.array(historyRecordSchema).min(1).max(128)
378
420
  }),
379
- z.strictObject({ type: z.literal("ping"), nonce: id }),
380
- z.strictObject({
381
- type: z.literal("reconcile.page"),
421
+ z2.strictObject({ type: z2.literal("ping"), nonce: id }),
422
+ z2.strictObject({
423
+ type: z2.literal("reconcile.page"),
382
424
  inventoryId: id.default("single-page"),
383
425
  page: sequence.default(0),
384
- complete: z.boolean(),
385
- runs: z.array(
386
- z.strictObject({
426
+ complete: z2.boolean(),
427
+ runs: z2.array(
428
+ z2.strictObject({
387
429
  runId: id,
388
430
  attemptId: id,
389
431
  executionRevision: sequence,
390
- phase: z.enum(["admitted", "prepared", "executing", "parked", "terminal", "recovery"])
432
+ phase: z2.enum(["admitted", "prepared", "executing", "parked", "terminal", "recovery"])
391
433
  })
392
434
  ).max(128)
393
435
  })
394
436
  ]);
395
- var runViewSchema = z.object({
437
+ var runViewSchema = z2.object({
396
438
  runId: id,
397
439
  sessionId: id,
398
440
  runnerId: id,
399
441
  computeProfileId: id.optional(),
400
442
  scope: scopeSchema,
401
443
  recordRevision: positive,
402
- label: z.string().max(160).optional(),
444
+ label: z2.string().max(160).optional(),
403
445
  key: runKeySchema.optional(),
404
446
  parent: runParentSchema.optional(),
405
- delegation: delegationSchema.optional(),
447
+ /**
448
+ * Not strict, unlike the start intent's: a Hub keeps more on the Run's delegation (`initialTokenBudget`) than it
449
+ * shows, and a client never refuses a view for a field it does not read.
450
+ */
451
+ delegation: z2.object(delegationSchema.shape).optional(),
452
+ /** The largest cumulative usage the Run's Runner reported; absent until one does (an older Runner never does). */
453
+ usage: runUsageSchema.optional(),
406
454
  /** Resolved by the runner at start; absent until the Run starts and for runners that predate reporting. */
407
455
  workflow: workflowIdentitySchema.optional(),
408
- execution: z.object({
409
- status: z.enum(["running", "awaiting_attention", "completed", "failed", "cancelled"]),
456
+ execution: z2.object({
457
+ status: z2.enum(["running", "awaiting_attention", "completed", "failed", "cancelled"]),
410
458
  revision: positive,
411
459
  attemptId: id,
412
- occupancy: z.enum(["held", "released"]),
460
+ occupancy: z2.enum(["held", "released"]),
413
461
  startedAt: timestamp.optional(),
414
462
  endedAt: timestamp.optional(),
415
463
  interruption: interruptionSchema.optional()
416
464
  }).nullable(),
417
- scheduling: z.enum(["queued", "dispatching", "admitted", "idle"]),
418
- closed: z.boolean(),
419
- closeReason: z.string().optional(),
465
+ scheduling: z2.enum(["queued", "dispatching", "admitted", "idle"]),
466
+ closed: z2.boolean(),
467
+ closeReason: z2.string().optional(),
420
468
  cancellation: id.optional(),
421
469
  pendingResume: commandSchema.shape.intent.optional(),
422
470
  /** Derived per viewer; absent on older Hubs. Never grants execution authority. */
423
- runnerStopped: z.boolean().optional(),
424
- canAbandon: z.boolean().optional(),
471
+ runnerStopped: z2.boolean().optional(),
472
+ canAbandon: z2.boolean().optional(),
425
473
  historyThrough: sequence,
426
474
  expectedHistoryThrough: sequence.optional(),
427
475
  createdAt: sequence,
428
- checkpoint: z.object({ id, state: z.enum(["pending", "ready"]), checksum: z.string().optional() }).optional()
476
+ checkpoint: z2.object({ id, state: z2.enum(["pending", "ready"]), checksum: z2.string().optional() }).optional()
429
477
  });
430
- var clientFrameSchema = z.discriminatedUnion("type", [
431
- z.strictObject({ type: z.literal("watch"), hubEpoch: id, runIds: z.array(id).max(100) }),
432
- z.strictObject({ type: z.literal("watch.ack"), subscriptionId: id, through: sequence }),
433
- z.strictObject({ type: z.literal("command.submit"), command: commandSchema }),
434
- z.strictObject({ type: z.literal("ping"), nonce: id })
478
+ var clientFrameSchema = z2.discriminatedUnion("type", [
479
+ z2.strictObject({ type: z2.literal("watch"), hubEpoch: id, runIds: z2.array(id).max(100) }),
480
+ z2.strictObject({ type: z2.literal("watch.ack"), subscriptionId: id, through: sequence }),
481
+ z2.strictObject({ type: z2.literal("command.submit"), command: commandSchema }),
482
+ z2.strictObject({ type: z2.literal("ping"), nonce: id })
435
483
  ]);
436
484
  function canonicalJson(value) {
437
485
  if (value === null || typeof value !== "object") {
@@ -442,76 +490,76 @@ function canonicalJson(value) {
442
490
  if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
443
491
  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(",")}}`;
444
492
  }
445
- var checkpointPathSchema = z.string().min(1).max(4096).refine(
493
+ var checkpointPathSchema = z2.string().min(1).max(4096).refine(
446
494
  (path) => !path.startsWith("/") && !path.includes("\\") && path.split("/").every((part) => part !== "" && part !== "." && part !== ".." && part !== ".git")
447
495
  );
448
- var checkpointSchema = z.strictObject({
449
- version: z.literal(1),
450
- checkpointId: z.string().min(1),
451
- orgId: z.string().min(1),
452
- phase: z.enum(["parked", "terminal"]),
453
- runId: z.string().min(1),
454
- sessionId: z.string().min(1),
455
- sourceAttemptId: z.string().min(1),
456
- executionRevision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
457
- historyProduced: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
458
- historyAck: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
496
+ var checkpointSchema = z2.strictObject({
497
+ version: z2.literal(1),
498
+ checkpointId: z2.string().min(1),
499
+ orgId: z2.string().min(1),
500
+ phase: z2.enum(["parked", "terminal"]),
501
+ runId: z2.string().min(1),
502
+ sessionId: z2.string().min(1),
503
+ sourceAttemptId: z2.string().min(1),
504
+ executionRevision: z2.number().int().positive().max(Number.MAX_SAFE_INTEGER),
505
+ historyProduced: z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
506
+ historyAck: z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
459
507
  grant: grantSchema,
460
- gitHead: z.string().regex(/^[0-9a-f]{40,64}$/),
461
- gitBase: z.string().regex(/^[0-9a-f]{40,64}$/).optional(),
462
- gitBundle: z.string(),
463
- indexPatch: z.string(),
464
- files: z.array(
465
- z.strictObject({ path: checkpointPathSchema, content: z.string(), executable: z.boolean() })
508
+ gitHead: z2.string().regex(/^[0-9a-f]{40,64}$/),
509
+ gitBase: z2.string().regex(/^[0-9a-f]{40,64}$/).optional(),
510
+ gitBundle: z2.string(),
511
+ indexPatch: z2.string(),
512
+ files: z2.array(
513
+ z2.strictObject({ path: checkpointPathSchema, content: z2.string(), executable: z2.boolean() })
466
514
  ).max(1e5),
467
- deleted: z.array(checkpointPathSchema).max(1e5),
468
- sessionRows: z.array(z.strictObject({ kind: z.string(), id: z.string(), payload: z.string() })),
469
- history: z.array(
470
- z.strictObject({ seq: z.number().int().positive(), record: historyRecordSchema })
515
+ deleted: z2.array(checkpointPathSchema).max(1e5),
516
+ sessionRows: z2.array(z2.strictObject({ kind: z2.string(), id: z2.string(), payload: z2.string() })),
517
+ history: z2.array(
518
+ z2.strictObject({ seq: z2.number().int().positive(), record: historyRecordSchema })
471
519
  )
472
520
  });
473
521
  var connectCodeAlphabet = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
474
- var connectCodeSchema = z.string().regex(/^[A-HJKMNP-Z2-9]{8}$/);
475
- var connectCodeRequestSchema = z.strictObject({ hubEpoch: z.string() });
476
- var connectCodeResponseSchema = z.strictObject({
522
+ var connectCodeSchema = z2.string().regex(/^[A-HJKMNP-Z2-9]{8}$/);
523
+ var connectCodeRequestSchema = z2.strictObject({ hubEpoch: z2.string() });
524
+ var connectCodeResponseSchema = z2.strictObject({
477
525
  code: connectCodeSchema,
478
526
  expiresAt: sequence
479
527
  });
480
- var connectRedeemRequestSchema = z.strictObject({
481
- code: z.string().min(8).max(16),
528
+ var connectRedeemRequestSchema = z2.strictObject({
529
+ code: z2.string().min(8).max(16),
482
530
  installationId: id,
483
- hostname: z.string().min(1).max(255),
484
- os: z.string().min(1).max(64),
485
- softwareVersion: z.string().min(1).max(128)
531
+ hostname: z2.string().min(1).max(255),
532
+ os: z2.string().min(1).max(64),
533
+ softwareVersion: z2.string().min(1).max(128)
486
534
  });
487
- var connectRedeemResponseSchema = z.strictObject({
535
+ var connectRedeemResponseSchema = z2.strictObject({
488
536
  orgId: id,
489
- hubEpoch: z.string(),
537
+ hubEpoch: z2.string(),
490
538
  runnerId: id,
491
539
  installationId: id,
492
- name: z.string(),
493
- token: z.string().min(32),
540
+ name: z2.string(),
541
+ token: z2.string().min(32),
494
542
  credentialId: id,
495
543
  expiresAt: sequence
496
544
  });
497
- var connectAlreadyConnectedSchema = z.strictObject({
498
- error: z.literal("runner_already_connected"),
545
+ var connectAlreadyConnectedSchema = z2.strictObject({
546
+ error: z2.literal("runner_already_connected"),
499
547
  orgId: id,
500
548
  runnerId: id,
501
- name: z.string()
549
+ name: z2.string()
502
550
  });
503
- var audienceSchema = z.enum(["personal", "team"]);
504
- var runnerListEntrySchema = z.object({
551
+ var audienceSchema = z2.enum(["personal", "team"]);
552
+ var runnerListEntrySchema = z2.object({
505
553
  id,
506
- online: z.number(),
507
- capacity: z.number(),
508
- managed: z.number(),
509
- draining: z.number(),
510
- stopped: z.number(),
511
- name: z.string().nullable(),
512
- connectedBy: z.string().nullable(),
554
+ online: z2.number(),
555
+ capacity: z2.number(),
556
+ managed: z2.number(),
557
+ draining: z2.number(),
558
+ stopped: z2.number(),
559
+ name: z2.string().nullable(),
560
+ connectedBy: z2.string().nullable(),
513
561
  audience: audienceSchema.nullable(),
514
- softwareVersion: z.string().nullable(),
562
+ softwareVersion: z2.string().nullable(),
515
563
  /** Milliseconds since the epoch of the last hello or disconnect; null before the first connection. */
516
564
  lastSeen: sequence.nullable(),
517
565
  /** Absent when the runner has not reported an inventory: unknown, not none. */
@@ -521,115 +569,119 @@ var runnerListEntrySchema = z.object({
521
569
  * Runner seen by an admin (who may still Disconnect it), or a Runner a member did not connect. Absent from Hubs
522
570
  * older than Audience, like the list's `viewer`, `teamDefault` and `runsGoTo`.
523
571
  */
524
- readOnly: z.boolean().optional(),
572
+ readOnly: z2.boolean().optional(),
525
573
  /** What the Runner last reported; absent when it never has (an older runner, or one not yet connected). */
526
574
  readiness: runnerReadinessSchema.optional(),
527
575
  /**
528
576
  * True when the Runner reported a version below the Hub's minimum: it is listed as "Update required" and takes no
529
577
  * Runs until it is updated (`runnerUpdateCommand`). Absent from Hubs older than Readiness.
530
578
  */
531
- updateRequired: z.boolean().optional(),
579
+ updateRequired: z2.boolean().optional(),
532
580
  /**
533
581
  * True while it is paused as "Needs an owner": the member who connected this Team Runner left the Team, so it
534
582
  * takes no Runs until an admin adopts it (`/runners/{id}/adopt`) or Disconnects it. Absent from older Hubs.
535
583
  */
536
- needsOwner: z.boolean().optional()
584
+ needsOwner: z2.boolean().optional()
537
585
  });
538
- var teamDefaultSchema = z.discriminatedUnion("kind", [
539
- z.strictObject({ kind: z.literal("runner"), runnerId: id }),
540
- z.strictObject({ kind: z.literal("profile"), profileId: id })
586
+ var teamDefaultSchema = z2.discriminatedUnion("kind", [
587
+ z2.strictObject({ kind: z2.literal("runner"), runnerId: id }),
588
+ z2.strictObject({ kind: z2.literal("profile"), profileId: id })
541
589
  ]);
542
- var teamDefaultRequestSchema = z.strictObject({
543
- hubEpoch: z.string(),
590
+ var teamDefaultRequestSchema = z2.strictObject({
591
+ hubEpoch: z2.string(),
544
592
  teamDefault: teamDefaultSchema.nullable()
545
593
  });
546
- var runnerUpdateRequestSchema = z.strictObject({
547
- hubEpoch: z.string(),
548
- name: z.string().max(100).optional(),
549
- capacity: z.number().int().min(1).max(64).optional(),
594
+ var runnerUpdateRequestSchema = z2.strictObject({
595
+ hubEpoch: z2.string(),
596
+ name: z2.string().max(100).optional(),
597
+ capacity: z2.number().int().min(1).max(64).optional(),
550
598
  audience: audienceSchema.optional()
551
599
  }).refine(
552
600
  (update) => update.name !== void 0 || update.capacity !== void 0 || update.audience !== void 0,
553
601
  { message: "nothing to update" }
554
602
  );
555
- var runsGoToSchema = z.union([
603
+ var runsGoToSchema = z2.union([
556
604
  /** The viewer's own Runner: Personal, or one they connected that was widened to Team (DRI-42). */
557
- z.strictObject({ via: z.literal("personal"), runnerId: id }),
558
- z.strictObject({ via: z.literal("team_default"), runnerId: id }),
559
- z.strictObject({ via: z.literal("team_default"), profileId: id }),
605
+ z2.strictObject({ via: z2.literal("personal"), runnerId: id }),
606
+ z2.strictObject({ via: z2.literal("team_default"), runnerId: id }),
607
+ z2.strictObject({ via: z2.literal("team_default"), profileId: id }),
560
608
  /** `runner_needs_owner`: the Team default is a Runner paused because the member who connected it left. */
561
- z.strictObject({ via: z.literal("none"), reason: z.enum(["no_runner_available", "runner_needs_owner"]) })
609
+ z2.strictObject({ via: z2.literal("none"), reason: z2.enum(["no_runner_available", "runner_needs_owner"]) })
562
610
  ]);
563
- var runnerListSchema = z.object({
564
- capabilities: z.record(z.string(), z.boolean()).optional(),
565
- historyRetentionDays: z.number().int().positive().nullable().optional(),
611
+ var runnerListSchema = z2.object({
612
+ capabilities: z2.record(z2.string(), z2.boolean()).optional(),
613
+ historyRetentionDays: z2.number().int().positive().nullable().optional(),
566
614
  /** Who the list was filtered for: a member sees their own and Team Runners, an admin every Runner. */
567
- viewer: z.object({ userId: z.string(), admin: z.boolean() }).optional(),
615
+ viewer: z2.object({ userId: z2.string(), admin: z2.boolean() }).optional(),
568
616
  teamDefault: teamDefaultSchema.nullable().optional(),
569
617
  runsGoTo: runsGoToSchema.optional(),
570
618
  /** The lowest Runner version this Hub sends Runs to. Absent from Hubs older than Readiness. */
571
- minimumRunnerVersion: z.string().optional(),
572
- runners: z.array(runnerListEntrySchema),
573
- profiles: z.array(z.object({
574
- id: z.string(),
575
- label: z.string(),
576
- projectDir: z.string(),
577
- repositoryRequired: z.boolean().optional(),
619
+ minimumRunnerVersion: z2.string().optional(),
620
+ runners: z2.array(runnerListEntrySchema),
621
+ profiles: z2.array(z2.object({
622
+ id: z2.string(),
623
+ label: z2.string(),
624
+ projectDir: z2.string(),
625
+ repositoryRequired: z2.boolean().optional(),
578
626
  /** Marketplace refs baked into the profile's image; absent when the profile declares none. */
579
- workflows: z.array(z.string()).optional(),
580
- workflowSources: z.array(z.string()).optional()
627
+ workflows: z2.array(z2.string()).optional(),
628
+ workflowSources: z2.array(z2.string()).optional()
581
629
  }))
582
630
  });
583
- var runnerDisconnectRequestSchema = z.strictObject({ hubEpoch: z.string() });
631
+ var runnerDisconnectRequestSchema = z2.strictObject({ hubEpoch: z2.string() });
584
632
  var hubEpochRequestSchema = runnerDisconnectRequestSchema;
585
- var runnerDisconnectPreviewSchema = z.object({
633
+ var runnerDisconnectPreviewSchema = z2.object({
586
634
  runnerId: id,
587
- name: z.string().nullable(),
588
- runs: z.array(z.object({
635
+ name: z2.string().nullable(),
636
+ runs: z2.array(z2.object({
589
637
  runId: id,
590
- label: z.string().optional(),
638
+ label: z2.string().optional(),
591
639
  /** Working: executing now. Parked: waiting for a person, Runner released. Queued: not started yet. */
592
- state: z.enum(["working", "parked", "queued"])
640
+ state: z2.enum(["working", "parked", "queued"])
593
641
  })),
594
- hiddenRuns: z.number().int().nonnegative()
642
+ hiddenRuns: z2.number().int().nonnegative()
595
643
  });
596
- var runnerDisconnectResponseSchema = z.object({
597
- disconnected: z.literal(true),
644
+ var runnerDisconnectResponseSchema = z2.object({
645
+ disconnected: z2.literal(true),
598
646
  /** How many Runs were Stopped with the reason `runner_disconnected`. */
599
- stoppedRuns: z.number().int().nonnegative()
647
+ stoppedRuns: z2.number().int().nonnegative()
600
648
  });
601
649
  var runnerAdoptRequestSchema = hubEpochRequestSchema;
602
650
  var connectStartRequestSchema = connectRedeemRequestSchema.omit({ code: true });
603
- var connectStartResponseSchema = z.strictObject({
651
+ var connectStartResponseSchema = z2.strictObject({
604
652
  /** The machine's secret for polling; never shown. */
605
- deviceCode: z.string().min(32).max(160),
653
+ deviceCode: z2.string().min(32).max(160),
606
654
  code: connectCodeSchema,
607
655
  expiresAt: sequence,
608
- intervalSec: z.number().int().positive(),
656
+ intervalSec: z2.number().int().positive(),
609
657
  /** The web console page that approves `code`. */
610
- verificationUrl: z.string().url()
658
+ verificationUrl: z2.string().url()
611
659
  });
612
- var connectPollRequestSchema = z.strictObject({ deviceCode: z.string().min(32).max(160) });
613
- var connectPendingResponseSchema = z.strictObject({
614
- hostname: z.string(),
615
- os: z.string(),
616
- softwareVersion: z.string(),
660
+ var connectPollRequestSchema = z2.strictObject({ deviceCode: z2.string().min(32).max(160) });
661
+ var connectPendingResponseSchema = z2.strictObject({
662
+ hostname: z2.string(),
663
+ os: z2.string(),
664
+ softwareVersion: z2.string(),
617
665
  requestedAt: sequence,
618
666
  expiresAt: sequence
619
667
  });
620
- var connectApproveRequestSchema = z.strictObject({
621
- code: z.string().min(8).max(16),
668
+ var connectApproveRequestSchema = z2.strictObject({
669
+ code: z2.string().min(8).max(16),
622
670
  audience: audienceSchema,
623
- hubEpoch: z.string().optional()
671
+ hubEpoch: z2.string().optional()
624
672
  });
625
- var connectDenyRequestSchema = z.strictObject({ code: z.string().min(8).max(16) });
673
+ var connectDenyRequestSchema = z2.strictObject({ code: z2.string().min(8).max(16) });
626
674
  export {
675
+ CALIBRATION_MIN_RUNS,
676
+ CALIBRATION_WINDOW_DAYS,
627
677
  SIZE_CLASS_CAPS,
628
678
  SIZE_CLASS_FORECASTS,
629
679
  abandonedConversationContinuationCapability,
630
680
  attemptCost,
631
681
  audienceSchema,
632
682
  buildCloseReasonSchema,
683
+ calibrate,
684
+ calibrationSchema,
633
685
  canonicalJson,
634
686
  checkpointPathSchema,
635
687
  checkpointSchema,
@@ -654,6 +706,7 @@ export {
654
706
  delegationSchema,
655
707
  delegationTokenPrefix,
656
708
  forecastOfCap,
709
+ forecastOfClass,
657
710
  grantSchema,
658
711
  harnessReadinessSchema,
659
712
  harnessSchema,
@@ -679,6 +732,8 @@ export {
679
732
  runParentIntentSchema,
680
733
  runParentSchema,
681
734
  runSpecSchema,
735
+ runUsageCapability,
736
+ runUsageSchema,
682
737
  runViewSchema,
683
738
  runnerAdoptRequestSchema,
684
739
  runnerDisconnectPreviewSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drisp/protocol",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
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",
@@ -357,6 +357,10 @@
357
357
  "tokenCap"
358
358
  ],
359
359
  "additionalProperties": false
360
+ },
361
+ "reportUsage": {
362
+ "type": "boolean",
363
+ "const": true
360
364
  }
361
365
  },
362
366
  "required": [
@@ -308,6 +308,10 @@
308
308
  "tokenCap"
309
309
  ],
310
310
  "additionalProperties": false
311
+ },
312
+ "reportUsage": {
313
+ "type": "boolean",
314
+ "const": true
311
315
  }
312
316
  },
313
317
  "required": [
@@ -112,6 +112,26 @@
112
112
  ],
113
113
  "additionalProperties": false
114
114
  },
115
+ "usage": {
116
+ "type": "object",
117
+ "properties": {
118
+ "counted": {
119
+ "type": "integer",
120
+ "minimum": 0,
121
+ "maximum": 9007199254740991
122
+ },
123
+ "cacheRead": {
124
+ "type": "integer",
125
+ "minimum": 0,
126
+ "maximum": 9007199254740991
127
+ }
128
+ },
129
+ "required": [
130
+ "counted",
131
+ "cacheRead"
132
+ ],
133
+ "additionalProperties": false
134
+ },
115
135
  "workflow": {
116
136
  "type": "object",
117
137
  "properties": {
@@ -720,6 +720,26 @@
720
720
  "additionalProperties": false
721
721
  }
722
722
  ]
723
+ },
724
+ "usage": {
725
+ "type": "object",
726
+ "properties": {
727
+ "counted": {
728
+ "type": "integer",
729
+ "minimum": 0,
730
+ "maximum": 9007199254740991
731
+ },
732
+ "cacheRead": {
733
+ "type": "integer",
734
+ "minimum": 0,
735
+ "maximum": 9007199254740991
736
+ }
737
+ },
738
+ "required": [
739
+ "counted",
740
+ "cacheRead"
741
+ ],
742
+ "additionalProperties": false
723
743
  }
724
744
  },
725
745
  "required": [
@@ -787,6 +807,26 @@
787
807
  "build_not_approved",
788
808
  "approval_question_missing"
789
809
  ]
810
+ },
811
+ "usage": {
812
+ "type": "object",
813
+ "properties": {
814
+ "counted": {
815
+ "type": "integer",
816
+ "minimum": 0,
817
+ "maximum": 9007199254740991
818
+ },
819
+ "cacheRead": {
820
+ "type": "integer",
821
+ "minimum": 0,
822
+ "maximum": 9007199254740991
823
+ }
824
+ },
825
+ "required": [
826
+ "counted",
827
+ "cacheRead"
828
+ ],
829
+ "additionalProperties": false
790
830
  }
791
831
  },
792
832
  "required": [
@@ -800,6 +840,43 @@
800
840
  ],
801
841
  "additionalProperties": false
802
842
  },
843
+ {
844
+ "type": "object",
845
+ "properties": {
846
+ "kind": {
847
+ "type": "string",
848
+ "const": "run.usage"
849
+ },
850
+ "runId": {
851
+ "type": "string",
852
+ "minLength": 1,
853
+ "maxLength": 160
854
+ },
855
+ "attemptId": {
856
+ "type": "string",
857
+ "minLength": 1,
858
+ "maxLength": 160
859
+ },
860
+ "counted": {
861
+ "type": "integer",
862
+ "minimum": 0,
863
+ "maximum": 9007199254740991
864
+ },
865
+ "cacheRead": {
866
+ "type": "integer",
867
+ "minimum": 0,
868
+ "maximum": 9007199254740991
869
+ }
870
+ },
871
+ "required": [
872
+ "kind",
873
+ "runId",
874
+ "attemptId",
875
+ "counted",
876
+ "cacheRead"
877
+ ],
878
+ "additionalProperties": false
879
+ },
803
880
  {
804
881
  "type": "object",
805
882
  "properties": {