@byok-sdk/core 0.31.0 → 0.33.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/dist/board.d.ts +2 -0
- package/dist/errors.d.ts +1 -0
- package/dist/in-memory/archive-access.d.ts +25 -0
- package/dist/in-memory/board.d.ts +1 -0
- package/dist/in-memory/mailbox.d.ts +8 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/mailbox.d.ts +83 -12
- package/dist/presence.d.ts +22 -0
- package/dist/sealed-payload/index.js.map +1 -1
- package/dist/sealed-payload/scope-key.d.ts +0 -2
- package/dist/store-compatibility.d.ts +37 -0
- package/package.json +2 -2
package/dist/mailbox.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type { CollectExpiredInput, CollectExpiredResult } from './retention';
|
|
|
15
15
|
* `@byok-sdk/protocol`, and core must not grow an edge to it (§12.1 invariant).
|
|
16
16
|
*/
|
|
17
17
|
import type { ContentHash } from './blob';
|
|
18
|
+
import { ByokCoreError } from './errors';
|
|
18
19
|
import type { TenantId } from './tenant';
|
|
19
20
|
/**
|
|
20
21
|
* Row lifecycle. `pending` and `acked` are derived from the device cursor;
|
|
@@ -46,9 +47,12 @@ export interface MailboxBody {
|
|
|
46
47
|
* How an append is admitted against the tenant's `mailboxLimitBytes`.
|
|
47
48
|
*
|
|
48
49
|
* Mailbox bytes have one authority: the retained rows. Usage is the tenant's
|
|
49
|
-
* `SUM(byteSize)` over
|
|
50
|
-
*
|
|
51
|
-
*
|
|
50
|
+
* `SUM(byteSize)` over its `pending` rows, and the limit is checked in the same
|
|
51
|
+
* serialized unit that inserts the row — there is no counter for a writer to
|
|
52
|
+
* forget, so acking, dead-lettering or deleting a row needs no accounting.
|
|
53
|
+
* `acked` and `expired` rows stay retained for retention and §12.7.5
|
|
54
|
+
* visibility but hold no quota, so undelivered-and-lost work can never wedge
|
|
55
|
+
* a tenant at its limit.
|
|
52
56
|
*
|
|
53
57
|
* - `limited`: refused with `storage_quota_exceeded` when `used + byteSize`
|
|
54
58
|
* exceeds the limit, and with `storage_entitlement_missing` when the tenant
|
|
@@ -76,13 +80,14 @@ export interface MailboxAppendInput {
|
|
|
76
80
|
readonly materialize: (seq: number) => MailboxBody | Promise<MailboxBody>;
|
|
77
81
|
/**
|
|
78
82
|
* Limit admission for a NEW row. An existing `messageId` returns its row
|
|
79
|
-
* before any check, so a retry is never refused for capacity.
|
|
83
|
+
* before any capacity check, so a retry is never refused for capacity. A
|
|
84
|
+
* closed stream refuses before even that (see {@link MailboxStore.closeStream}).
|
|
80
85
|
*/
|
|
81
86
|
readonly admission: MailboxAdmission;
|
|
82
87
|
}
|
|
83
88
|
/** Tenant mailbox usage, derived from the retained rows on every read. */
|
|
84
89
|
export interface MailboxUsage {
|
|
85
|
-
/** `SUM(byteSize)` over
|
|
90
|
+
/** `SUM(byteSize)` over the retained `pending` rows. */
|
|
86
91
|
readonly bytes: bigint;
|
|
87
92
|
}
|
|
88
93
|
export interface MailboxReadQuery {
|
|
@@ -113,8 +118,9 @@ export interface MailboxPage {
|
|
|
113
118
|
* whole point of the field.
|
|
114
119
|
*
|
|
115
120
|
* `1` for a mailbox that has lost nothing, so a fresh device's cursor `0` is
|
|
116
|
-
* always inside the window. Monotonic
|
|
117
|
-
*
|
|
121
|
+
* always inside the window. Monotonic: `collectExpired` reaps old dead
|
|
122
|
+
* letters but always keeps each device's highest-seq one, which is the
|
|
123
|
+
* evidence this floor is read from.
|
|
118
124
|
*
|
|
119
125
|
* This is a READ of the retained window, never a second retention authority:
|
|
120
126
|
* `collectExpired` decides what is retained, this reports what it cost.
|
|
@@ -144,7 +150,7 @@ export interface MailboxCursorState {
|
|
|
144
150
|
/**
|
|
145
151
|
* Retention cutoffs.
|
|
146
152
|
*
|
|
147
|
-
*
|
|
153
|
+
* All three instants must be **canonical ISO-8601 UTC** (`YYYY-MM-DDTHH:mm:ss.sssZ`);
|
|
148
154
|
* anything else is rejected with `timestamp_not_canonical`. A retention sweep
|
|
149
155
|
* deletes rows, so an offset-bearing string that a string comparison and a SQL
|
|
150
156
|
* `timestamptz` comparison read differently is the worst place to guess — see
|
|
@@ -153,8 +159,41 @@ export interface MailboxCursorState {
|
|
|
153
159
|
export interface MailboxCollectExpiredInput extends CollectExpiredInput {
|
|
154
160
|
/** Acked rows appended before this instant are deleted. */
|
|
155
161
|
readonly ackedBefore: string;
|
|
156
|
-
/** Unacked rows appended before this instant move to `expired
|
|
162
|
+
/** Unacked rows appended before this instant move to `expired`. */
|
|
157
163
|
readonly expireUnackedBefore: string;
|
|
164
|
+
/**
|
|
165
|
+
* Dead letters (`expired` rows) appended before this instant are deleted,
|
|
166
|
+
* except each device's highest-seq dead letter: that row is the evidence for
|
|
167
|
+
* `recoverableFrom`, so a reap never moves the floor. Only rows that were
|
|
168
|
+
* already `expired` when the call started are eligible; a row this call
|
|
169
|
+
* expires waits for the next call. Reaped rows count in `removed`.
|
|
170
|
+
*/
|
|
171
|
+
readonly reapDeadLettersBefore: string;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Which of one device's `pending` rows {@link MailboxStore.expirePending}
|
|
175
|
+
* dead-letters. A listed seq that is not `pending` (acked, already expired, or
|
|
176
|
+
* never written) is skipped.
|
|
177
|
+
*/
|
|
178
|
+
export interface MailboxExpirePendingInput {
|
|
179
|
+
readonly deviceId: string;
|
|
180
|
+
readonly seqs: readonly number[];
|
|
181
|
+
}
|
|
182
|
+
/** Why a device's stream was closed: the device it addressed was retired. */
|
|
183
|
+
export declare const MAILBOX_STREAM_CLOSE_CAUSES: readonly ['device_revoked', 'device_superseded'];
|
|
184
|
+
export type MailboxStreamCloseCause = (typeof MAILBOX_STREAM_CLOSE_CAUSES)[number];
|
|
185
|
+
/** An append refused because its device's stream was closed when the device was retired. */
|
|
186
|
+
export declare class MailboxStreamClosedError extends ByokCoreError {
|
|
187
|
+
readonly deviceId: string;
|
|
188
|
+
readonly closeCause: MailboxStreamCloseCause;
|
|
189
|
+
constructor(deviceId: string, closeCause: MailboxStreamCloseCause, options?: ErrorOptions);
|
|
190
|
+
}
|
|
191
|
+
export interface MailboxCloseStreamInput {
|
|
192
|
+
readonly deviceId: string;
|
|
193
|
+
readonly cause: MailboxStreamCloseCause;
|
|
194
|
+
}
|
|
195
|
+
export interface MailboxReopenStreamInput {
|
|
196
|
+
readonly deviceId: string;
|
|
158
197
|
}
|
|
159
198
|
/**
|
|
160
199
|
* Mailbox port. Tenant-first, async.
|
|
@@ -165,11 +204,13 @@ export interface MailboxCollectExpiredInput extends CollectExpiredInput {
|
|
|
165
204
|
* server has returned to that device),
|
|
166
205
|
* `timestamp_not_canonical` (a retention cutoff that is not a canonical
|
|
167
206
|
* ISO-8601 UTC instant), `storage_quota_exceeded` and
|
|
168
|
-
* `storage_entitlement_missing` (a `limited` append refused at admission)
|
|
207
|
+
* `storage_entitlement_missing` (a `limited` append refused at admission), and
|
|
208
|
+
* `mailbox_stream_closed` ({@link MailboxStreamClosedError}, any append to a
|
|
209
|
+
* closed stream).
|
|
169
210
|
*/
|
|
170
211
|
export interface MailboxStore {
|
|
171
212
|
append(tenant: TenantId, input: MailboxAppendInput): Promise<MailboxMessage>;
|
|
172
|
-
/** The tenant's mailbox bytes, summed from the retained rows. */
|
|
213
|
+
/** The tenant's mailbox bytes, summed from the retained `pending` rows. */
|
|
173
214
|
readUsage(tenant: TenantId): Promise<MailboxUsage>;
|
|
174
215
|
/** Pure read. Never advances the cursor, never deletes, never marks acked. */
|
|
175
216
|
readAfter(tenant: TenantId, query: MailboxReadQuery): Promise<MailboxPage>;
|
|
@@ -178,6 +219,36 @@ export interface MailboxStore {
|
|
|
178
219
|
/** The one and only ack. Monotonic and bounded by the recorded delivery watermark. */
|
|
179
220
|
advanceCursor(tenant: TenantId, input: MailboxAdvanceCursorInput): Promise<MailboxCursorState>;
|
|
180
221
|
readCursor(tenant: TenantId, deviceId: string): Promise<MailboxCursorState>;
|
|
181
|
-
/** Retention hook: delete acked rows, dead-letter unacked ones. */
|
|
222
|
+
/** Retention hook: delete acked rows, reap old dead letters below the floor, dead-letter unacked ones. */
|
|
182
223
|
collectExpired(tenant: TenantId, input: MailboxCollectExpiredInput): Promise<CollectExpiredResult>;
|
|
224
|
+
/**
|
|
225
|
+
* Dead-letters the listed undelivered rows of a task the Host abandoned,
|
|
226
|
+
* without waiting for retention. Only `pending` rows move, and only to
|
|
227
|
+
* `expired`: nothing is deleted, no row returns to `pending`, the cursor is
|
|
228
|
+
* untouched, and the device's `seq` allocator keeps counting. The moved rows
|
|
229
|
+
* stop holding mailbox quota and raise `recoverableFrom` exactly as a
|
|
230
|
+
* retention sweep would. Serialized with the device's appends and acks.
|
|
231
|
+
*/
|
|
232
|
+
expirePending(tenant: TenantId, input: MailboxExpirePendingInput): Promise<{
|
|
233
|
+
readonly expired: number;
|
|
234
|
+
}>;
|
|
235
|
+
/**
|
|
236
|
+
* Closes a retired device's stream and dead-letters every `pending` row on
|
|
237
|
+
* it, as one step serialized with the device's appends: an append ordered
|
|
238
|
+
* before it has its row expired here, and every append ordered after it is
|
|
239
|
+
* refused with `mailbox_stream_closed`, whatever its admission and even for
|
|
240
|
+
* a known `messageId`. The stream need not exist yet; closing creates it
|
|
241
|
+
* closed. Closing a closed stream keeps its first close instant, records the
|
|
242
|
+
* new cause and still expires pending rows. Cursor, `seq` and
|
|
243
|
+
* `recoverableFrom` move exactly as {@link expirePending} moves them.
|
|
244
|
+
*/
|
|
245
|
+
closeStream(tenant: TenantId, input: MailboxCloseStreamInput): Promise<{
|
|
246
|
+
readonly expired: number;
|
|
247
|
+
}>;
|
|
248
|
+
/**
|
|
249
|
+
* Reopens a stream for a device registered again under the same id. Rows,
|
|
250
|
+
* cursor, `seq` and `recoverableFrom` are untouched, so delivery stays
|
|
251
|
+
* monotonic across the close. A no-op on an open or absent stream.
|
|
252
|
+
*/
|
|
253
|
+
reopenStream(tenant: TenantId, input: MailboxReopenStreamInput): Promise<void>;
|
|
183
254
|
}
|
package/dist/presence.d.ts
CHANGED
|
@@ -18,12 +18,34 @@ import type { TenantId } from './tenant';
|
|
|
18
18
|
/** The five presence levels. */
|
|
19
19
|
export declare const PRESENCE_LEVELS: readonly ['online', 'thinking', 'working', 'error', 'offline'];
|
|
20
20
|
export type PresenceLevel = (typeof PRESENCE_LEVELS)[number];
|
|
21
|
+
/**
|
|
22
|
+
* The capability matrix a daemon reported for one runtime: the shape of
|
|
23
|
+
* `@byok-sdk/protocol`'s `RuntimeCapabilities` (#1103). Omitted fields are unknown.
|
|
24
|
+
*/
|
|
25
|
+
export interface PresenceRuntimeCapabilities {
|
|
26
|
+
readonly steer?: boolean;
|
|
27
|
+
readonly resume?: boolean;
|
|
28
|
+
readonly approvalInteractive?: boolean;
|
|
29
|
+
readonly mcpToolsets?: boolean;
|
|
30
|
+
readonly messageDraft?: boolean;
|
|
31
|
+
readonly toolAuthorizationAuto?: boolean;
|
|
32
|
+
readonly durablePi?: boolean;
|
|
33
|
+
readonly preparedLane?: boolean;
|
|
34
|
+
readonly isolation?: {
|
|
35
|
+
readonly userContext?: boolean;
|
|
36
|
+
readonly userMcpServers?: boolean;
|
|
37
|
+
readonly sessionPersistence?: boolean;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
21
40
|
/** Runtime facts observed by a daemon's real local probe. Omitted fields are unknown. */
|
|
22
41
|
export interface PresenceRuntimeFact {
|
|
23
42
|
readonly id: string;
|
|
24
43
|
readonly version?: string;
|
|
25
44
|
readonly authPresent?: boolean;
|
|
45
|
+
readonly capabilities?: PresenceRuntimeCapabilities;
|
|
26
46
|
}
|
|
47
|
+
/** A frozen copy of one runtime fact holding only the known fields; every presence store returns this. */
|
|
48
|
+
export declare function freezePresenceRuntimeFact(runtime: PresenceRuntimeFact): PresenceRuntimeFact;
|
|
27
49
|
/** Unexpired presence facts nested in the tenant aggregate. */
|
|
28
50
|
export interface TenantReadinessPresence {
|
|
29
51
|
readonly level: PresenceLevel;
|