@byok-sdk/client 0.4.0 → 0.4.2

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.
@@ -159,25 +159,24 @@ export declare class ConnectionManager {
159
159
  */
160
160
  private cancelPendingDrainRetry;
161
161
  /**
162
- * The capabilities the CURRENTLY connected server advertised in its
163
- * `conn.ack` — untyped `string[]` (forward-compat: a server may advertise
164
- * a flag this build doesn't recognize yet), populated by {@link onAcked}
165
- * and read by {@link getServerCapabilities}. Empty until the very first
166
- * successful handshake.
162
+ * The capabilities the CURRENT transport's server advertised untyped
163
+ * `string[]` for forward compatibility. WS populates it from `conn.ack`;
164
+ * long-poll populates it from each successful events response. Empty until
165
+ * the active transport supplies an advertisement.
167
166
  *
168
167
  * Finding R2 (cross-model re-review — was P1): strictly PER-CONNECTION,
169
168
  * not per-daemon-lifetime. Cleared to `[]` the instant the acked WS
170
169
  * connection ends for ANY reason — an ordinary disconnect (`onWsOutcome`'s
171
170
  * `acked` branch), `stop()`, or a transport switch to long-poll
172
- * (`enterLongPoll`) — and only ever repopulated by a FRESH `conn.ack`.
171
+ * (`enterLongPoll`) — and only repopulated by a fresh advertisement from
172
+ * the transport that is still current.
173
173
  * The previous version of this doc comment claimed long-poll mode simply
174
174
  * "stays at whatever the last real WS `conn.ack` said" — that was the bug:
175
175
  * a daemon that once learned e.g. `approval_resolved` from an earlier WS
176
176
  * session kept believing it applied to whatever it's connected to NOW,
177
177
  * even after a disconnect/degrade where nothing has actually confirmed
178
178
  * that's still true (a reconnect could land on a DIFFERENT server behind a
179
- * load balancer; long-poll fallback itself never performs an equivalent
180
- * handshake at all). Concretely, `TaskRunner.sendApprovalResolved` gates
179
+ * load balancer). Concretely, `TaskRunner.sendApprovalResolved` gates
181
180
  * `task.approval_resolved` on this list — sending it to a server that
182
181
  * doesn't actually understand it over the long-poll path would get a
183
182
  * batch-level 400 from `MessagesSendRequestSchema` (protocol §8.2), which
@@ -242,13 +241,10 @@ export declare class ConnectionManager {
242
241
  private drainRetryDelay;
243
242
  isTransportDegraded(): boolean;
244
243
  /**
245
- * The capabilities the CURRENTLY connected server advertised in its
246
- * `conn.ack` e.g. lets a caller gate a daemon->server message on whether
247
- * THIS server understands it before sending (see `task-runner.ts`'s
248
- * `sendApprovalResolved`, gated on `approval_resolved`). Empty before the
249
- * first handshake completes, AND (finding R2) once again empty after any
250
- * disconnect/degrade — see `serverCapabilities`'s own doc comment for why
251
- * this is strictly per-connection rather than "sticky" across one.
244
+ * The capabilities the CURRENT transport's server advertised: from
245
+ * `conn.ack` on WS, or the latest successful `GET /byok/events` response
246
+ * on long-poll. Empty before either transport has supplied its current
247
+ * advertisement, and cleared across disconnect/switch boundaries.
252
248
  */
253
249
  getServerCapabilities(): readonly string[];
254
250
  isConnected(): boolean;
@@ -5,6 +5,12 @@ export interface LongPollClientOptions {
5
5
  auth: AuthManager;
6
6
  getCursor: () => number | undefined;
7
7
  onEnvelope: (envelope: Envelope) => void;
8
+ /**
9
+ * Capabilities advertised by the server that produced the current poll
10
+ * response. Called before any envelopes from that response are delivered.
11
+ * An older responder omitting the additive field is reported as `[]`.
12
+ */
13
+ onServerCapabilities?: (capabilities: string[]) => void;
8
14
  /** Called once the device is found to be revoked (401 surfaced through {@link AuthManager}) — the loop stops itself rather than retrying. */
9
15
  onRevoked?: () => void;
10
16
  /**
@@ -264,9 +264,10 @@ export interface TaskRunnerDeps {
264
264
  */
265
265
  maxTaskOutputBytes?: number;
266
266
  /**
267
- * M4 (additive-minor, `task.approval_resolved`): the negotiated
268
- * `conn.ack.capabilities` of the CURRENTLY (or most recently) connected
269
- * server — read fresh at call time (mirrors `getCursor`/`getToken`'s own
267
+ * M4 (additive-minor, `task.approval_resolved`): the capabilities advertised
268
+ * by the CURRENT transport's server (`conn.ack` on WS, the latest successful
269
+ * events response on long-poll) — read fresh at call time (mirrors
270
+ * `getCursor`/`getToken`'s own
270
271
  * "read fresh, not captured once" convention elsewhere in this codebase),
271
272
  * since the capability is learned asynchronously, after this `TaskRunner`
272
273
  * is already constructed (`create-daemon.ts`'s `start()` builds `deps`
@@ -935,9 +936,9 @@ export declare class TaskRunner {
935
936
  /**
936
937
  * Whether the CURRENTLY connected server advertised `result-document` —
937
938
  * read fresh on every call, never captured, because the answer changes
938
- * across a reconnect (`ConnectionManager.getServerCapabilities` returns
939
- * `[]` from the moment an acked connection closes until a fresh
940
- * `conn.ack` repopulates it). An absent `getServerCapabilities` seam is
939
+ * across a reconnect or transport switch (`ConnectionManager` clears the
940
+ * old advertisement at the boundary, then repopulates it from a fresh WS
941
+ * ack or successful poll response). An absent `getServerCapabilities` seam is
941
942
  * "no capabilities", the fail-closed reading.
942
943
  */
943
944
  private hasResultDocumentCapability;