@usine/config 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,10 +41,12 @@ repos:
41
41
 
42
42
  ## Settings and workers
43
43
 
44
- `settings.max_children` (default 4) limits the child sessions, sequential and concurrent, that one attempt can start. Without a `workers` key, the parser adds a local worker named `local` that runs one attempt at a time. A worker's `kind` (`local`, `exe.dev`, or `ssh`) selects its executor.
44
+ `settings.max_children` (default 4) limits the child sessions, sequential and concurrent, that one attempt can start. Without a `workers` key, the parser adds a local worker named `local` that runs one attempt at a time. A worker's `kind` (`local`, `exe.dev`, or `ssh`) selects its executor. An SSH worker's `container` (`WorkerContainer`) sets the image and the `cpus`, `memory_mib`, and `pids` limits of each attempt container; each limit is optional, and the executor derives an unset one from the machine at preflight.
45
45
 
46
46
  Issue and pull request loops accept `max_cycles`, a positive integer (default 3): the number of runs each loop can open on an item between operator resets. The first admission past it blocks runs from every loop on the item. Schedule loops are exempt. See [Write review and fix loops](https://docs.usine.dev/guides/review-fix-loops/).
47
47
 
48
+ A loop's optional `priority`, a positive integer (`LoopFile.priority`, `LoopPriority`), ranks its runs for a free worker slot before runs that lane order ranks, higher first. See [Loop files](https://docs.usine.dev/reference/configuration/loop-files/#priority).
49
+
48
50
  ## Load an instance
49
51
 
50
52
  `InstanceFolder.load` takes an `InstanceDirectory` (`@usine/core/instance`) and returns one atomic `LoadedInstance` snapshot:
package/dist/board.d.ts CHANGED
@@ -3,11 +3,14 @@ export declare const LaneName: Schema.brand<Schema.String, "LaneName">;
3
3
  export type LaneName = typeof LaneName.Type;
4
4
  export declare const LaneItemState: Schema.Literals<readonly ["issue-open", "issue-closed", "pr-open", "pr-closed", "pr-merged"]>;
5
5
  export type LaneItemState = typeof LaneItemState.Type;
6
+ /** The state of a closed issue or a closed or merged pull request. */
7
+ export declare const SettledItemState: Schema.Literals<readonly ["issue-closed", "pr-closed", "pr-merged"]>;
8
+ export type SettledItemState = typeof SettledItemState.Type;
6
9
  /**
7
10
  * Returns whether `state` is a closed issue or a closed or merged pull request, which the Board
8
11
  * places by state regardless of labels.
9
12
  */
10
- export declare const isSettledItemState: (state: LaneItemState) => boolean;
13
+ export declare const isSettledItemState: (state: LaneItemState) => state is SettledItemState;
11
14
  declare const LabelLaneSource_base: Schema.Class<LabelLaneSource, Schema.Struct<{
12
15
  readonly label: Schema.brand<Schema.String, "GitHubLabelName">;
13
16
  }>, {}>;
@@ -1 +1 @@
1
- {"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,eAAO,MAAM,QAAQ,yCAEpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAE5C,eAAO,MAAM,aAAa,+FAMxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAQtD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAW,aAAa,KAAG,OAAyC,CAAC;;;;AAEpG,0FAA0F;AAC1F,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;;;;AAEJ,sFAAsF;AACtF,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;AAEJ,eAAO,MAAM,UAAU,yEAAmD,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;;;;;AAEhD,wEAAwE;AACxE,qBAAa,IAAK,SAAQ,SAGxB;CAAG"}
1
+ {"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,eAAO,MAAM,QAAQ,yCAEpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAE5C,eAAO,MAAM,aAAa,+FAMxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAEtD,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,sEAA8D,CAAC;AAE5F,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAC;AAI5D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAW,aAAa,KAAG,KAAK,IAAI,gBACjD,CAAC;;;;AAEnB,0FAA0F;AAC1F,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;;;;AAEJ,sFAAsF;AACtF,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;AAEJ,eAAO,MAAM,UAAU,yEAAmD,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;;;;;AAEhD,wEAAwE;AACxE,qBAAa,IAAK,SAAQ,SAGxB;CAAG"}
package/dist/board.js CHANGED
@@ -9,16 +9,14 @@ export const LaneItemState = Schema.Literals([
9
9
  "pr-closed",
10
10
  "pr-merged",
11
11
  ]);
12
- const SETTLED_ITEM_STATES = new Set([
13
- "issue-closed",
14
- "pr-closed",
15
- "pr-merged",
16
- ]);
12
+ /** The state of a closed issue or a closed or merged pull request. */
13
+ export const SettledItemState = Schema.Literals(["issue-closed", "pr-closed", "pr-merged"]);
14
+ const isSettled = Schema.is(SettledItemState);
17
15
  /**
18
16
  * Returns whether `state` is a closed issue or a closed or merged pull request, which the Board
19
17
  * places by state regardless of labels.
20
18
  */
21
- export const isSettledItemState = (state) => SETTLED_ITEM_STATES.has(state);
19
+ export const isSettledItemState = (state) => isSettled(state);
22
20
  /** A lane source that matches Items with this GitHub label, which Board moves can set. */
23
21
  export class LabelLaneSource extends Schema.Class("@usine/config/LabelLaneSource")({
24
22
  label: GitHubLabelName,
package/dist/board.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"board.js","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAC3E,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CACzB,CAAC;AAIF,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3C,YAAY;IACZ,cAAc;IACd,SAAS;IACT,WAAW;IACX,WAAW;CACZ,CAAC,CAAC;AAIH,MAAM,mBAAmB,GAA+B,IAAI,GAAG,CAAC;IAC9D,cAAc;IACd,WAAW;IACX,WAAW;CACZ,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAoB,EAAW,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAEpG,0FAA0F;AAC1F,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,eAAe;CACvB,CACF;CAAG;AAEJ,sFAAsF;AACtF,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,aAAa;CACrB,CACF;CAAG;AAEJ,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;AAI3E,wEAAwE;AACxE,MAAM,OAAO,IAAK,SAAQ,MAAM,CAAC,KAAK,CAAO,oBAAoB,CAAC,CAAC;IACjE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;CAC7D,CAAC;CAAG"}
1
+ {"version":3,"file":"board.js","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAC3E,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CACzB,CAAC;AAIF,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3C,YAAY;IACZ,cAAc;IACd,SAAS;IACT,WAAW;IACX,WAAW;CACZ,CAAC,CAAC;AAIH,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;AAI5F,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAoB,EAA6B,EAAE,CACpF,SAAS,CAAC,KAAK,CAAC,CAAC;AAEnB,0FAA0F;AAC1F,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,eAAe;CACvB,CACF;CAAG;AAEJ,sFAAsF;AACtF,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,aAAa;CACrB,CACF;CAAG;AAEJ,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;AAI3E,wEAAwE;AACxE,MAAM,OAAO,IAAK,SAAQ,MAAM,CAAC,KAAK,CAAO,oBAAoB,CAAC,CAAC;IACjE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;CAC7D,CAAC;CAAG"}
package/dist/factory.d.ts CHANGED
@@ -32,7 +32,7 @@ declare const WorkerGateway_base: Schema.Class<WorkerGateway, Schema.Struct<{
32
32
  readonly destination: Schema.brand<Schema.String, "SshDestination">;
33
33
  readonly adminPort: Schema.withDecodingDefaultKey<Schema.brand<Schema.Int, "GatewayAdminPort">, never>;
34
34
  readonly adminTokenEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
35
- readonly llmProviders: Schema.withDecodingDefaultKey<Schema.$Array<Schema.Literals<readonly ["anthropic"]>>, never>;
35
+ readonly llmProviders: Schema.withDecodingDefaultKey<Schema.$Array<Schema.Literals<readonly ["anthropic", "openai"]>>, never>;
36
36
  }>, {}>;
37
37
  /**
38
38
  * The Gateway in front of an SSH Worker's machine on a private network (ADR 0027).
@@ -43,16 +43,111 @@ declare const WorkerGateway_base: Schema.Class<WorkerGateway, Schema.Struct<{
43
43
  * Gateway's loopback interface.
44
44
  * - `adminTokenEnv`: the orchestrator environment variable with the admin token, read when
45
45
  * `usine up` starts or a reload adds the Worker.
46
- * - `llmProviders`: the providers whose credential the Gateway injects. Harnesses for other
47
- * providers, and Codex, use the operator's login on the Worker through the forward proxy.
46
+ * - `llmProviders`: the providers whose credential the Gateway injects: `anthropic` for Claude
47
+ * Code, `openai` for Codex. Harnesses for other providers use the operator's login on the
48
+ * Worker through the forward proxy.
48
49
  */
49
50
  export declare class WorkerGateway extends WorkerGateway_base {
50
51
  }
52
+ declare const WorkerContainer_base: Schema.Class<WorkerContainer, Schema.Struct<{
53
+ readonly image: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "ContainerImage">>;
54
+ readonly cpus: Schema.OptionFromOptionalKey<Schema.brand<Schema.Finite, "ContainerCpus">>;
55
+ readonly memoryMib: Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "ContainerMemoryMib">>;
56
+ readonly pids: Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "ContainerPids">>;
57
+ }>, {}>;
58
+ /**
59
+ * The container that each Attempt on an SSH Worker runs in, if the machine has Docker.
60
+ *
61
+ * - `image`: the image to run. If `None`, the executor's image for the harness versions of this
62
+ * release.
63
+ * - `cpus`, `memoryMib`, and `pids`: the limits of each Attempt's container. If `None`, the
64
+ * executor derives the limit from the machine at preflight: the machine's total less a reserve
65
+ * for its own processes, divided by `maxConcurrentAttempts`.
66
+ */
67
+ export declare class WorkerContainer extends WorkerContainer_base {
68
+ }
69
+ declare const ProviderApiKeys_base: Schema.Class<ProviderApiKeys, Schema.Struct<{
70
+ readonly anthropic: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "EnvironmentVariableName">>;
71
+ readonly openai: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "EnvironmentVariableName">>;
72
+ }>, {}>;
73
+ /**
74
+ * The orchestrator environment variables with the LLM provider API keys that each Attempt on a
75
+ * provisioned Worker gets in its environment, read when `usine up` starts or a reload adds the
76
+ * Worker. `anthropic` becomes `ANTHROPIC_API_KEY` for Claude Code, and `openai` becomes
77
+ * `OPENAI_API_KEY` for Codex.
78
+ */
79
+ export declare class ProviderApiKeys extends ProviderApiKeys_base {
80
+ }
81
+ declare const HetznerProvisioner_base: Schema.Class<HetznerProvisioner, Schema.Struct<{
82
+ readonly provider: Schema.Literal<"hetzner">;
83
+ readonly tokenEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
84
+ readonly serverType: Schema.brand<Schema.String, "HetznerServerType">;
85
+ readonly location: Schema.brand<Schema.String, "HetznerLocation">;
86
+ readonly image: Schema.brand<Schema.String, "HetznerImage">;
87
+ readonly network: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "HetznerResourceName">>;
88
+ readonly firewall: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "HetznerResourceName">>;
89
+ readonly sshKey: Schema.brand<Schema.String, "HetznerResourceName">;
90
+ readonly sshUser: Schema.withDecodingDefaultKey<Schema.brand<Schema.String, "SshUser">, never>;
91
+ readonly labels: Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>;
92
+ readonly apiKeys: Schema.withDecodingDefaultKey<typeof ProviderApiKeys, never>;
93
+ }>, {}>;
94
+ /**
95
+ * Creates one Hetzner Cloud server per Attempt from a snapshot, and deletes it after the
96
+ * Attempt (#550).
97
+ *
98
+ * - `tokenEnv`: the orchestrator environment variable with a Hetzner Cloud API token with read
99
+ * and write access to the project.
100
+ * - `serverType` and `location`: each server's type and location.
101
+ * - `image`: the snapshot's ID or description, which `infra/hetzner/snapshot.sh` prints.
102
+ * - `network`: the private network to attach each server to. With a Gateway, it's the Gateway's
103
+ * network and the server gets no public address.
104
+ * - `firewall`: the project's firewall to apply to each server, such as one that admits SSH only
105
+ * from the orchestrator's address to a server with a public address.
106
+ * - `sshKey`: the name of the SSH key in the project that each server authorizes.
107
+ * - `sshUser`: the user the executor connects as.
108
+ * - `labels`: extra labels for each server.
109
+ * - `apiKeys`: provider API keys for each Attempt, for harnesses whose credential the Gateway
110
+ * doesn't have.
111
+ */
112
+ export declare class HetznerProvisioner extends HetznerProvisioner_base {
113
+ }
114
+ declare const BoatProvisioner_base: Schema.Class<BoatProvisioner, Schema.Struct<{
115
+ readonly provider: Schema.Literal<"boat">;
116
+ readonly tokenEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
117
+ readonly size: Schema.withDecodingDefaultKey<Schema.Literals<readonly ["small", "default", "large", "xlarge"]>, never>;
118
+ readonly apiKeys: Schema.withDecodingDefaultKey<typeof ProviderApiKeys, never>;
119
+ }>, {}>;
120
+ /**
121
+ * Creates one Boat sandbox per Attempt and deletes it after the Attempt (#550). Boat has no
122
+ * network rules, so a Boat Worker has no Gateway, and each Attempt's GitHub token is on its
123
+ * machine (ADR 0026). Boat documents no region choice; its machines are in Germany, Finland, and
124
+ * France.
125
+ *
126
+ * - `tokenEnv`: the orchestrator environment variable with a Boat API key.
127
+ * - `size`: each sandbox's Boat machine type.
128
+ * - `apiKeys`: provider API keys for each Attempt. A harness without one can't authenticate,
129
+ * because a subscription login needs a Gateway.
130
+ */
131
+ export declare class BoatProvisioner extends BoatProvisioner_base {
132
+ }
133
+ /** The provider that creates one machine per Attempt for an SSH Worker; `provider` selects it. */
134
+ export declare const WorkerProvisioner: Schema.Union<readonly [typeof HetznerProvisioner, typeof BoatProvisioner]>;
135
+ export type WorkerProvisioner = typeof WorkerProvisioner.Type;
51
136
  declare const SshWorker_base: Schema.Class<SshWorker, Schema.Struct<{
52
137
  readonly name: Schema.brand<Schema.String, "WorkerName">;
53
138
  readonly kind: Schema.Literal<"ssh">;
54
139
  readonly maxConcurrentAttempts: Schema.withDecodingDefaultKey<Schema.Int, never>;
55
- readonly destination: Schema.brand<Schema.String, "SshDestination">;
140
+ readonly destination: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshDestination">>;
141
+ readonly provisioner: Schema.OptionFromOptionalKey<Schema.Union<readonly [Schema.encodeKeys<typeof HetznerProvisioner, {
142
+ readonly tokenEnv: "token_env";
143
+ readonly serverType: "server_type";
144
+ readonly sshKey: "ssh_key";
145
+ readonly sshUser: "ssh_user";
146
+ readonly apiKeys: "api_keys";
147
+ }>, Schema.encodeKeys<typeof BoatProvisioner, {
148
+ readonly tokenEnv: "token_env";
149
+ readonly apiKeys: "api_keys";
150
+ }>]>>;
56
151
  readonly identityFile: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshIdentityFile">>;
57
152
  readonly port: Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "SshPort">>;
58
153
  readonly root: Schema.brand<Schema.String, "WorkerRoot">;
@@ -61,16 +156,58 @@ declare const SshWorker_base: Schema.Class<SshWorker, Schema.Struct<{
61
156
  readonly adminTokenEnv: "admin_token_env";
62
157
  readonly llmProviders: "llm_providers";
63
158
  }>>;
159
+ readonly container: Schema.withDecodingDefaultKey<Schema.encodeKeys<typeof WorkerContainer, {
160
+ readonly memoryMib: "memory_mib";
161
+ }>, never>;
64
162
  }>, {}>;
65
163
  /**
66
164
  * A Linux machine reached with `ssh`, with Worker state under `<root>/workers/<name>`. If
67
165
  * `gateway` is set, the machine stores no GitHub token; the executor sends each Attempt's token
68
- * to the Gateway.
166
+ * to the Gateway. A Worker sets either `destination`, for one long-lived machine, or
167
+ * `provisioner`, for one machine per Attempt; `maxConcurrentAttempts` then caps the machines in
168
+ * flight.
69
169
  */
70
170
  export declare class SshWorker extends SshWorker_base {
71
171
  }
172
+ declare const CloudflareLlmProviderKey_base: Schema.Class<CloudflareLlmProviderKey, Schema.Struct<{
173
+ readonly provider: Schema.Literals<readonly ["anthropic", "openai"]>;
174
+ readonly apiKeyEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
175
+ }>, {}>;
176
+ /**
177
+ * An LLM provider whose API key the Cloudflare Worker's outbound handlers hold for each Attempt.
178
+ * `apiKeyEnv` is the orchestrator environment variable with the key, read when `usine up` starts.
179
+ */
180
+ export declare class CloudflareLlmProviderKey extends CloudflareLlmProviderKey_base {
181
+ }
182
+ declare const CloudflareWorker_base: Schema.Class<CloudflareWorker, Schema.Struct<{
183
+ readonly name: Schema.brand<Schema.String, "WorkerName">;
184
+ readonly kind: Schema.Literal<"cloudflare">;
185
+ readonly maxConcurrentAttempts: Schema.withDecodingDefaultKey<Schema.Int, never>;
186
+ readonly workerUrl: Schema.URLFromString;
187
+ readonly accessClientIdEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
188
+ readonly accessClientSecretEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
189
+ readonly image: Schema.brand<Schema.String, "CloudflareImageName">;
190
+ readonly instanceType: Schema.withDecodingDefaultKey<Schema.Literals<readonly ["lite", "basic", "standard-1", "standard-2", "standard-3", "standard-4"]>, never>;
191
+ readonly llmProviders: Schema.withDecodingDefaultKey<Schema.$Array<Schema.encodeKeys<typeof CloudflareLlmProviderKey, {
192
+ readonly apiKeyEnv: "api_key_env";
193
+ }>>, never>;
194
+ }>, {}>;
195
+ /**
196
+ * A Worker that runs each Attempt in its own Cloudflare sandbox, through the Worker that the
197
+ * operator deploys from `@usine/cloudflare`.
198
+ *
199
+ * - `workerUrl`: the deployed Worker's origin.
200
+ * - `accessClientIdEnv` and `accessClientSecretEnv`: the orchestrator environment variables with
201
+ * the Cloudflare Access service token that the Worker accepts, read when `usine up` starts.
202
+ * - `image`: the name of the image in the Worker's `containers[].images`.
203
+ * - `instanceType`: the container instance type of each sandbox.
204
+ * - `llmProviders`: the providers whose API key the Worker's outbound handlers inject. Claude Code
205
+ * needs `anthropic` and Codex needs `openai`; a sandbox holds no harness login.
206
+ */
207
+ export declare class CloudflareWorker extends CloudflareWorker_base {
208
+ }
72
209
  /** A configured Worker; `kind` selects the adapter. */
73
- export declare const Worker: Schema.Union<readonly [typeof LocalWorker, typeof ExeDevWorker, typeof SshWorker]>;
210
+ export declare const Worker: Schema.Union<readonly [typeof LocalWorker, typeof ExeDevWorker, typeof SshWorker, typeof CloudflareWorker]>;
74
211
  export type Worker = typeof Worker.Type;
75
212
  declare const Settings_base: Schema.Class<Settings, Schema.Struct<{
76
213
  /** The interval between GitHub polling cycles, in seconds. */
@@ -100,6 +237,18 @@ export declare const Webhooks: Schema.Union<readonly [Schema.Struct<{
100
237
  readonly publicUrl: "public_url";
101
238
  }>]>;
102
239
  export type Webhooks = typeof Webhooks.Type;
240
+ declare const Tracing_base: Schema.Class<Tracing, Schema.Struct<{
241
+ /**
242
+ * The collector's OTLP/HTTP traces endpoint, used as given, such as
243
+ * `http://localhost:4318/v1/traces`. It has no credentials or query string.
244
+ */
245
+ readonly otlpUrl: Schema.URLFromString;
246
+ /** The `service.name` resource attribute of every exported span. */
247
+ readonly serviceName: Schema.withDecodingDefaultKey<Schema.String, never>;
248
+ }>, {}>;
249
+ /** Span export over OTLP/HTTP (ADR 0028). */
250
+ export declare class Tracing extends Tracing_base {
251
+ }
103
252
  declare const UsineConfig_base: Schema.Class<UsineConfig, Schema.Struct<{
104
253
  readonly version: Schema.Literal<1>;
105
254
  readonly labels: Schema.withDecodingDefaultKey<Schema.$Array<typeof DeclaredLabel>, never>;
@@ -116,9 +265,39 @@ declare const UsineConfig_base: Schema.Class<UsineConfig, Schema.Struct<{
116
265
  readonly maxConcurrentAttempts: "max_concurrent_attempts";
117
266
  }>, Schema.encodeKeys<typeof ExeDevWorker, {
118
267
  readonly maxConcurrentAttempts: "max_concurrent_attempts";
119
- }>, Schema.encodeKeys<typeof SshWorker, {
268
+ }>, Schema.decodeTo<typeof SshWorker, Schema.Struct<{
269
+ readonly container: Schema.toEncoded<Schema.withDecodingDefaultKey<Schema.encodeKeys<typeof WorkerContainer, {
270
+ readonly memoryMib: "memory_mib";
271
+ }>, never>>;
272
+ readonly destination: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshDestination">>>;
273
+ readonly gateway: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.encodeKeys<typeof WorkerGateway, {
274
+ readonly adminPort: "admin_port";
275
+ readonly adminTokenEnv: "admin_token_env";
276
+ readonly llmProviders: "llm_providers";
277
+ }>>>;
278
+ readonly identity_file: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshIdentityFile">>>;
279
+ readonly kind: Schema.toEncoded<Schema.Literal<"ssh">>;
280
+ readonly max_concurrent_attempts: Schema.toEncoded<Schema.withDecodingDefaultKey<Schema.Int, never>>;
281
+ readonly name: Schema.toEncoded<Schema.brand<Schema.String, "WorkerName">>;
282
+ readonly port: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "SshPort">>>;
283
+ readonly provisioner: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.Union<readonly [Schema.encodeKeys<typeof HetznerProvisioner, {
284
+ readonly tokenEnv: "token_env";
285
+ readonly serverType: "server_type";
286
+ readonly sshKey: "ssh_key";
287
+ readonly sshUser: "ssh_user";
288
+ readonly apiKeys: "api_keys";
289
+ }>, Schema.encodeKeys<typeof BoatProvisioner, {
290
+ readonly tokenEnv: "token_env";
291
+ readonly apiKeys: "api_keys";
292
+ }>]>>>;
293
+ readonly root: Schema.toEncoded<Schema.brand<Schema.String, "WorkerRoot">>;
294
+ }>, never, never>, Schema.encodeKeys<typeof CloudflareWorker, {
120
295
  readonly maxConcurrentAttempts: "max_concurrent_attempts";
121
- readonly identityFile: "identity_file";
296
+ readonly workerUrl: "worker_url";
297
+ readonly accessClientIdEnv: "access_client_id_env";
298
+ readonly accessClientSecretEnv: "access_client_secret_env";
299
+ readonly instanceType: "instance_type";
300
+ readonly llmProviders: "llm_providers";
122
301
  }>]>>, never>;
123
302
  readonly webhooks: Schema.withDecodingDefaultKey<Schema.Union<readonly [Schema.Struct<{
124
303
  readonly mode: Schema.Literal<"off">;
@@ -131,6 +310,10 @@ declare const UsineConfig_base: Schema.Class<UsineConfig, Schema.Struct<{
131
310
  readonly publicUrl: "public_url";
132
311
  }>]>, never>;
133
312
  readonly operator: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "OperatorLogin">>;
313
+ readonly tracing: Schema.OptionFromOptionalKey<Schema.encodeKeys<typeof Tracing, {
314
+ readonly otlpUrl: "otlp_url";
315
+ readonly serviceName: "service_name";
316
+ }>>;
134
317
  }>, {}>;
135
318
  /** The decoded `usine.yaml`. */
136
319
  export declare class UsineConfig extends UsineConfig_base {
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAcA,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAc,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D,kDAAkD;AAClD,eAAO,MAAM,WAAW,4CAEvB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;;;;;;AA6BlD,qBAAa,WAAY,SAAQ,gBAM/B;CAAG;;;;;;AAIL,iEAAiE;AACjE,qBAAa,WAAY,SAAQ,gBAI/B;CAAG;;;;;;AAEL,qDAAqD;AACrD,qBAAa,YAAa,SAAQ,iBAIhC;CAAG;;;;;;;;AAQL;;;;;;;;;;;GAWG;AACH,qBAAa,aAAc,SAAQ,kBAQjC;CAAG;;;;;;;;;;;;;;;AAEL;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAiB7B;CAAG;AAEL,uDAAuD;AACvD,eAAO,MAAM,MAAM,oFAAuD,CAAC;AAC3E,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;;IAGtC,8DAA8D;;IAE9D,oFAAoF;;IAEpF,4EAA4E;;IAE5E,gGAAgG;;IAEhG,gFAAgF;;IAEhF,iGAAiG;;;AAXnG,qBAAa,QAAS,SAAQ,aAa5B;CAAG;AAEL,uGAAuG;AACvG,eAAO,MAAM,QAAQ;;;;;;;;;IAMnB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8B5C,gCAAgC;AAChC,qBAAa,WAAY,SAAQ,gBAU/B;CAAG"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAkB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,EAAc,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D,kDAAkD;AAClD,eAAO,MAAM,WAAW,4CAEvB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;;;;;;AA6BlD,qBAAa,WAAY,SAAQ,gBAM/B;CAAG;;;;;;AAIL,iEAAiE;AACjE,qBAAa,WAAY,SAAQ,gBAI/B;CAAG;;;;;;AAEL,qDAAqD;AACrD,qBAAa,YAAa,SAAQ,iBAIhC;CAAG;;;;;;;;AAQL;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,kBAQjC;CAAG;;;;;;;AAEL;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,oBAOpC;CAAG;;;;;AAEJ;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,oBAKpC;CAAG;;;;;;;;;;;;;;AAMJ;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,kBAAmB,SAAQ,uBActC;CAAG;;;;;;;AAEL;;;;;;;;;;GAUG;AACH,qBAAa,eAAgB,SAAQ,oBAOpC;CAAG;AAEJ,kGAAkG;AAClG,eAAO,MAAM,iBAAiB,4EAAsD,CAAC;AACrF,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAe9D;;;;;;GAMG;AACH,qBAAa,SAAU,SAAQ,cAsB7B;CAAG;;;;;AAuCL;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,6BAK5C;CAAG;;;;;;;;;;;;;;AAOL;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAiB,SAAQ,qBAkBpC;CAAG;AAEL,uDAAuD;AACvD,eAAO,MAAM,MAAM,6GAAyE,CAAC;AAC7F,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC;;IAGtC,8DAA8D;;IAE9D,oFAAoF;;IAEpF,4EAA4E;;IAE5E,gGAAgG;;IAEhG,gFAAgF;;IAEhF,iGAAiG;;;AAXnG,qBAAa,QAAS,SAAQ,aAa5B;CAAG;AAEL,uGAAuG;AACvG,eAAO,MAAM,QAAQ;;;;;;;;;IAMnB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;;IAc1C;;;OAGG;;IAEH,oEAAoE;;;AAPtE,6CAA6C;AAC7C,qBAAa,OAAQ,SAAQ,YAU3B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCL,gCAAgC;AAChC,qBAAa,WAAY,SAAQ,gBAa/B;CAAG"}
package/dist/factory.js CHANGED
@@ -2,8 +2,8 @@ import { Effort, ModelId } from "@usine/core/agent/brain";
2
2
  import { ChildSessionBudget } from "@usine/core/agent/session";
3
3
  import { OperatorLogin } from "@usine/core/operator";
4
4
  import { RepositoryName } from "@usine/core/repository";
5
- import { GatewayAdminPort, GatewayDomain, GatewayLlmProvider, SshDestination, SshIdentityFile, SshPort, WorkerName, WorkerRoot, } from "@usine/core/worker";
6
- import { Effect, Schema } from "effect";
5
+ import { BoatSize, CloudflareImageName, CloudflareInstanceType, CloudflareLlmProvider, ContainerCpus, ContainerImage, ContainerMemoryMib, ContainerPids, GatewayAdminPort, GatewayDomain, GatewayLlmProvider, HetznerImage, HetznerLabels, HetznerLocation, HetznerResourceName, HetznerServerType, SshDestination, SshIdentityFile, SshPort, SshUser, WorkerName, WorkerRoot, } from "@usine/core/worker";
6
+ import { Effect, Option, Schema } from "effect";
7
7
  import { nonBlankString, uniqueRepositoryNames } from "./checks.js";
8
8
  import { LaneSource, Lane } from "./board.js";
9
9
  import { canonicalLabelName, DeclaredLabel } from "./label.js";
@@ -54,8 +54,9 @@ const EnvironmentVariableName = Schema.String.check(Schema.isPattern(/^[A-Za-z_]
54
54
  * Gateway's loopback interface.
55
55
  * - `adminTokenEnv`: the orchestrator environment variable with the admin token, read when
56
56
  * `usine up` starts or a reload adds the Worker.
57
- * - `llmProviders`: the providers whose credential the Gateway injects. Harnesses for other
58
- * providers, and Codex, use the operator's login on the Worker through the forward proxy.
57
+ * - `llmProviders`: the providers whose credential the Gateway injects: `anthropic` for Claude
58
+ * Code, `openai` for Codex. Harnesses for other providers use the operator's login on the
59
+ * Worker through the forward proxy.
59
60
  */
60
61
  export class WorkerGateway extends Schema.Class("@usine/config/WorkerGateway")({
61
62
  domain: GatewayDomain,
@@ -67,16 +68,109 @@ export class WorkerGateway extends Schema.Class("@usine/config/WorkerGateway")({
67
68
  .pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
68
69
  }) {
69
70
  }
71
+ /**
72
+ * The container that each Attempt on an SSH Worker runs in, if the machine has Docker.
73
+ *
74
+ * - `image`: the image to run. If `None`, the executor's image for the harness versions of this
75
+ * release.
76
+ * - `cpus`, `memoryMib`, and `pids`: the limits of each Attempt's container. If `None`, the
77
+ * executor derives the limit from the machine at preflight: the machine's total less a reserve
78
+ * for its own processes, divided by `maxConcurrentAttempts`.
79
+ */
80
+ export class WorkerContainer extends Schema.Class("@usine/config/WorkerContainer")({
81
+ image: Schema.OptionFromOptionalKey(ContainerImage),
82
+ cpus: Schema.OptionFromOptionalKey(ContainerCpus),
83
+ memoryMib: Schema.OptionFromOptionalKey(ContainerMemoryMib),
84
+ pids: Schema.OptionFromOptionalKey(ContainerPids),
85
+ }) {
86
+ }
87
+ /**
88
+ * The orchestrator environment variables with the LLM provider API keys that each Attempt on a
89
+ * provisioned Worker gets in its environment, read when `usine up` starts or a reload adds the
90
+ * Worker. `anthropic` becomes `ANTHROPIC_API_KEY` for Claude Code, and `openai` becomes
91
+ * `OPENAI_API_KEY` for Codex.
92
+ */
93
+ export class ProviderApiKeys extends Schema.Class("@usine/config/ProviderApiKeys")({
94
+ anthropic: Schema.OptionFromOptionalKey(EnvironmentVariableName),
95
+ openai: Schema.OptionFromOptionalKey(EnvironmentVariableName),
96
+ }) {
97
+ }
98
+ const ProviderApiKeysFromYaml = ProviderApiKeys.pipe(Schema.withDecodingDefaultKey(Effect.succeed({})));
99
+ /**
100
+ * Creates one Hetzner Cloud server per Attempt from a snapshot, and deletes it after the
101
+ * Attempt (#550).
102
+ *
103
+ * - `tokenEnv`: the orchestrator environment variable with a Hetzner Cloud API token with read
104
+ * and write access to the project.
105
+ * - `serverType` and `location`: each server's type and location.
106
+ * - `image`: the snapshot's ID or description, which `infra/hetzner/snapshot.sh` prints.
107
+ * - `network`: the private network to attach each server to. With a Gateway, it's the Gateway's
108
+ * network and the server gets no public address.
109
+ * - `firewall`: the project's firewall to apply to each server, such as one that admits SSH only
110
+ * from the orchestrator's address to a server with a public address.
111
+ * - `sshKey`: the name of the SSH key in the project that each server authorizes.
112
+ * - `sshUser`: the user the executor connects as.
113
+ * - `labels`: extra labels for each server.
114
+ * - `apiKeys`: provider API keys for each Attempt, for harnesses whose credential the Gateway
115
+ * doesn't have.
116
+ */
117
+ export class HetznerProvisioner extends Schema.Class("@usine/config/HetznerProvisioner")({
118
+ provider: Schema.Literal("hetzner"),
119
+ tokenEnv: EnvironmentVariableName,
120
+ serverType: HetznerServerType,
121
+ location: HetznerLocation,
122
+ image: HetznerImage,
123
+ network: Schema.OptionFromOptionalKey(HetznerResourceName),
124
+ firewall: Schema.OptionFromOptionalKey(HetznerResourceName),
125
+ sshKey: HetznerResourceName,
126
+ sshUser: SshUser.pipe(Schema.withDecodingDefaultKey(Effect.succeed("usine"))),
127
+ labels: HetznerLabels.pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
128
+ apiKeys: ProviderApiKeysFromYaml,
129
+ }) {
130
+ }
131
+ /**
132
+ * Creates one Boat sandbox per Attempt and deletes it after the Attempt (#550). Boat has no
133
+ * network rules, so a Boat Worker has no Gateway, and each Attempt's GitHub token is on its
134
+ * machine (ADR 0026). Boat documents no region choice; its machines are in Germany, Finland, and
135
+ * France.
136
+ *
137
+ * - `tokenEnv`: the orchestrator environment variable with a Boat API key.
138
+ * - `size`: each sandbox's Boat machine type.
139
+ * - `apiKeys`: provider API keys for each Attempt. A harness without one can't authenticate,
140
+ * because a subscription login needs a Gateway.
141
+ */
142
+ export class BoatProvisioner extends Schema.Class("@usine/config/BoatProvisioner")({
143
+ provider: Schema.Literal("boat"),
144
+ tokenEnv: EnvironmentVariableName,
145
+ size: BoatSize.pipe(Schema.withDecodingDefaultKey(Effect.succeed("default"))),
146
+ apiKeys: ProviderApiKeysFromYaml,
147
+ }) {
148
+ }
149
+ /** The provider that creates one machine per Attempt for an SSH Worker; `provider` selects it. */
150
+ export const WorkerProvisioner = Schema.Union([HetznerProvisioner, BoatProvisioner]);
151
+ const WorkerProvisionerFromYaml = Schema.Union([
152
+ HetznerProvisioner.pipe(Schema.encodeKeys({
153
+ tokenEnv: "token_env",
154
+ serverType: "server_type",
155
+ sshKey: "ssh_key",
156
+ sshUser: "ssh_user",
157
+ apiKeys: "api_keys",
158
+ })),
159
+ BoatProvisioner.pipe(Schema.encodeKeys({ tokenEnv: "token_env", apiKeys: "api_keys" })),
160
+ ]);
70
161
  /**
71
162
  * A Linux machine reached with `ssh`, with Worker state under `<root>/workers/<name>`. If
72
163
  * `gateway` is set, the machine stores no GitHub token; the executor sends each Attempt's token
73
- * to the Gateway.
164
+ * to the Gateway. A Worker sets either `destination`, for one long-lived machine, or
165
+ * `provisioner`, for one machine per Attempt; `maxConcurrentAttempts` then caps the machines in
166
+ * flight.
74
167
  */
75
168
  export class SshWorker extends Schema.Class("@usine/config/SshWorker")({
76
169
  name: WorkerName,
77
170
  kind: Schema.Literal("ssh"),
78
171
  maxConcurrentAttempts: MaxConcurrentAttempts,
79
- destination: SshDestination,
172
+ destination: Schema.OptionFromOptionalKey(SshDestination),
173
+ provisioner: Schema.OptionFromOptionalKey(WorkerProvisionerFromYaml),
80
174
  identityFile: Schema.OptionFromOptionalKey(SshIdentityFile),
81
175
  port: Schema.OptionFromOptionalKey(SshPort),
82
176
  root: WorkerRoot,
@@ -85,10 +179,76 @@ export class SshWorker extends Schema.Class("@usine/config/SshWorker")({
85
179
  adminTokenEnv: "admin_token_env",
86
180
  llmProviders: "llm_providers",
87
181
  }))),
182
+ container: WorkerContainer.pipe(Schema.encodeKeys({ memoryMib: "memory_mib" }), Schema.withDecodingDefaultKey(Effect.succeed({}))),
183
+ }) {
184
+ }
185
+ /** Returns the reason an SSH Worker's machine settings conflict, or `undefined` if they don't. */
186
+ const sshMachineConflict = (worker) => {
187
+ const provisioner = Option.getOrUndefined(worker.provisioner);
188
+ if (provisioner === undefined)
189
+ return Option.isNone(worker.destination)
190
+ ? `SSH worker "${worker.name}" needs a destination or a provisioner`
191
+ : undefined;
192
+ if (Option.isSome(worker.destination))
193
+ return `SSH worker "${worker.name}" sets both destination and provisioner; a provisioned worker creates its machines, so remove destination`;
194
+ if (Option.isSome(worker.port))
195
+ return `SSH worker "${worker.name}" sets port, which a provisioned worker takes from its provider`;
196
+ switch (provisioner.provider) {
197
+ case "hetzner":
198
+ return Option.isSome(worker.gateway) && Option.isNone(provisioner.network)
199
+ ? `SSH worker "${worker.name}" has a gateway, so its provisioner needs the gateway's private network in network`
200
+ : undefined;
201
+ case "boat":
202
+ if (Option.isSome(worker.gateway))
203
+ return `SSH worker "${worker.name}" has a Boat provisioner and a gateway; Boat has no network rules, so no gateway can be its machines' only way out. Remove gateway.`;
204
+ return Option.isNone(worker.identityFile)
205
+ ? `SSH worker "${worker.name}" has a Boat provisioner and needs identity_file, whose .pub file usine adds to each sandbox`
206
+ : undefined;
207
+ }
208
+ };
209
+ const HttpsUrl = Schema.URLFromString.check(Schema.makeFilter((url) => url.protocol === "https:", { message: "Expected an https URL" }), Schema.makeFilter((url) => url.username === "" &&
210
+ url.password === "" &&
211
+ url.search === "" &&
212
+ url.hash === "" &&
213
+ url.pathname === "/", { message: "Expected the Worker's origin, without a path, credentials, or query string" }));
214
+ /**
215
+ * An LLM provider whose API key the Cloudflare Worker's outbound handlers hold for each Attempt.
216
+ * `apiKeyEnv` is the orchestrator environment variable with the key, read when `usine up` starts.
217
+ */
218
+ export class CloudflareLlmProviderKey extends Schema.Class("@usine/config/CloudflareLlmProviderKey")({
219
+ provider: CloudflareLlmProvider,
220
+ apiKeyEnv: EnvironmentVariableName,
221
+ }) {
222
+ }
223
+ const uniqueProviders = Schema.makeFilter((values) => new Set(values.map(({ provider }) => provider)).size === values.length, { message: "Expected each provider once" });
224
+ /**
225
+ * A Worker that runs each Attempt in its own Cloudflare sandbox, through the Worker that the
226
+ * operator deploys from `@usine/cloudflare`.
227
+ *
228
+ * - `workerUrl`: the deployed Worker's origin.
229
+ * - `accessClientIdEnv` and `accessClientSecretEnv`: the orchestrator environment variables with
230
+ * the Cloudflare Access service token that the Worker accepts, read when `usine up` starts.
231
+ * - `image`: the name of the image in the Worker's `containers[].images`.
232
+ * - `instanceType`: the container instance type of each sandbox.
233
+ * - `llmProviders`: the providers whose API key the Worker's outbound handlers inject. Claude Code
234
+ * needs `anthropic` and Codex needs `openai`; a sandbox holds no harness login.
235
+ */
236
+ export class CloudflareWorker extends Schema.Class("@usine/config/CloudflareWorker")({
237
+ name: WorkerName,
238
+ kind: Schema.Literal("cloudflare"),
239
+ maxConcurrentAttempts: MaxConcurrentAttempts,
240
+ workerUrl: HttpsUrl,
241
+ accessClientIdEnv: EnvironmentVariableName,
242
+ accessClientSecretEnv: EnvironmentVariableName,
243
+ image: CloudflareImageName,
244
+ instanceType: CloudflareInstanceType.pipe(Schema.withDecodingDefaultKey(Effect.succeed("standard-4"))),
245
+ llmProviders: Schema.Array(CloudflareLlmProviderKey.pipe(Schema.encodeKeys({ apiKeyEnv: "api_key_env" })))
246
+ .check(uniqueProviders)
247
+ .pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
88
248
  }) {
89
249
  }
90
250
  /** A configured Worker; `kind` selects the adapter. */
91
- export const Worker = Schema.Union([LocalWorker, ExeDevWorker, SshWorker]);
251
+ export const Worker = Schema.Union([LocalWorker, ExeDevWorker, SshWorker, CloudflareWorker]);
92
252
  export class Settings extends Schema.Class("@usine/config/Settings")({
93
253
  /** The interval between GitHub polling cycles, in seconds. */
94
254
  pollInterval: PositiveInt.pipe(Schema.withDecodingDefaultKey(Effect.succeed(60))),
@@ -110,6 +270,22 @@ export const Webhooks = Schema.Union([
110
270
  Schema.Struct({ mode: Schema.Literal("deliveries") }),
111
271
  Schema.Struct({ mode: Schema.Literal("endpoint"), publicUrl: Schema.URLFromString }).pipe(Schema.encodeKeys({ publicUrl: "public_url" })),
112
272
  ]);
273
+ const OtlpUrl = Schema.URLFromString.check(Schema.makeFilter((url) => url.protocol === "http:" || url.protocol === "https:", {
274
+ message: "Expected an http or https URL",
275
+ }), Schema.makeFilter((url) => url.username === "" && url.password === "" && url.search === "", {
276
+ message: "Expected a URL without a username, password, or query string; authenticate in a collector next to usine up",
277
+ }));
278
+ /** Span export over OTLP/HTTP (ADR 0028). */
279
+ export class Tracing extends Schema.Class("@usine/config/Tracing")({
280
+ /**
281
+ * The collector's OTLP/HTTP traces endpoint, used as given, such as
282
+ * `http://localhost:4318/v1/traces`. It has no credentials or query string.
283
+ */
284
+ otlpUrl: OtlpUrl,
285
+ /** The `service.name` resource attribute of every exported span. */
286
+ serviceName: nonBlankString("Expected a non-blank service name").pipe(Schema.withDecodingDefaultKey(Effect.succeed("usine"))),
287
+ }) {
288
+ }
113
289
  const SettingsFromYaml = Settings.pipe(Schema.encodeKeys({
114
290
  pollInterval: "poll_interval",
115
291
  maxChildren: "max_children",
@@ -124,6 +300,14 @@ const WorkerFromYaml = Schema.Union([
124
300
  SshWorker.pipe(Schema.encodeKeys({
125
301
  maxConcurrentAttempts: "max_concurrent_attempts",
126
302
  identityFile: "identity_file",
303
+ })).check(Schema.makeFilter((worker) => sshMachineConflict(worker) ?? true)),
304
+ CloudflareWorker.pipe(Schema.encodeKeys({
305
+ maxConcurrentAttempts: "max_concurrent_attempts",
306
+ workerUrl: "worker_url",
307
+ accessClientIdEnv: "access_client_id_env",
308
+ accessClientSecretEnv: "access_client_secret_env",
309
+ instanceType: "instance_type",
310
+ llmProviders: "llm_providers",
127
311
  })),
128
312
  ]);
129
313
  const ManagedRepos = Schema.Array(ManagedRepo).check(uniqueRepositoryNames((repo) => repo.name));
@@ -137,6 +321,7 @@ export class UsineConfig extends Schema.Class("@usine/config/UsineConfig")({
137
321
  workers: Workers.pipe(Schema.withDecodingDefaultKey(Effect.succeed([{ name: "local", kind: "local" }]))),
138
322
  webhooks: Webhooks.pipe(Schema.withDecodingDefaultKey(Effect.succeed({ mode: "off" }))),
139
323
  operator: Schema.OptionFromOptionalKey(OperatorLogin),
324
+ tracing: Schema.OptionFromOptionalKey(Tracing.pipe(Schema.encodeKeys({ otlpUrl: "otlp_url", serviceName: "service_name" }))),
140
325
  }) {
141
326
  }
142
327
  //# sourceMappingURL=factory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,OAAO,EACP,UAAU,EACV,UAAU,GACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D,kDAAkD;AAClD,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC,mCAAmC,CAAC,CAAC,IAAI,CACjF,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAC5B,CAAC;AAIF,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvE,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CACnC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,EAC1E,EAAE,OAAO,EAAE,uBAAuB,EAAE,CACrC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,MAAkB,EAAU,EAAE,CACnD,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,KAAK,EAAE,CAAC;AAE5F,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CACzC,CAAC,KAAK,EAAE,EAAE;IACR,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACxE,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;AAC5C,CAAC,EACD,EAAE,OAAO,EAAE,4CAA4C,EAAE,CAC1D,CAAC;AAEF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;AAEvE,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CACxC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,EAC9F,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAClD,CAAC;AAEF,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAE3E,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAc,2BAA2B,CAAC,CAAC;IACtF,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;SAC5B,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;SACxB,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;CACrE,CAAC;CAAG;AAEL,MAAM,qBAAqB,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjG,iEAAiE;AACjE,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAc,2BAA2B,CAAC,CAAC;IACtF,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;IAC7B,qBAAqB,EAAE,qBAAqB;CAC7C,CAAC;CAAG;AAEL,qDAAqD;AACrD,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,KAAK,CAAe,4BAA4B,CAAC,CAAC;IACzF,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;IAC/B,qBAAqB,EAAE,qBAAqB;CAC7C,CAAC;CAAG;AAEL,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACjD,MAAM,CAAC,SAAS,CAAC,2BAA2B,EAAE;IAC5C,OAAO,EAAE,uCAAuC;CACjD,CAAC,CACH,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,aAAc,SAAQ,MAAM,CAAC,KAAK,CAAgB,6BAA6B,CAAC,CAAC;IAC5F,MAAM,EAAE,aAAa;IACrB,WAAW,EAAE,cAAc;IAC3B,SAAS,EAAE,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACrF,aAAa,EAAE,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC;SAC3C,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;SACxB,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;CAC3D,CAAC;CAAG;AAEL;;;;GAIG;AACH,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,KAAK,CAAY,yBAAyB,CAAC,CAAC;IAChF,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,qBAAqB,EAAE,qBAAqB;IAC5C,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,MAAM,CAAC,qBAAqB,CAAC,eAAe,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC,qBAAqB,CAAC,OAAO,CAAC;IAC3C,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,MAAM,CAAC,qBAAqB,CACnC,aAAa,CAAC,IAAI,CAChB,MAAM,CAAC,UAAU,CAAC;QAChB,SAAS,EAAE,YAAY;QACvB,aAAa,EAAE,iBAAiB;QAChC,YAAY,EAAE,eAAe;KAC9B,CAAC,CACH,CACF;CACF,CAAC;CAAG;AAEL,uDAAuD;AACvD,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAG3E,MAAM,OAAO,QAAS,SAAQ,MAAM,CAAC,KAAK,CAAW,wBAAwB,CAAC,CAAC;IAC7E,8DAA8D;IAC9D,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACjF,oFAAoF;IACpF,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,4EAA4E;IAC5E,iBAAiB,EAAE,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC;IAC5D,gGAAgG;IAChG,gBAAgB,EAAE,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC;IAC3D,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC,qBAAqB,CAAC,OAAO,CAAC;IAClD,iGAAiG;IACjG,YAAY,EAAE,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC;CACnD,CAAC;CAAG;AAEL,uGAAuG;AACvG,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;IACnC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9C,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;IACrD,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CACvF,MAAM,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAC/C;CACF,CAAC,CAAC;AAIH,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CACpC,MAAM,CAAC,UAAU,CAAC;IAChB,YAAY,EAAE,eAAe;IAC7B,WAAW,EAAE,cAAc;IAC3B,iBAAiB,EAAE,qBAAqB;IACxC,gBAAgB,EAAE,oBAAoB;IACtC,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,eAAe;CAC9B,CAAC,CACH,CAAC;AAEF,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;IAClC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACzF,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,CAAC,CAAC;IAC1F,SAAS,CAAC,IAAI,CACZ,MAAM,CAAC,UAAU,CAAC;QAChB,qBAAqB,EAAE,yBAAyB;QAChD,YAAY,EAAE,eAAe;KAC9B,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,CAClD,qBAAqB,CAAC,CAAC,IAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CACxD,CAAC;AAEF,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,CAAC;AAErF,gCAAgC;AAChC,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAc,2BAA2B,CAAC,CAAC;IACtF,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,OAAO,EAAE,OAAO,CAAC,IAAI,CACnB,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAClF;IACD,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACvF,QAAQ,EAAE,MAAM,CAAC,qBAAqB,CAAC,aAAa,CAAC;CACtD,CAAC;CAAG"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}