@byollm/server 0.1.0-alpha.5 → 0.1.0-alpha.51

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.
@@ -19,10 +19,22 @@ interface WaitOptions {
19
19
  readonly timeoutMs?: number;
20
20
  /**
21
21
  * Called instead of throwing when no runner can take the job. Return a
22
- * substitute result (a hosted-model answer, say) and the wait resolves with
23
- * it; return nothing and {@link NoRunnerAvailableError} is thrown.
22
+ * substitute and the wait resolves with it; return nothing and
23
+ * {@link NoRunnerAvailableError} is thrown.
24
+ *
25
+ * **A string is enough.** It is the app's own fallback answer — a hosted
26
+ * model's text, a cached reply — not wire data, and requiring a whole
27
+ * `DeliveredResult` for it was ceremony that invited invented shapes. The
28
+ * README's own example got it wrong, which is how this was found.
29
+ *
30
+ * **Whatever comes back is labelled `fallback: true` by the wait, not by
31
+ * the caller** — {@link MUSTS.FALLBACK_LABELED}. Work that did not come
32
+ * from the user's own compute must not be reportable as though it did, and
33
+ * that stays true whether an app returns a bare string or a full record it
34
+ * assembled itself. The stamp is applied after this function returns, so
35
+ * there is no shape an app can hand back that hides what it is.
24
36
  */
25
- readonly onNoRunner?: (reason: string) => DeliveredResult | undefined | Promise<DeliveredResult | undefined>;
37
+ readonly onNoRunner?: (reason: string) => string | DeliveredResult | undefined | Promise<string | DeliveredResult | undefined>;
26
38
  /** Abort the wait. */
27
39
  readonly signal?: AbortSignal;
28
40
  }
@@ -1,5 +1,5 @@
1
1
  import { StoredKeys, Endpoint } from '@byollm/protocol';
2
- import { B as ByollmStore } from './store-Cj5b6A9j.js';
2
+ import { B as ByollmStore } from './store-DoUlJWaO.js';
3
3
 
4
4
  /** Everything a mount needs to serve the protocol. */
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { StoredKeys, JobKind, DeliveredResult, Endpoint, Capability } from '@byollm/protocol';
2
- import { P as PollingDeliveryDeps, R as ResultDelivery, W as WaitOptions } from './delivery-36nIe-b3.js';
3
- export { N as NoRunnerAvailableError, a as PollingDelivery, b as ResultTimeoutError } from './delivery-36nIe-b3.js';
4
- import { B as ByollmStore, J as JobRecord, E as EnqueueInput, R as RunnerRecord, S as StoredJobInput, C as ClaimArgs, a as RenewArgs, b as RenewResult, A as AdoptArgs, c as CompleteArgs, d as CompleteResult, e as ReleaseArgs, P as PairingRecord, f as ApproveArgs, T as TouchArgs } from './store-Cj5b6A9j.js';
5
- export { g as CompleteHolder, h as JobStore, i as RunnerStore } from './store-Cj5b6A9j.js';
6
- import { H as HandlerConfig } from './handlers-DgW0QNTf.js';
7
- export { B as ByollmHandlers, a as HandlerResult, S as SERVED_PROTOCOL_VERSION } from './handlers-DgW0QNTf.js';
2
+ import { P as PollingDeliveryDeps, R as ResultDelivery, W as WaitOptions } from './delivery-C6VzgMgH.js';
3
+ export { N as NoRunnerAvailableError, a as PollingDelivery, b as ResultTimeoutError } from './delivery-C6VzgMgH.js';
4
+ import { B as ByollmStore, J as JobRecord, E as EnqueueInput, R as RunnerRecord, S as StoredJobInput, C as ClaimArgs, a as RenewArgs, b as RenewResult, A as AdoptArgs, c as CompleteArgs, d as CompleteResult, e as ReleaseArgs, P as PairingRecord, f as ApproveArgs, T as TouchArgs } from './store-DoUlJWaO.js';
5
+ export { g as CompleteHolder, h as JobStore, i as RunnerStore } from './store-DoUlJWaO.js';
6
+ import { H as HandlerConfig } from './handlers-D1ni1D8r.js';
7
+ export { B as ByollmHandlers, a as HandlerResult, S as SERVED_PROTOCOL_VERSION } from './handlers-D1ni1D8r.js';
8
8
 
9
9
  /**
10
10
  * The cloud lane — cloud_004 §9.4.
@@ -49,6 +49,19 @@ interface CloudLaneOptions {
49
49
  readonly fetch?: typeof fetch;
50
50
  }
51
51
  /** What one pump cycle did, for logging and for tests. */
52
+ /**
53
+ * A relay that could not answer this request — alpha.31.
54
+ *
55
+ * `retryable` is the whole point: a draining pod and a bad signature are both
56
+ * failures, and treating them alike is how a site either falls over on every
57
+ * deploy or stays silently disconnected for a week.
58
+ */
59
+ declare class RelayUnavailable extends Error {
60
+ readonly retryable: boolean;
61
+ /** The protocol's own code, when the relay sent one. */
62
+ readonly code: string;
63
+ constructor(message: string, retryable: boolean, code: string);
64
+ }
52
65
  interface PumpReport {
53
66
  /** Jobs sealed to a claiming device this cycle. */
54
67
  readonly sealed: string[];
@@ -62,6 +75,20 @@ interface PumpReport {
62
75
  * exactly the case `awaiting-payload` exists to bound.
63
76
  */
64
77
  readonly refused: string[];
78
+ /**
79
+ * Why this cycle stopped early, when it did — alpha.31.
80
+ *
81
+ * A relay can legitimately say "ask me later": a pod draining through its
82
+ * `preStop` window answers `503 not-ready` to every routed call, and that
83
+ * happens on **every deploy**. Before this existed the lane read the body
84
+ * of that answer, found no `jobs` in it, and threw `TypeError: finished.jobs
85
+ * is not iterable` — a site falling over because its relay was polite.
86
+ *
87
+ * Absent on an ordinary cycle. Present, with the reason, when the lane
88
+ * deferred: a site that quietly did nothing and a site that was told to wait
89
+ * must not look the same in a log.
90
+ */
91
+ readonly deferred?: string;
65
92
  }
66
93
  declare class CloudLane {
67
94
  #private;
@@ -79,6 +106,19 @@ declare class CloudLane {
79
106
  * field on `JobStub` to put one in.
80
107
  */
81
108
  publish(record: JobRecord): Promise<void>;
109
+ /**
110
+ * Withdraw a job at the relay — cloud_008 §2.2.
111
+ *
112
+ * `app.cancel()` marks the site's own row terminal, which stops the *next*
113
+ * seal. It cannot stop a device that is already running the work, because
114
+ * on this lane the site is not the upstream: only the relay talks to the
115
+ * daemon, and it answered `cancel: []` unconditionally.
116
+ *
117
+ * So the cancellation has to travel. The relay marks the job, stops
118
+ * offering it, and names it to the holding device at its next heartbeat —
119
+ * the same path the direct plane has always had, arriving one hop later.
120
+ */
121
+ cancel(jobId: string): Promise<void>;
82
122
  /**
83
123
  * One cycle: seal for anything claimed, collect anything finished.
84
124
  *
@@ -91,7 +131,45 @@ declare class CloudLane {
91
131
  }
92
132
 
93
133
  /** Why a job cannot presently run. */
94
- type NoRunnerReason = "no-runner-paired" | "no-runner-online" | "no-matching-capability" | "audience-admits-nobody";
134
+ type NoRunnerReason = "no-runner-paired" | "no-runner-online" | "no-matching-capability" | "audience-admits-nobody"
135
+ /**
136
+ * A named service cannot serve this requester — byollm_016 Phase B.
137
+ *
138
+ * **One reason for two causes, and the collapse is the point.** The name may
139
+ * be one nobody advertises, or one advertised and not offered to this
140
+ * person. Those are different facts and a requester may learn neither,
141
+ * because telling them apart turns the advisory into an inventory oracle:
142
+ * try names, sort the answers, enumerate a device you were never offered.
143
+ *
144
+ * My first version split them, on the argument that this answers a site
145
+ * about its own users' devices. That argument does not survive a team job.
146
+ * The site holds capabilities for devices belonging to *other people* on the
147
+ * roster, and it is free to relay a reason to the requester who asked — so
148
+ * the split leaks through a side door rather than the front one, which is
149
+ * how the collapse in `RefusalReason` gets defeated by a helpful SDK.
150
+ *
151
+ * The finer cause stays owner-side, where `byollm services` reports it to
152
+ * the person who already knows what their machine runs.
153
+ */
154
+ | "selection-unavailable"
155
+ /**
156
+ * A kind two services answer with no default chosen, so the daemon
157
+ * withholds it — byollm_016. Nothing is wrong with the device; its owner has
158
+ * a decision to make, and saying "no matching capability" would send them
159
+ * looking for a missing install instead.
160
+ */
161
+ | "awaiting-default"
162
+ /**
163
+ * The owner's default for this kind can never serve *this* requester —
164
+ * byollm_016's defaults-meet-audiences corner.
165
+ *
166
+ * The specimen: a default of `claude-cli`, self-locked by
167
+ * `SUBSCRIPTION_SELF_LOCK`, and a team member's unselected job. It resolves
168
+ * to something that will never run it. Reported rather than left to time
169
+ * out, because a wait that can never end is indistinguishable from one that
170
+ * has not ended yet, and only one of them is worth waiting through.
171
+ */
172
+ | "default-unusable";
95
173
  /**
96
174
  * The no-runner signal (byollm_001 Rev 1 §D).
97
175
  *
@@ -110,7 +188,9 @@ interface RunnerAvailability {
110
188
  interface AvailabilityQuery {
111
189
  readonly kind: JobKind;
112
190
  readonly owner: string;
113
- readonly audience?: "self" | "named" | "public";
191
+ /** The service the job named, if it named one — byollm_016 Phase B. */
192
+ readonly service?: string;
193
+ readonly audience?: "private" | "team" | "public";
114
194
  readonly audienceAllow?: readonly string[];
115
195
  }
116
196
  interface ByollmAppOptions {
@@ -163,14 +243,6 @@ interface JobHandle {
163
243
  /** Ask the runner to stop. */
164
244
  cancel(): Promise<void>;
165
245
  }
166
- /**
167
- * The app-facing half of `@byollm/server`.
168
- *
169
- * The daemon talks to {@link ByollmHandlers}; the app talks to this. Keeping
170
- * them separate is what makes "one door per state write" hold — an app
171
- * enqueues and cancels through these methods and never writes job rows by
172
- * hand.
173
- */
174
246
  declare class ByollmApp {
175
247
  #private;
176
248
  /** Present only in the cloud lane; the site's side of the relay. */
@@ -192,7 +264,7 @@ declare class ByollmApp {
192
264
  * Check `provenance.untrusted` before rendering. It is true for every
193
265
  * `named`/`public` job, because that text came from someone else's machine
194
266
  * and the app must not present it as its own AI's answer
195
- * ({@link MUSTS.RESULT_PROVENANCE}).
267
+ * ({@link MUSTS.PROVENANCE_NAMES_DEVICE}).
196
268
  */
197
269
  result(jobId: string): Promise<DeliveredResult | null>;
198
270
  /** Ask a runner to stop. Queued jobs cancel at once; held jobs at the next heartbeat. */
@@ -315,8 +387,6 @@ declare function formatSiteKeys(keys: StoredKeys): string;
315
387
 
316
388
  /** A device code: the secret the daemon polls with. Never shown to a user. */
317
389
  declare function generateDeviceCode(): string;
318
- /** A runner bearer token. */
319
- declare function generateRunnerToken(): string;
320
390
  /** A runner id. */
321
391
  declare function generateRunnerId(): string;
322
392
  /** A job id. */
@@ -366,14 +436,16 @@ declare class MemoryStore implements ByollmStore {
366
436
  expireDue(now: number): Promise<JobRecord[]>;
367
437
  cancel(jobId: string, now: number): Promise<JobRecord | null>;
368
438
  listClaimedBy(runnerId: string): Promise<JobRecord[]>;
369
- listCancelRequests(runnerId: string): Promise<string[]>;
439
+ listCancelRequests(runnerId: string): Promise<{
440
+ jobId: string;
441
+ leaseId: string;
442
+ }[]>;
370
443
  createPairing(record: PairingRecord): Promise<void>;
371
444
  getPairingByDeviceCodeHash(hash: string): Promise<PairingRecord | null>;
372
445
  getPairingByUserCode(userCode: string): Promise<PairingRecord | null>;
373
446
  approvePairing(args: ApproveArgs): Promise<RunnerRecord>;
374
447
  denyPairing(userCode: string, _now: number): Promise<void>;
375
448
  consumePairingToken(deviceCodeHash: string): Promise<void>;
376
- getRunnerByTokenHash(hash: string): Promise<RunnerRecord | null>;
377
449
  getRunner(runnerId: string): Promise<RunnerRecord | null>;
378
450
  touchRunner(args: TouchArgs): Promise<RunnerRecord | null>;
379
451
  revokeRunner(runnerId: string, now: number): Promise<void>;
@@ -384,4 +456,4 @@ declare class MemoryStore implements ByollmStore {
384
456
  /** The capability that would serve a kind, if any. */
385
457
  declare function capabilityFor(capabilities: readonly Capability[], kind: string): Capability | undefined;
386
458
 
387
- export { AdoptArgs, ApproveArgs, type AvailabilityQuery, ByollmApp, type ByollmAppOptions, ByollmStore, ClaimArgs, CloudLane, type CloudLaneOptions, CompleteArgs, CompleteResult, EnqueueInput, HandlerConfig, type JobHandle, JobRecord, MemoryStore, type MemoryStoreOptions, type NoRunnerReason, PairingRecord, PollingDeliveryDeps, type PumpReport, ReleaseArgs, RenewArgs, RenewResult, ResultDelivery, type RunnerAvailability, RunnerRecord, TouchArgs, WaitOptions, capabilityFor, createFetchHandler, formatSiteKeys, generateDeviceCode, generateJobId, generateRunnerId, generateRunnerToken, generateSiteKeys, generateUserCode, hashSecret, normalizeUserCode, routeEndpoint, secretsMatch, signatureFrom, siteKeysFromEnv };
459
+ export { AdoptArgs, ApproveArgs, type AvailabilityQuery, ByollmApp, type ByollmAppOptions, ByollmStore, ClaimArgs, CloudLane, type CloudLaneOptions, CompleteArgs, CompleteResult, EnqueueInput, HandlerConfig, type JobHandle, JobRecord, MemoryStore, type MemoryStoreOptions, type NoRunnerReason, PairingRecord, PollingDeliveryDeps, type PumpReport, RelayUnavailable, ReleaseArgs, RenewArgs, RenewResult, ResultDelivery, type RunnerAvailability, RunnerRecord, TouchArgs, WaitOptions, capabilityFor, createFetchHandler, formatSiteKeys, generateDeviceCode, generateJobId, generateRunnerId, generateSiteKeys, generateUserCode, hashSecret, normalizeUserCode, routeEndpoint, secretsMatch, signatureFrom, siteKeysFromEnv };