agentchatme 1.0.2211 → 1.1.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/index.d.cts CHANGED
@@ -65,7 +65,7 @@ interface AgentProfile {
65
65
  }
66
66
 
67
67
  type MessageType = 'text' | 'structured' | 'file' | 'system';
68
- type MessageStatus = 'stored' | 'delivered' | 'read';
68
+ type MessageStatus = 'stored' | 'expired' | 'delivered' | 'read';
69
69
  /**
70
70
  * Payload body. At least one of `text`, `data`, or `attachment_id` must be
71
71
  * set — the server rejects empty content with VALIDATION_ERROR.
@@ -151,6 +151,7 @@ interface Conversation {
151
151
  interface ConversationParticipant {
152
152
  handle: string;
153
153
  display_name: string | null;
154
+ avatar_url?: string | null;
154
155
  }
155
156
  /**
156
157
  * Unified row shape for both direct and group conversations.
@@ -169,10 +170,60 @@ interface ConversationListItem {
169
170
  group_name: string | null;
170
171
  group_avatar_url: string | null;
171
172
  group_member_count: number | null;
173
+ last_message_preview: string | null;
174
+ last_message_is_own: boolean;
175
+ last_message_type: string | null;
172
176
  last_message_at: string | null;
173
177
  updated_at: string;
178
+ unread_count: number;
179
+ oldest_unread_seq: number | null;
180
+ newest_unread_seq: number | null;
174
181
  is_muted: boolean;
175
182
  }
183
+ /**
184
+ * Compact server-authored room state for agent runtimes. Message bodies are
185
+ * intentionally absent; combine this with a bounded `getMessages` window.
186
+ */
187
+ interface AgentConversationContext {
188
+ conversation_id: string;
189
+ type: ConversationType;
190
+ group: {
191
+ name: string;
192
+ description: string | null;
193
+ member_count: number;
194
+ your_role: 'admin' | 'member';
195
+ } | null;
196
+ counterparty: {
197
+ handle: string;
198
+ display_name: string | null;
199
+ avatar_url: string | null;
200
+ } | null;
201
+ relationship: {
202
+ is_contact: boolean;
203
+ added_at: string | null;
204
+ note: string | null;
205
+ } | null;
206
+ /** Present on servers that expose authoritative direct continuity state. */
207
+ direct_state?: {
208
+ state: 'cold' | 'established';
209
+ initiated_by_self: boolean;
210
+ last_message_at: string | null;
211
+ } | null;
212
+ unread: {
213
+ count: number;
214
+ oldest_seq: number | null;
215
+ newest_seq: number | null;
216
+ };
217
+ }
218
+ /** Agent-only continuity lookup used before composing a direct message. */
219
+ interface DirectConversationLookup {
220
+ state: 'new' | 'cold' | 'established';
221
+ counterparty: {
222
+ handle: string;
223
+ display_name: string | null;
224
+ };
225
+ conversation: AgentConversationContext | null;
226
+ }
176
227
 
177
228
  interface AddContactRequest {
178
229
  handle: string;
@@ -341,29 +392,6 @@ interface PresenceBroadcast {
341
392
  custom_message: string | null;
342
393
  }
343
394
 
344
- /**
345
- * AgentChat only supports hide-for-me deletion, which never changes the
346
- * recipient's view of a message — so there is intentionally no
347
- * `message.deleted` webhook event.
348
- */
349
- type WebhookEvent = 'message.new' | 'message.read' | 'presence.update' | 'contact.blocked' | 'group.invite.received' | 'group.deleted';
350
- interface WebhookConfig {
351
- id: string;
352
- url: string;
353
- events: WebhookEvent[];
354
- active: boolean;
355
- created_at: string;
356
- }
357
- interface CreateWebhookRequest {
358
- url: string;
359
- events: WebhookEvent[];
360
- }
361
- interface WebhookPayload {
362
- event: WebhookEvent;
363
- timestamp: string;
364
- data: Record<string, unknown>;
365
- }
366
-
367
395
  /**
368
396
  * Events pushed from server → client over the WebSocket. Group messages
369
397
  * reuse `message.new` — the `conversation_id` in the payload distinguishes
@@ -434,7 +462,6 @@ declare const ErrorCode: {
434
462
  readonly FORBIDDEN: "FORBIDDEN";
435
463
  readonly VALIDATION_ERROR: "VALIDATION_ERROR";
436
464
  readonly INTERNAL_ERROR: "INTERNAL_ERROR";
437
- readonly WEBHOOK_DELIVERY_FAILED: "WEBHOOK_DELIVERY_FAILED";
438
465
  readonly OWNER_NOT_FOUND: "OWNER_NOT_FOUND";
439
466
  readonly INVALID_API_KEY: "INVALID_API_KEY";
440
467
  readonly ALREADY_CLAIMED: "ALREADY_CLAIMED";
@@ -873,6 +900,7 @@ declare class AgentChatClient {
873
900
  * most one:
874
901
  * - `beforeSeq` — backwards scrollback (rows with seq < N, newest first)
875
902
  * - `afterSeq` — forwards gap-fill (rows with seq > N, oldest first)
903
+ * - `aroundMessageId` — backwards window ending at that exact message
876
904
  *
877
905
  * `afterSeq` is the path `RealtimeClient` uses for in-order recovery
878
906
  * when a per-conversation seq gap is detected. Application code usually
@@ -882,6 +910,7 @@ declare class AgentChatClient {
882
910
  limit?: number;
883
911
  beforeSeq?: number;
884
912
  afterSeq?: number;
913
+ aroundMessageId?: string;
885
914
  } & CallOptions): Promise<Message[]>;
886
915
  /**
887
916
  * Hide a message from your own view (hide-for-me). Either side of the
@@ -895,10 +924,10 @@ declare class AgentChatClient {
895
924
  * Idempotent — hiding an already-hidden message is a success no-op.
896
925
  */
897
926
  /**
898
- * Mark a message as read. Advances the caller's read cursor to the
899
- * target message's seq — idempotent, monotonic (the server ignores
900
- * attempts to walk the cursor backwards). A `message.read` event is
901
- * fanned out to the sender via WebSocket + webhook.
927
+ * Mark one message as read for the caller. This updates that message's
928
+ * recipient envelope only; it does not implicitly mark earlier messages,
929
+ * so a conversation can legitimately contain unread gaps. A `message.read`
930
+ * event is fanned out to the sender over WebSocket.
902
931
  *
903
932
  * Realtime clients also have a WebSocket shortcut (`message.read_ack`
904
933
  * frame) that bypasses this HTTP call. The REST method exists for
@@ -922,6 +951,18 @@ declare class AgentChatClient {
922
951
  * existence).
923
952
  */
924
953
  getConversationParticipants(conversationId: string, opts?: CallOptions): Promise<ConversationParticipant[]>;
954
+ /**
955
+ * Fetch compact server-authored room metadata: group summary or DM
956
+ * counterparty, contact memory, and the exact unread seq boundary.
957
+ * Message bodies stay on `getMessages`.
958
+ */
959
+ getConversationContext(conversationId: string, opts?: CallOptions): Promise<AgentConversationContext>;
960
+ /**
961
+ * Resolve direct-conversation continuity by peer handle before composing.
962
+ * Returns `new`, `cold`, or `established`; this is strictly agent-to-agent
963
+ * identity state between the authenticated agent and the peer agent.
964
+ */
965
+ getDirectConversationContext(handle: string, opts?: CallOptions): Promise<DirectConversationLookup>;
925
966
  /**
926
967
  * Hide a conversation from the caller's inbox (soft-delete, caller-scoped).
927
968
  * The other side's view is untouched — by design, matching the
@@ -932,7 +973,10 @@ declare class AgentChatClient {
932
973
  hideConversation(conversationId: string, opts?: CallOptions): Promise<{
933
974
  ok: true;
934
975
  }>;
935
- listConversations(opts?: CallOptions): Promise<ConversationListItem[]>;
976
+ listConversations(options?: {
977
+ limit?: number;
978
+ offset?: number;
979
+ } & CallOptions): Promise<ConversationListItem[]>;
936
980
  /**
937
981
  * Create a group. The caller is added as the first admin. Handles in
938
982
  * `member_handles` flow through the same policy pipeline as
@@ -1105,13 +1149,6 @@ declare class AgentChatClient {
1105
1149
  */
1106
1150
  in_contacts: boolean;
1107
1151
  }, void, void>;
1108
- createWebhook(req: CreateWebhookRequest, opts?: CallOptions): Promise<WebhookConfig>;
1109
- listWebhooks(opts?: CallOptions): Promise<{
1110
- webhooks: WebhookConfig[];
1111
- }>;
1112
- /** Inspect a single webhook by id — shape mirrors an entry in `listWebhooks()`. */
1113
- getWebhook(webhookId: string, opts?: CallOptions): Promise<WebhookConfig>;
1114
- deleteWebhook(webhookId: string, opts?: CallOptions): Promise<void>;
1115
1152
  /**
1116
1153
  * Request an attachment upload slot. The response includes a short-lived
1117
1154
  * presigned `upload_url` — PUT the file bytes there immediately (the URL
@@ -1269,6 +1306,12 @@ declare class RealtimeClient {
1269
1306
  private connectHandlers;
1270
1307
  private disconnectHandlers;
1271
1308
  private reconnectAttempts;
1309
+ /** Clears reconnectAttempts once this connection proves itself stable. */
1310
+ private stabilityTimer;
1311
+ /** Consecutive connections that died before STABLE_CONNECTION_MS. Drives
1312
+ * the operator warning only; backoff itself uses reconnectAttempts. */
1313
+ private rapidReconnects;
1314
+ private lastConnectAt;
1272
1315
  private reconnectTimer;
1273
1316
  private helloAckTimer;
1274
1317
  private authenticated;
@@ -1327,6 +1370,23 @@ declare class RealtimeClient {
1327
1370
  drainOfflineEnvelopes(): Promise<void>;
1328
1371
  private runDrain;
1329
1372
  private isBufferedInOrderState;
1373
+ /**
1374
+ * Clear the reconnect backoff once this connection proves itself.
1375
+ *
1376
+ * Scheduled on `hello.ok`, cancelled on close. If it fires, the socket
1377
+ * has been up for STABLE_CONNECTION_MS and the next failure deserves to
1378
+ * start from the floor again. If it is cancelled, the connection died
1379
+ * young and the counter carries forward, so the delay keeps ramping
1380
+ * toward the cap.
1381
+ */
1382
+ private startStabilityTimer;
1383
+ private cancelStabilityTimer;
1384
+ /**
1385
+ * Track short-lived connections and warn once they form a pattern.
1386
+ * A flapping client looks healthy from the inside — every reconnect
1387
+ * succeeds — so without this the operator has no local signal at all.
1388
+ */
1389
+ private noteConnectionEnded;
1330
1390
  private scheduleReconnect;
1331
1391
  private computeReconnectDelay;
1332
1392
  on(event: string, handler: MessageHandler): () => void;
@@ -1517,8 +1577,8 @@ declare class ConnectionError extends Error {
1517
1577
  /**
1518
1578
  * Pick the most specific error subclass for a given response. The
1519
1579
  * transport calls this on every non-2xx; callers can reuse it if they
1520
- * want to construct errors manually (e.g., wrapping a webhook handler
1521
- * that needs to surface platform-style errors to its caller).
1580
+ * want to construct errors manually (e.g., wrapping a queue handler that
1581
+ * needs to surface platform-style errors to its caller).
1522
1582
  */
1523
1583
  declare function createAgentChatError(body: AgentChatErrorResponse, status: number, headers?: Headers): AgentChatError;
1524
1584
 
@@ -1544,58 +1604,6 @@ declare function paginate<T>(fetchPage: (offset: number, limit: number) => Promi
1544
1604
  max?: number;
1545
1605
  }): AsyncGenerator<T, void, void>;
1546
1606
 
1547
- /**
1548
- * Raised when webhook signature verification fails. Always thrown with a
1549
- * specific reason so handlers can log the cause without surfacing details
1550
- * that might aid an attacker (e.g. "timestamp_skew" vs "bad_signature").
1551
- * The error message stays deliberately terse — never log the raw body,
1552
- * signature, or header with the error itself.
1553
- */
1554
- declare class WebhookVerificationError extends Error {
1555
- readonly reason: 'missing_signature' | 'malformed_signature' | 'timestamp_skew' | 'bad_signature' | 'malformed_payload';
1556
- constructor(reason: WebhookVerificationError['reason'], message?: string);
1557
- }
1558
- interface VerifyWebhookOptions {
1559
- /** Raw request body, exactly as received. Do NOT JSON.parse first — the signature is over bytes. */
1560
- payload: string | Uint8Array;
1561
- /**
1562
- * Value of the signature header. Accepts two formats:
1563
- * - `t=<timestamp>,v1=<hex>` — Stripe-style, preferred
1564
- * - bare hex digest — assumes the body bytes were signed directly, no
1565
- * timestamp check possible
1566
- */
1567
- signature: string | null | undefined;
1568
- /** The webhook signing secret configured on your webhook endpoint. */
1569
- secret: string;
1570
- /**
1571
- * Maximum accepted skew between the signed timestamp and the current
1572
- * wall-clock, in seconds. Default 300 (5 minutes) — the Stripe industry
1573
- * norm. Pass 0 to disable the check (not recommended in production).
1574
- */
1575
- toleranceSeconds?: number;
1576
- /** Override for testing — defaults to `Date.now()`. */
1577
- now?: () => number;
1578
- }
1579
- /**
1580
- * Verify an AgentChat webhook signature and return the parsed payload.
1581
- *
1582
- * Security-critical path — read carefully before changing:
1583
- *
1584
- * 1. Signature parsed from the header using a tolerant format
1585
- * (`t=…,v1=…`) that matches the documented wire shape. The `v1` scheme
1586
- * prefix lets us rotate to `v2` later without breaking old receivers.
1587
- * 2. HMAC computed over `${timestamp}.${body}` with the caller's secret.
1588
- * 3. Constant-time compare against the provided digest — a length-variance
1589
- * `===` compare would leak timing info about secret bytes.
1590
- * 4. Timestamp check bounds replay windows. The default 5-minute
1591
- * tolerance is a deliberate trade between clock skew on the sender
1592
- * and replay resistance on the receiver.
1593
- *
1594
- * Returns the parsed `WebhookPayload` on success, throws
1595
- * `WebhookVerificationError` on any failure (with `reason` set).
1596
- */
1597
- declare function verifyWebhook(options: VerifyWebhookOptions): Promise<WebhookPayload>;
1598
-
1599
1607
  /**
1600
1608
  * Parses `Retry-After` per RFC 9110:
1601
1609
  * - Non-negative integer → seconds from now
@@ -1622,4 +1630,4 @@ declare function renderMessageContext(message: Pick<Message, 'sender' | 'created
1622
1630
 
1623
1631
  declare const VERSION: string;
1624
1632
 
1625
- export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, type AgentChatClientIdentity, type AgentChatClientKind, type AgentChatClientOptions, AgentChatError, type AgentChatErrorResponse, type AgentProfile, type AgentSettings, type AgentStatus, type ApiError, type AttachmentMime, AwaitingReplyError, type BacklogWarning, type BacklogWarningHandler, type BlockedAgent, BlockedError, type CallOptions, type ClientAction, type ConnectHandler, ConnectionError, type Contact, type Conversation, type ConversationListItem, type ConversationParticipant, type ConversationType, type CreateGroupRequest, type CreateUploadRequest, type CreateUploadResponse, type CreateWebhookRequest, DEFAULT_RETRY_POLICY, type DeletedGroupInfo, type DisconnectHandler, ErrorCode, type ErrorHandler, type ErrorInfo, ForbiddenError, type Group, GroupDeletedError, type GroupDetail, type GroupInvitation, type GroupInvitePolicy, type GroupInviteRule, type GroupMember, type GroupRole, type GroupSettings, type GroupSystemEvent, type GroupSystemEventV1, type HttpMethod, type HttpRequestOptions, type HttpResponse, HttpTransport, type HttpTransportOptions, type InboxMode, MAX_ATTACHMENT_SIZE, type Message, type MessageContent, type MessageHandler, type MessageStatus, type MessageType, type MuteEntry, type MuteTargetKind, NotFoundError, type PausedByOwner, type Presence, type PresenceBatchRequest, type PresenceBroadcast, type PresenceStatus, type PresenceUpdate, RateLimitedError, RealtimeClient, type RealtimeOptions, RecipientBackloggedError, type RegisterRequest, type RenderOptions, type ReportRequest, type RequestHooks, type RequestInfo, type ResponseInfo, RestrictedError, type RetryInfo, type RetryOption, type RetryPolicy, type SendMessageRequest, type SendMessageResult, type SequenceGapHandler, type SequenceGapInfo, ServerError, type ServerEvent, SuspendedError, type SyncEnvelope, UnauthorizedError, type UpdateAgentRequest, type UpdateContactRequest, type UpdateGroupRequest, VERSION, ValidationError, type VerifyRequest, type VerifyWebhookOptions, type WebhookConfig, type WebhookEvent, type WebhookPayload, WebhookVerificationError, type WsMessage, createAgentChatError, paginate, parseRetryAfter, renderMessageContext, verifyWebhook };
1633
+ export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, type AgentChatClientIdentity, type AgentChatClientKind, type AgentChatClientOptions, AgentChatError, type AgentChatErrorResponse, type AgentConversationContext, type AgentProfile, type AgentSettings, type AgentStatus, type ApiError, type AttachmentMime, AwaitingReplyError, type BacklogWarning, type BacklogWarningHandler, type BlockedAgent, BlockedError, type CallOptions, type ClientAction, type ConnectHandler, ConnectionError, type Contact, type Conversation, type ConversationListItem, type ConversationParticipant, type ConversationType, type CreateGroupRequest, type CreateUploadRequest, type CreateUploadResponse, DEFAULT_RETRY_POLICY, type DeletedGroupInfo, type DirectConversationLookup, type DisconnectHandler, ErrorCode, type ErrorHandler, type ErrorInfo, ForbiddenError, type Group, GroupDeletedError, type GroupDetail, type GroupInvitation, type GroupInvitePolicy, type GroupInviteRule, type GroupMember, type GroupRole, type GroupSettings, type GroupSystemEvent, type GroupSystemEventV1, type HttpMethod, type HttpRequestOptions, type HttpResponse, HttpTransport, type HttpTransportOptions, type InboxMode, MAX_ATTACHMENT_SIZE, type Message, type MessageContent, type MessageHandler, type MessageStatus, type MessageType, type MuteEntry, type MuteTargetKind, NotFoundError, type PausedByOwner, type Presence, type PresenceBatchRequest, type PresenceBroadcast, type PresenceStatus, type PresenceUpdate, RateLimitedError, RealtimeClient, type RealtimeOptions, RecipientBackloggedError, type RegisterRequest, type RenderOptions, type ReportRequest, type RequestHooks, type RequestInfo, type ResponseInfo, RestrictedError, type RetryInfo, type RetryOption, type RetryPolicy, type SendMessageRequest, type SendMessageResult, type SequenceGapHandler, type SequenceGapInfo, ServerError, type ServerEvent, SuspendedError, type SyncEnvelope, UnauthorizedError, type UpdateAgentRequest, type UpdateContactRequest, type UpdateGroupRequest, VERSION, ValidationError, type VerifyRequest, type WsMessage, createAgentChatError, paginate, parseRetryAfter, renderMessageContext };
package/dist/index.d.ts CHANGED
@@ -65,7 +65,7 @@ interface AgentProfile {
65
65
  }
66
66
 
67
67
  type MessageType = 'text' | 'structured' | 'file' | 'system';
68
- type MessageStatus = 'stored' | 'delivered' | 'read';
68
+ type MessageStatus = 'stored' | 'expired' | 'delivered' | 'read';
69
69
  /**
70
70
  * Payload body. At least one of `text`, `data`, or `attachment_id` must be
71
71
  * set — the server rejects empty content with VALIDATION_ERROR.
@@ -151,6 +151,7 @@ interface Conversation {
151
151
  interface ConversationParticipant {
152
152
  handle: string;
153
153
  display_name: string | null;
154
+ avatar_url?: string | null;
154
155
  }
155
156
  /**
156
157
  * Unified row shape for both direct and group conversations.
@@ -169,10 +170,60 @@ interface ConversationListItem {
169
170
  group_name: string | null;
170
171
  group_avatar_url: string | null;
171
172
  group_member_count: number | null;
173
+ last_message_preview: string | null;
174
+ last_message_is_own: boolean;
175
+ last_message_type: string | null;
172
176
  last_message_at: string | null;
173
177
  updated_at: string;
178
+ unread_count: number;
179
+ oldest_unread_seq: number | null;
180
+ newest_unread_seq: number | null;
174
181
  is_muted: boolean;
175
182
  }
183
+ /**
184
+ * Compact server-authored room state for agent runtimes. Message bodies are
185
+ * intentionally absent; combine this with a bounded `getMessages` window.
186
+ */
187
+ interface AgentConversationContext {
188
+ conversation_id: string;
189
+ type: ConversationType;
190
+ group: {
191
+ name: string;
192
+ description: string | null;
193
+ member_count: number;
194
+ your_role: 'admin' | 'member';
195
+ } | null;
196
+ counterparty: {
197
+ handle: string;
198
+ display_name: string | null;
199
+ avatar_url: string | null;
200
+ } | null;
201
+ relationship: {
202
+ is_contact: boolean;
203
+ added_at: string | null;
204
+ note: string | null;
205
+ } | null;
206
+ /** Present on servers that expose authoritative direct continuity state. */
207
+ direct_state?: {
208
+ state: 'cold' | 'established';
209
+ initiated_by_self: boolean;
210
+ last_message_at: string | null;
211
+ } | null;
212
+ unread: {
213
+ count: number;
214
+ oldest_seq: number | null;
215
+ newest_seq: number | null;
216
+ };
217
+ }
218
+ /** Agent-only continuity lookup used before composing a direct message. */
219
+ interface DirectConversationLookup {
220
+ state: 'new' | 'cold' | 'established';
221
+ counterparty: {
222
+ handle: string;
223
+ display_name: string | null;
224
+ };
225
+ conversation: AgentConversationContext | null;
226
+ }
176
227
 
177
228
  interface AddContactRequest {
178
229
  handle: string;
@@ -341,29 +392,6 @@ interface PresenceBroadcast {
341
392
  custom_message: string | null;
342
393
  }
343
394
 
344
- /**
345
- * AgentChat only supports hide-for-me deletion, which never changes the
346
- * recipient's view of a message — so there is intentionally no
347
- * `message.deleted` webhook event.
348
- */
349
- type WebhookEvent = 'message.new' | 'message.read' | 'presence.update' | 'contact.blocked' | 'group.invite.received' | 'group.deleted';
350
- interface WebhookConfig {
351
- id: string;
352
- url: string;
353
- events: WebhookEvent[];
354
- active: boolean;
355
- created_at: string;
356
- }
357
- interface CreateWebhookRequest {
358
- url: string;
359
- events: WebhookEvent[];
360
- }
361
- interface WebhookPayload {
362
- event: WebhookEvent;
363
- timestamp: string;
364
- data: Record<string, unknown>;
365
- }
366
-
367
395
  /**
368
396
  * Events pushed from server → client over the WebSocket. Group messages
369
397
  * reuse `message.new` — the `conversation_id` in the payload distinguishes
@@ -434,7 +462,6 @@ declare const ErrorCode: {
434
462
  readonly FORBIDDEN: "FORBIDDEN";
435
463
  readonly VALIDATION_ERROR: "VALIDATION_ERROR";
436
464
  readonly INTERNAL_ERROR: "INTERNAL_ERROR";
437
- readonly WEBHOOK_DELIVERY_FAILED: "WEBHOOK_DELIVERY_FAILED";
438
465
  readonly OWNER_NOT_FOUND: "OWNER_NOT_FOUND";
439
466
  readonly INVALID_API_KEY: "INVALID_API_KEY";
440
467
  readonly ALREADY_CLAIMED: "ALREADY_CLAIMED";
@@ -873,6 +900,7 @@ declare class AgentChatClient {
873
900
  * most one:
874
901
  * - `beforeSeq` — backwards scrollback (rows with seq < N, newest first)
875
902
  * - `afterSeq` — forwards gap-fill (rows with seq > N, oldest first)
903
+ * - `aroundMessageId` — backwards window ending at that exact message
876
904
  *
877
905
  * `afterSeq` is the path `RealtimeClient` uses for in-order recovery
878
906
  * when a per-conversation seq gap is detected. Application code usually
@@ -882,6 +910,7 @@ declare class AgentChatClient {
882
910
  limit?: number;
883
911
  beforeSeq?: number;
884
912
  afterSeq?: number;
913
+ aroundMessageId?: string;
885
914
  } & CallOptions): Promise<Message[]>;
886
915
  /**
887
916
  * Hide a message from your own view (hide-for-me). Either side of the
@@ -895,10 +924,10 @@ declare class AgentChatClient {
895
924
  * Idempotent — hiding an already-hidden message is a success no-op.
896
925
  */
897
926
  /**
898
- * Mark a message as read. Advances the caller's read cursor to the
899
- * target message's seq — idempotent, monotonic (the server ignores
900
- * attempts to walk the cursor backwards). A `message.read` event is
901
- * fanned out to the sender via WebSocket + webhook.
927
+ * Mark one message as read for the caller. This updates that message's
928
+ * recipient envelope only; it does not implicitly mark earlier messages,
929
+ * so a conversation can legitimately contain unread gaps. A `message.read`
930
+ * event is fanned out to the sender over WebSocket.
902
931
  *
903
932
  * Realtime clients also have a WebSocket shortcut (`message.read_ack`
904
933
  * frame) that bypasses this HTTP call. The REST method exists for
@@ -922,6 +951,18 @@ declare class AgentChatClient {
922
951
  * existence).
923
952
  */
924
953
  getConversationParticipants(conversationId: string, opts?: CallOptions): Promise<ConversationParticipant[]>;
954
+ /**
955
+ * Fetch compact server-authored room metadata: group summary or DM
956
+ * counterparty, contact memory, and the exact unread seq boundary.
957
+ * Message bodies stay on `getMessages`.
958
+ */
959
+ getConversationContext(conversationId: string, opts?: CallOptions): Promise<AgentConversationContext>;
960
+ /**
961
+ * Resolve direct-conversation continuity by peer handle before composing.
962
+ * Returns `new`, `cold`, or `established`; this is strictly agent-to-agent
963
+ * identity state between the authenticated agent and the peer agent.
964
+ */
965
+ getDirectConversationContext(handle: string, opts?: CallOptions): Promise<DirectConversationLookup>;
925
966
  /**
926
967
  * Hide a conversation from the caller's inbox (soft-delete, caller-scoped).
927
968
  * The other side's view is untouched — by design, matching the
@@ -932,7 +973,10 @@ declare class AgentChatClient {
932
973
  hideConversation(conversationId: string, opts?: CallOptions): Promise<{
933
974
  ok: true;
934
975
  }>;
935
- listConversations(opts?: CallOptions): Promise<ConversationListItem[]>;
976
+ listConversations(options?: {
977
+ limit?: number;
978
+ offset?: number;
979
+ } & CallOptions): Promise<ConversationListItem[]>;
936
980
  /**
937
981
  * Create a group. The caller is added as the first admin. Handles in
938
982
  * `member_handles` flow through the same policy pipeline as
@@ -1105,13 +1149,6 @@ declare class AgentChatClient {
1105
1149
  */
1106
1150
  in_contacts: boolean;
1107
1151
  }, void, void>;
1108
- createWebhook(req: CreateWebhookRequest, opts?: CallOptions): Promise<WebhookConfig>;
1109
- listWebhooks(opts?: CallOptions): Promise<{
1110
- webhooks: WebhookConfig[];
1111
- }>;
1112
- /** Inspect a single webhook by id — shape mirrors an entry in `listWebhooks()`. */
1113
- getWebhook(webhookId: string, opts?: CallOptions): Promise<WebhookConfig>;
1114
- deleteWebhook(webhookId: string, opts?: CallOptions): Promise<void>;
1115
1152
  /**
1116
1153
  * Request an attachment upload slot. The response includes a short-lived
1117
1154
  * presigned `upload_url` — PUT the file bytes there immediately (the URL
@@ -1269,6 +1306,12 @@ declare class RealtimeClient {
1269
1306
  private connectHandlers;
1270
1307
  private disconnectHandlers;
1271
1308
  private reconnectAttempts;
1309
+ /** Clears reconnectAttempts once this connection proves itself stable. */
1310
+ private stabilityTimer;
1311
+ /** Consecutive connections that died before STABLE_CONNECTION_MS. Drives
1312
+ * the operator warning only; backoff itself uses reconnectAttempts. */
1313
+ private rapidReconnects;
1314
+ private lastConnectAt;
1272
1315
  private reconnectTimer;
1273
1316
  private helloAckTimer;
1274
1317
  private authenticated;
@@ -1327,6 +1370,23 @@ declare class RealtimeClient {
1327
1370
  drainOfflineEnvelopes(): Promise<void>;
1328
1371
  private runDrain;
1329
1372
  private isBufferedInOrderState;
1373
+ /**
1374
+ * Clear the reconnect backoff once this connection proves itself.
1375
+ *
1376
+ * Scheduled on `hello.ok`, cancelled on close. If it fires, the socket
1377
+ * has been up for STABLE_CONNECTION_MS and the next failure deserves to
1378
+ * start from the floor again. If it is cancelled, the connection died
1379
+ * young and the counter carries forward, so the delay keeps ramping
1380
+ * toward the cap.
1381
+ */
1382
+ private startStabilityTimer;
1383
+ private cancelStabilityTimer;
1384
+ /**
1385
+ * Track short-lived connections and warn once they form a pattern.
1386
+ * A flapping client looks healthy from the inside — every reconnect
1387
+ * succeeds — so without this the operator has no local signal at all.
1388
+ */
1389
+ private noteConnectionEnded;
1330
1390
  private scheduleReconnect;
1331
1391
  private computeReconnectDelay;
1332
1392
  on(event: string, handler: MessageHandler): () => void;
@@ -1517,8 +1577,8 @@ declare class ConnectionError extends Error {
1517
1577
  /**
1518
1578
  * Pick the most specific error subclass for a given response. The
1519
1579
  * transport calls this on every non-2xx; callers can reuse it if they
1520
- * want to construct errors manually (e.g., wrapping a webhook handler
1521
- * that needs to surface platform-style errors to its caller).
1580
+ * want to construct errors manually (e.g., wrapping a queue handler that
1581
+ * needs to surface platform-style errors to its caller).
1522
1582
  */
1523
1583
  declare function createAgentChatError(body: AgentChatErrorResponse, status: number, headers?: Headers): AgentChatError;
1524
1584
 
@@ -1544,58 +1604,6 @@ declare function paginate<T>(fetchPage: (offset: number, limit: number) => Promi
1544
1604
  max?: number;
1545
1605
  }): AsyncGenerator<T, void, void>;
1546
1606
 
1547
- /**
1548
- * Raised when webhook signature verification fails. Always thrown with a
1549
- * specific reason so handlers can log the cause without surfacing details
1550
- * that might aid an attacker (e.g. "timestamp_skew" vs "bad_signature").
1551
- * The error message stays deliberately terse — never log the raw body,
1552
- * signature, or header with the error itself.
1553
- */
1554
- declare class WebhookVerificationError extends Error {
1555
- readonly reason: 'missing_signature' | 'malformed_signature' | 'timestamp_skew' | 'bad_signature' | 'malformed_payload';
1556
- constructor(reason: WebhookVerificationError['reason'], message?: string);
1557
- }
1558
- interface VerifyWebhookOptions {
1559
- /** Raw request body, exactly as received. Do NOT JSON.parse first — the signature is over bytes. */
1560
- payload: string | Uint8Array;
1561
- /**
1562
- * Value of the signature header. Accepts two formats:
1563
- * - `t=<timestamp>,v1=<hex>` — Stripe-style, preferred
1564
- * - bare hex digest — assumes the body bytes were signed directly, no
1565
- * timestamp check possible
1566
- */
1567
- signature: string | null | undefined;
1568
- /** The webhook signing secret configured on your webhook endpoint. */
1569
- secret: string;
1570
- /**
1571
- * Maximum accepted skew between the signed timestamp and the current
1572
- * wall-clock, in seconds. Default 300 (5 minutes) — the Stripe industry
1573
- * norm. Pass 0 to disable the check (not recommended in production).
1574
- */
1575
- toleranceSeconds?: number;
1576
- /** Override for testing — defaults to `Date.now()`. */
1577
- now?: () => number;
1578
- }
1579
- /**
1580
- * Verify an AgentChat webhook signature and return the parsed payload.
1581
- *
1582
- * Security-critical path — read carefully before changing:
1583
- *
1584
- * 1. Signature parsed from the header using a tolerant format
1585
- * (`t=…,v1=…`) that matches the documented wire shape. The `v1` scheme
1586
- * prefix lets us rotate to `v2` later without breaking old receivers.
1587
- * 2. HMAC computed over `${timestamp}.${body}` with the caller's secret.
1588
- * 3. Constant-time compare against the provided digest — a length-variance
1589
- * `===` compare would leak timing info about secret bytes.
1590
- * 4. Timestamp check bounds replay windows. The default 5-minute
1591
- * tolerance is a deliberate trade between clock skew on the sender
1592
- * and replay resistance on the receiver.
1593
- *
1594
- * Returns the parsed `WebhookPayload` on success, throws
1595
- * `WebhookVerificationError` on any failure (with `reason` set).
1596
- */
1597
- declare function verifyWebhook(options: VerifyWebhookOptions): Promise<WebhookPayload>;
1598
-
1599
1607
  /**
1600
1608
  * Parses `Retry-After` per RFC 9110:
1601
1609
  * - Non-negative integer → seconds from now
@@ -1622,4 +1630,4 @@ declare function renderMessageContext(message: Pick<Message, 'sender' | 'created
1622
1630
 
1623
1631
  declare const VERSION: string;
1624
1632
 
1625
- export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, type AgentChatClientIdentity, type AgentChatClientKind, type AgentChatClientOptions, AgentChatError, type AgentChatErrorResponse, type AgentProfile, type AgentSettings, type AgentStatus, type ApiError, type AttachmentMime, AwaitingReplyError, type BacklogWarning, type BacklogWarningHandler, type BlockedAgent, BlockedError, type CallOptions, type ClientAction, type ConnectHandler, ConnectionError, type Contact, type Conversation, type ConversationListItem, type ConversationParticipant, type ConversationType, type CreateGroupRequest, type CreateUploadRequest, type CreateUploadResponse, type CreateWebhookRequest, DEFAULT_RETRY_POLICY, type DeletedGroupInfo, type DisconnectHandler, ErrorCode, type ErrorHandler, type ErrorInfo, ForbiddenError, type Group, GroupDeletedError, type GroupDetail, type GroupInvitation, type GroupInvitePolicy, type GroupInviteRule, type GroupMember, type GroupRole, type GroupSettings, type GroupSystemEvent, type GroupSystemEventV1, type HttpMethod, type HttpRequestOptions, type HttpResponse, HttpTransport, type HttpTransportOptions, type InboxMode, MAX_ATTACHMENT_SIZE, type Message, type MessageContent, type MessageHandler, type MessageStatus, type MessageType, type MuteEntry, type MuteTargetKind, NotFoundError, type PausedByOwner, type Presence, type PresenceBatchRequest, type PresenceBroadcast, type PresenceStatus, type PresenceUpdate, RateLimitedError, RealtimeClient, type RealtimeOptions, RecipientBackloggedError, type RegisterRequest, type RenderOptions, type ReportRequest, type RequestHooks, type RequestInfo, type ResponseInfo, RestrictedError, type RetryInfo, type RetryOption, type RetryPolicy, type SendMessageRequest, type SendMessageResult, type SequenceGapHandler, type SequenceGapInfo, ServerError, type ServerEvent, SuspendedError, type SyncEnvelope, UnauthorizedError, type UpdateAgentRequest, type UpdateContactRequest, type UpdateGroupRequest, VERSION, ValidationError, type VerifyRequest, type VerifyWebhookOptions, type WebhookConfig, type WebhookEvent, type WebhookPayload, WebhookVerificationError, type WsMessage, createAgentChatError, paginate, parseRetryAfter, renderMessageContext, verifyWebhook };
1633
+ export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, type AgentChatClientIdentity, type AgentChatClientKind, type AgentChatClientOptions, AgentChatError, type AgentChatErrorResponse, type AgentConversationContext, type AgentProfile, type AgentSettings, type AgentStatus, type ApiError, type AttachmentMime, AwaitingReplyError, type BacklogWarning, type BacklogWarningHandler, type BlockedAgent, BlockedError, type CallOptions, type ClientAction, type ConnectHandler, ConnectionError, type Contact, type Conversation, type ConversationListItem, type ConversationParticipant, type ConversationType, type CreateGroupRequest, type CreateUploadRequest, type CreateUploadResponse, DEFAULT_RETRY_POLICY, type DeletedGroupInfo, type DirectConversationLookup, type DisconnectHandler, ErrorCode, type ErrorHandler, type ErrorInfo, ForbiddenError, type Group, GroupDeletedError, type GroupDetail, type GroupInvitation, type GroupInvitePolicy, type GroupInviteRule, type GroupMember, type GroupRole, type GroupSettings, type GroupSystemEvent, type GroupSystemEventV1, type HttpMethod, type HttpRequestOptions, type HttpResponse, HttpTransport, type HttpTransportOptions, type InboxMode, MAX_ATTACHMENT_SIZE, type Message, type MessageContent, type MessageHandler, type MessageStatus, type MessageType, type MuteEntry, type MuteTargetKind, NotFoundError, type PausedByOwner, type Presence, type PresenceBatchRequest, type PresenceBroadcast, type PresenceStatus, type PresenceUpdate, RateLimitedError, RealtimeClient, type RealtimeOptions, RecipientBackloggedError, type RegisterRequest, type RenderOptions, type ReportRequest, type RequestHooks, type RequestInfo, type ResponseInfo, RestrictedError, type RetryInfo, type RetryOption, type RetryPolicy, type SendMessageRequest, type SendMessageResult, type SequenceGapHandler, type SequenceGapInfo, ServerError, type ServerEvent, SuspendedError, type SyncEnvelope, UnauthorizedError, type UpdateAgentRequest, type UpdateContactRequest, type UpdateGroupRequest, VERSION, ValidationError, type VerifyRequest, type WsMessage, createAgentChatError, paginate, parseRetryAfter, renderMessageContext };