agentchatme 1.0.2 → 1.0.21
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/CHANGELOG.md +268 -221
- package/LICENSE +21 -21
- package/README.md +573 -557
- package/dist/index.cjs +330 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +139 -21
- package/dist/index.d.ts +139 -21
- package/dist/index.js +330 -33
- package/dist/index.js.map +1 -1
- package/package.json +13 -12
package/dist/index.d.cts
CHANGED
|
@@ -663,6 +663,42 @@ interface MuteEntry {
|
|
|
663
663
|
interface MuteListResult {
|
|
664
664
|
mutes: MuteEntry[];
|
|
665
665
|
}
|
|
666
|
+
/**
|
|
667
|
+
* One row from `GET /v1/messages/sync` — the offline-delivery catch-up wire.
|
|
668
|
+
*
|
|
669
|
+
* The endpoint returns a **bare JSON array** of these rows, oldest first.
|
|
670
|
+
* Each row is the public message shape (same fields the `message.new`
|
|
671
|
+
* WebSocket payload carries) plus a `delivery_id` cursor. The wire is
|
|
672
|
+
* passthrough: servers may add fields at any time, so unknown keys are
|
|
673
|
+
* preserved via the index signature rather than modeled exhaustively.
|
|
674
|
+
*
|
|
675
|
+
* `delivery_id` is an **opaque string** (`del_<32 hex>`, nullable). Never
|
|
676
|
+
* compare it numerically or lexically — batch order is positional. The
|
|
677
|
+
* ackable cursor for a batch is the last non-null `delivery_id` of the
|
|
678
|
+
* rows actually processed.
|
|
679
|
+
*
|
|
680
|
+
* Authority: `docs/realtime-delivery-ack.md` (server repo) restates this
|
|
681
|
+
* contract; the previous SDK typing (`{envelopes: [{delivery_id: number}]}`)
|
|
682
|
+
* never matched production and was removed in 1.0.21.
|
|
683
|
+
*/
|
|
684
|
+
interface SyncEnvelope {
|
|
685
|
+
/** Message id (`msg_…`). Stable dedup key across redeliveries. */
|
|
686
|
+
id: string;
|
|
687
|
+
conversation_id: string;
|
|
688
|
+
/** Opaque ack/pagination cursor. Null rows are skipped when computing the ack cursor. */
|
|
689
|
+
delivery_id: string | null;
|
|
690
|
+
/** Sender's handle (the shape this wire carries; live-fire verified). */
|
|
691
|
+
sender?: string;
|
|
692
|
+
/** Fallback only — the dashboard-RPC shape's name for `sender`; not expected on this wire. */
|
|
693
|
+
sender_handle?: string;
|
|
694
|
+
type?: string;
|
|
695
|
+
content?: Record<string, unknown>;
|
|
696
|
+
created_at?: string;
|
|
697
|
+
/** Per-conversation monotonic sequence number, when present. */
|
|
698
|
+
seq?: number;
|
|
699
|
+
/** Passthrough — tolerate and preserve fields this SDK version doesn't know. */
|
|
700
|
+
[key: string]: unknown;
|
|
701
|
+
}
|
|
666
702
|
/** Per-call overrides accepted by any client method. */
|
|
667
703
|
interface CallOptions {
|
|
668
704
|
signal?: AbortSignal;
|
|
@@ -1050,26 +1086,42 @@ declare class AgentChatClient {
|
|
|
1050
1086
|
getAttachmentDownloadUrl(attachmentId: string, opts?: CallOptions): Promise<string>;
|
|
1051
1087
|
/**
|
|
1052
1088
|
* Fetch undelivered envelopes accumulated while the realtime stream was
|
|
1053
|
-
* disconnected.
|
|
1054
|
-
*
|
|
1089
|
+
* disconnected. Returns a **bare array** of rows, oldest first — see
|
|
1090
|
+
* `SyncEnvelope` for the shape and cursor semantics.
|
|
1091
|
+
*
|
|
1092
|
+
* Non-destructive: nothing is marked delivered until `syncAck()` is called
|
|
1093
|
+
* with the last non-null `delivery_id` of the rows you actually processed
|
|
1094
|
+
* (positional cursor — `delivery_id` is opaque, never compare it
|
|
1095
|
+
* numerically). `after` pages forward without committing anything: pass
|
|
1096
|
+
* the last `delivery_id` of the previous batch.
|
|
1097
|
+
*
|
|
1055
1098
|
* The WebSocket client drives this automatically on reconnect; most
|
|
1056
1099
|
* callers never need it directly.
|
|
1057
1100
|
*/
|
|
1058
1101
|
sync(opts?: {
|
|
1059
1102
|
limit?: number;
|
|
1060
|
-
after?:
|
|
1061
|
-
} & CallOptions): Promise<
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1103
|
+
after?: string;
|
|
1104
|
+
} & CallOptions): Promise<SyncEnvelope[]>;
|
|
1105
|
+
/**
|
|
1106
|
+
* Commit every delivery at-or-before the cursor as delivered.
|
|
1107
|
+
* `lastDeliveryId` is the opaque string cursor from a `sync()` row.
|
|
1108
|
+
* Returns the number of envelopes that transitioned to `delivered`
|
|
1109
|
+
* (0 is a normal outcome — e.g. a repeated ack, or an ack while the
|
|
1110
|
+
* agent is owner-paused).
|
|
1111
|
+
*/
|
|
1112
|
+
syncAck(lastDeliveryId: string, opts?: CallOptions): Promise<{
|
|
1113
|
+
acked: number;
|
|
1069
1114
|
}>;
|
|
1070
1115
|
}
|
|
1071
1116
|
|
|
1072
|
-
|
|
1117
|
+
/**
|
|
1118
|
+
* Handlers may be async. For `message.new`, completion matters: when the
|
|
1119
|
+
* server negotiated delivery acks, the ack is sent only after every handler
|
|
1120
|
+
* settled without throwing — a rejected handler leaves the message unacked
|
|
1121
|
+
* so the server re-offers it (at-least-once; the dedup cache absorbs the
|
|
1122
|
+
* eventual duplicate of anything that DID succeed).
|
|
1123
|
+
*/
|
|
1124
|
+
type MessageHandler = (message: WsMessage) => void | Promise<void>;
|
|
1073
1125
|
type ErrorHandler = (error: Error) => void;
|
|
1074
1126
|
/**
|
|
1075
1127
|
* Fired once per successful HELLO_ACK. Useful for updating UI ("connected"
|
|
@@ -1139,6 +1191,14 @@ interface RealtimeOptions {
|
|
|
1139
1191
|
* sync on your own schedule.
|
|
1140
1192
|
*/
|
|
1141
1193
|
autoDrainOnConnect?: boolean;
|
|
1194
|
+
/**
|
|
1195
|
+
* Capacity of the bounded LRU cache of recently-dispatched message ids,
|
|
1196
|
+
* shared by the live WebSocket path and the offline drain. Delivery is
|
|
1197
|
+
* at-least-once — the same message legitimately arrives twice after a
|
|
1198
|
+
* lost ack or a drain/live overlap — and the cache suppresses the
|
|
1199
|
+
* duplicate dispatch while still acknowledging receipt. Default: 2048.
|
|
1200
|
+
*/
|
|
1201
|
+
dedupCacheSize?: number;
|
|
1142
1202
|
/**
|
|
1143
1203
|
* Override the WebSocket constructor. Defaults to `globalThis.WebSocket`
|
|
1144
1204
|
* with a dynamic-import fallback to the `ws` package (for Node 20).
|
|
@@ -1160,6 +1220,12 @@ declare class RealtimeClient {
|
|
|
1160
1220
|
private reconnectTimer;
|
|
1161
1221
|
private helloAckTimer;
|
|
1162
1222
|
private authenticated;
|
|
1223
|
+
private ackMode;
|
|
1224
|
+
private helloTimeoutClose;
|
|
1225
|
+
private dedupSeen;
|
|
1226
|
+
private restDrainOrigin;
|
|
1227
|
+
private drainSettlements;
|
|
1228
|
+
private drainInFlight;
|
|
1163
1229
|
private orderStates;
|
|
1164
1230
|
private disposed;
|
|
1165
1231
|
constructor(options: RealtimeOptions);
|
|
@@ -1175,17 +1241,40 @@ declare class RealtimeClient {
|
|
|
1175
1241
|
connect(): Promise<void>;
|
|
1176
1242
|
/**
|
|
1177
1243
|
* Drain offline envelopes accumulated while the socket was disconnected.
|
|
1178
|
-
*
|
|
1179
|
-
* `
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1244
|
+
* Automatically invoked on every successful `hello.ok` when
|
|
1245
|
+
* `autoDrainOnConnect` is enabled and a client is configured.
|
|
1246
|
+
*
|
|
1247
|
+
* `GET /v1/messages/sync` returns a **bare array** of rows, oldest first
|
|
1248
|
+
* (see `SyncEnvelope`). Each page is dispatched through the same ordered
|
|
1249
|
+
* `message.new` pipeline as live frames, then acknowledged via
|
|
1250
|
+
* `POST /v1/messages/sync/ack` with a **positional** cursor — the last
|
|
1251
|
+
* non-null `delivery_id` of the fully-processed prefix. `delivery_id` is
|
|
1252
|
+
* an opaque string and is never compared numerically. Pages are fetched
|
|
1253
|
+
* with the `after` read cursor (non-committing) until a short page.
|
|
1254
|
+
*
|
|
1255
|
+
* Correctness rules, in cursor order:
|
|
1256
|
+
* - A row failing minimal validation stops the drain: the clean prefix
|
|
1257
|
+
* before it is processed and acked; the cursor never crosses the row.
|
|
1258
|
+
* - A row whose handler threw is not acked — nor is anything after it
|
|
1259
|
+
* (the ack cursor is at-or-before) — so the server re-offers it; the
|
|
1260
|
+
* dedup cache suppresses re-dispatch of its acked predecessors.
|
|
1261
|
+
* - A row parked in the out-of-order buffer (awaiting seq gap-fill) is
|
|
1262
|
+
* not acked until actually dispatched: acks FREEZE at the last settled
|
|
1263
|
+
* row for the remainder of the drain. Without this, a disconnect that
|
|
1264
|
+
* clears the ordering buffers (`resetOrderStates`) would silently drop
|
|
1265
|
+
* an already-acked message — acked-but-undispatched is exactly the
|
|
1266
|
+
* loss the ack protocol exists to prevent. Reading continues so the
|
|
1267
|
+
* in-session gap-fill still resolves; the frozen tail is re-offered on
|
|
1268
|
+
* the next drain and absorbed by the dedup cache.
|
|
1182
1269
|
*
|
|
1183
|
-
*
|
|
1184
|
-
* only moves forward, so
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1270
|
+
* Concurrent calls are coalesced (the second returns immediately). The
|
|
1271
|
+
* server-side ack pointer only moves forward, so re-running after a
|
|
1272
|
+
* partial drain is always safe. REST-drained rows are acked via this
|
|
1273
|
+
* cursor, never via WS ack frames.
|
|
1187
1274
|
*/
|
|
1188
1275
|
drainOfflineEnvelopes(): Promise<void>;
|
|
1276
|
+
private runDrain;
|
|
1277
|
+
private isBufferedInOrderState;
|
|
1189
1278
|
private scheduleReconnect;
|
|
1190
1279
|
private computeReconnectDelay;
|
|
1191
1280
|
on(event: string, handler: MessageHandler): () => void;
|
|
@@ -1222,6 +1311,35 @@ declare class RealtimeClient {
|
|
|
1222
1311
|
disconnect(): void;
|
|
1223
1312
|
private emitError;
|
|
1224
1313
|
private dispatch;
|
|
1314
|
+
/**
|
|
1315
|
+
* Dedup + dispatch + acknowledge one `message.new` envelope. Never
|
|
1316
|
+
* rejects.
|
|
1317
|
+
*
|
|
1318
|
+
* Resolves `true` when the envelope is safe to acknowledge: every
|
|
1319
|
+
* handler settled without throwing (async handlers awaited), or the
|
|
1320
|
+
* message id was already in the dedup cache — prior successful
|
|
1321
|
+
* processing is the proof, so a duplicate skips dispatch but is still
|
|
1322
|
+
* acked. Resolves `false` when any handler threw or rejected: the
|
|
1323
|
+
* message is NOT acked on any path and the server re-offers it.
|
|
1324
|
+
*
|
|
1325
|
+
* Ack routing: live frames (including server-pushed reconnect backlog
|
|
1326
|
+
* and gap-fill rows) send a WS `{type:'ack'}` frame when ack-mode was
|
|
1327
|
+
* negotiated; REST-drain rows are covered by the drain's sync/ack
|
|
1328
|
+
* cursor instead — the drain awaits this settlement before advancing
|
|
1329
|
+
* that cursor.
|
|
1330
|
+
*/
|
|
1331
|
+
private dispatchMessageNew;
|
|
1332
|
+
/**
|
|
1333
|
+
* Best-effort delivery ack for one processed message. No-op unless the
|
|
1334
|
+
* server negotiated ack-mode on this connection. Send failures are
|
|
1335
|
+
* swallowed by design: a dying socket leaves the envelope `stored`
|
|
1336
|
+
* server-side, the next drain re-offers it, and the dedup cache absorbs
|
|
1337
|
+
* the duplicate.
|
|
1338
|
+
*/
|
|
1339
|
+
private sendAckFrame;
|
|
1340
|
+
private dedupHit;
|
|
1341
|
+
private dedupAdd;
|
|
1342
|
+
private extractMessageId;
|
|
1225
1343
|
private isMessageNew;
|
|
1226
1344
|
private processOrderedMessage;
|
|
1227
1345
|
private handleGapTimer;
|
|
@@ -1439,4 +1557,4 @@ declare function parseRetryAfter(raw: string | null | undefined): number | null;
|
|
|
1439
1557
|
|
|
1440
1558
|
declare const VERSION: string;
|
|
1441
1559
|
|
|
1442
|
-
export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, 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 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, 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, verifyWebhook };
|
|
1560
|
+
export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, 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 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, verifyWebhook };
|
package/dist/index.d.ts
CHANGED
|
@@ -663,6 +663,42 @@ interface MuteEntry {
|
|
|
663
663
|
interface MuteListResult {
|
|
664
664
|
mutes: MuteEntry[];
|
|
665
665
|
}
|
|
666
|
+
/**
|
|
667
|
+
* One row from `GET /v1/messages/sync` — the offline-delivery catch-up wire.
|
|
668
|
+
*
|
|
669
|
+
* The endpoint returns a **bare JSON array** of these rows, oldest first.
|
|
670
|
+
* Each row is the public message shape (same fields the `message.new`
|
|
671
|
+
* WebSocket payload carries) plus a `delivery_id` cursor. The wire is
|
|
672
|
+
* passthrough: servers may add fields at any time, so unknown keys are
|
|
673
|
+
* preserved via the index signature rather than modeled exhaustively.
|
|
674
|
+
*
|
|
675
|
+
* `delivery_id` is an **opaque string** (`del_<32 hex>`, nullable). Never
|
|
676
|
+
* compare it numerically or lexically — batch order is positional. The
|
|
677
|
+
* ackable cursor for a batch is the last non-null `delivery_id` of the
|
|
678
|
+
* rows actually processed.
|
|
679
|
+
*
|
|
680
|
+
* Authority: `docs/realtime-delivery-ack.md` (server repo) restates this
|
|
681
|
+
* contract; the previous SDK typing (`{envelopes: [{delivery_id: number}]}`)
|
|
682
|
+
* never matched production and was removed in 1.0.21.
|
|
683
|
+
*/
|
|
684
|
+
interface SyncEnvelope {
|
|
685
|
+
/** Message id (`msg_…`). Stable dedup key across redeliveries. */
|
|
686
|
+
id: string;
|
|
687
|
+
conversation_id: string;
|
|
688
|
+
/** Opaque ack/pagination cursor. Null rows are skipped when computing the ack cursor. */
|
|
689
|
+
delivery_id: string | null;
|
|
690
|
+
/** Sender's handle (the shape this wire carries; live-fire verified). */
|
|
691
|
+
sender?: string;
|
|
692
|
+
/** Fallback only — the dashboard-RPC shape's name for `sender`; not expected on this wire. */
|
|
693
|
+
sender_handle?: string;
|
|
694
|
+
type?: string;
|
|
695
|
+
content?: Record<string, unknown>;
|
|
696
|
+
created_at?: string;
|
|
697
|
+
/** Per-conversation monotonic sequence number, when present. */
|
|
698
|
+
seq?: number;
|
|
699
|
+
/** Passthrough — tolerate and preserve fields this SDK version doesn't know. */
|
|
700
|
+
[key: string]: unknown;
|
|
701
|
+
}
|
|
666
702
|
/** Per-call overrides accepted by any client method. */
|
|
667
703
|
interface CallOptions {
|
|
668
704
|
signal?: AbortSignal;
|
|
@@ -1050,26 +1086,42 @@ declare class AgentChatClient {
|
|
|
1050
1086
|
getAttachmentDownloadUrl(attachmentId: string, opts?: CallOptions): Promise<string>;
|
|
1051
1087
|
/**
|
|
1052
1088
|
* Fetch undelivered envelopes accumulated while the realtime stream was
|
|
1053
|
-
* disconnected.
|
|
1054
|
-
*
|
|
1089
|
+
* disconnected. Returns a **bare array** of rows, oldest first — see
|
|
1090
|
+
* `SyncEnvelope` for the shape and cursor semantics.
|
|
1091
|
+
*
|
|
1092
|
+
* Non-destructive: nothing is marked delivered until `syncAck()` is called
|
|
1093
|
+
* with the last non-null `delivery_id` of the rows you actually processed
|
|
1094
|
+
* (positional cursor — `delivery_id` is opaque, never compare it
|
|
1095
|
+
* numerically). `after` pages forward without committing anything: pass
|
|
1096
|
+
* the last `delivery_id` of the previous batch.
|
|
1097
|
+
*
|
|
1055
1098
|
* The WebSocket client drives this automatically on reconnect; most
|
|
1056
1099
|
* callers never need it directly.
|
|
1057
1100
|
*/
|
|
1058
1101
|
sync(opts?: {
|
|
1059
1102
|
limit?: number;
|
|
1060
|
-
after?:
|
|
1061
|
-
} & CallOptions): Promise<
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1103
|
+
after?: string;
|
|
1104
|
+
} & CallOptions): Promise<SyncEnvelope[]>;
|
|
1105
|
+
/**
|
|
1106
|
+
* Commit every delivery at-or-before the cursor as delivered.
|
|
1107
|
+
* `lastDeliveryId` is the opaque string cursor from a `sync()` row.
|
|
1108
|
+
* Returns the number of envelopes that transitioned to `delivered`
|
|
1109
|
+
* (0 is a normal outcome — e.g. a repeated ack, or an ack while the
|
|
1110
|
+
* agent is owner-paused).
|
|
1111
|
+
*/
|
|
1112
|
+
syncAck(lastDeliveryId: string, opts?: CallOptions): Promise<{
|
|
1113
|
+
acked: number;
|
|
1069
1114
|
}>;
|
|
1070
1115
|
}
|
|
1071
1116
|
|
|
1072
|
-
|
|
1117
|
+
/**
|
|
1118
|
+
* Handlers may be async. For `message.new`, completion matters: when the
|
|
1119
|
+
* server negotiated delivery acks, the ack is sent only after every handler
|
|
1120
|
+
* settled without throwing — a rejected handler leaves the message unacked
|
|
1121
|
+
* so the server re-offers it (at-least-once; the dedup cache absorbs the
|
|
1122
|
+
* eventual duplicate of anything that DID succeed).
|
|
1123
|
+
*/
|
|
1124
|
+
type MessageHandler = (message: WsMessage) => void | Promise<void>;
|
|
1073
1125
|
type ErrorHandler = (error: Error) => void;
|
|
1074
1126
|
/**
|
|
1075
1127
|
* Fired once per successful HELLO_ACK. Useful for updating UI ("connected"
|
|
@@ -1139,6 +1191,14 @@ interface RealtimeOptions {
|
|
|
1139
1191
|
* sync on your own schedule.
|
|
1140
1192
|
*/
|
|
1141
1193
|
autoDrainOnConnect?: boolean;
|
|
1194
|
+
/**
|
|
1195
|
+
* Capacity of the bounded LRU cache of recently-dispatched message ids,
|
|
1196
|
+
* shared by the live WebSocket path and the offline drain. Delivery is
|
|
1197
|
+
* at-least-once — the same message legitimately arrives twice after a
|
|
1198
|
+
* lost ack or a drain/live overlap — and the cache suppresses the
|
|
1199
|
+
* duplicate dispatch while still acknowledging receipt. Default: 2048.
|
|
1200
|
+
*/
|
|
1201
|
+
dedupCacheSize?: number;
|
|
1142
1202
|
/**
|
|
1143
1203
|
* Override the WebSocket constructor. Defaults to `globalThis.WebSocket`
|
|
1144
1204
|
* with a dynamic-import fallback to the `ws` package (for Node 20).
|
|
@@ -1160,6 +1220,12 @@ declare class RealtimeClient {
|
|
|
1160
1220
|
private reconnectTimer;
|
|
1161
1221
|
private helloAckTimer;
|
|
1162
1222
|
private authenticated;
|
|
1223
|
+
private ackMode;
|
|
1224
|
+
private helloTimeoutClose;
|
|
1225
|
+
private dedupSeen;
|
|
1226
|
+
private restDrainOrigin;
|
|
1227
|
+
private drainSettlements;
|
|
1228
|
+
private drainInFlight;
|
|
1163
1229
|
private orderStates;
|
|
1164
1230
|
private disposed;
|
|
1165
1231
|
constructor(options: RealtimeOptions);
|
|
@@ -1175,17 +1241,40 @@ declare class RealtimeClient {
|
|
|
1175
1241
|
connect(): Promise<void>;
|
|
1176
1242
|
/**
|
|
1177
1243
|
* Drain offline envelopes accumulated while the socket was disconnected.
|
|
1178
|
-
*
|
|
1179
|
-
* `
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1244
|
+
* Automatically invoked on every successful `hello.ok` when
|
|
1245
|
+
* `autoDrainOnConnect` is enabled and a client is configured.
|
|
1246
|
+
*
|
|
1247
|
+
* `GET /v1/messages/sync` returns a **bare array** of rows, oldest first
|
|
1248
|
+
* (see `SyncEnvelope`). Each page is dispatched through the same ordered
|
|
1249
|
+
* `message.new` pipeline as live frames, then acknowledged via
|
|
1250
|
+
* `POST /v1/messages/sync/ack` with a **positional** cursor — the last
|
|
1251
|
+
* non-null `delivery_id` of the fully-processed prefix. `delivery_id` is
|
|
1252
|
+
* an opaque string and is never compared numerically. Pages are fetched
|
|
1253
|
+
* with the `after` read cursor (non-committing) until a short page.
|
|
1254
|
+
*
|
|
1255
|
+
* Correctness rules, in cursor order:
|
|
1256
|
+
* - A row failing minimal validation stops the drain: the clean prefix
|
|
1257
|
+
* before it is processed and acked; the cursor never crosses the row.
|
|
1258
|
+
* - A row whose handler threw is not acked — nor is anything after it
|
|
1259
|
+
* (the ack cursor is at-or-before) — so the server re-offers it; the
|
|
1260
|
+
* dedup cache suppresses re-dispatch of its acked predecessors.
|
|
1261
|
+
* - A row parked in the out-of-order buffer (awaiting seq gap-fill) is
|
|
1262
|
+
* not acked until actually dispatched: acks FREEZE at the last settled
|
|
1263
|
+
* row for the remainder of the drain. Without this, a disconnect that
|
|
1264
|
+
* clears the ordering buffers (`resetOrderStates`) would silently drop
|
|
1265
|
+
* an already-acked message — acked-but-undispatched is exactly the
|
|
1266
|
+
* loss the ack protocol exists to prevent. Reading continues so the
|
|
1267
|
+
* in-session gap-fill still resolves; the frozen tail is re-offered on
|
|
1268
|
+
* the next drain and absorbed by the dedup cache.
|
|
1182
1269
|
*
|
|
1183
|
-
*
|
|
1184
|
-
* only moves forward, so
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1270
|
+
* Concurrent calls are coalesced (the second returns immediately). The
|
|
1271
|
+
* server-side ack pointer only moves forward, so re-running after a
|
|
1272
|
+
* partial drain is always safe. REST-drained rows are acked via this
|
|
1273
|
+
* cursor, never via WS ack frames.
|
|
1187
1274
|
*/
|
|
1188
1275
|
drainOfflineEnvelopes(): Promise<void>;
|
|
1276
|
+
private runDrain;
|
|
1277
|
+
private isBufferedInOrderState;
|
|
1189
1278
|
private scheduleReconnect;
|
|
1190
1279
|
private computeReconnectDelay;
|
|
1191
1280
|
on(event: string, handler: MessageHandler): () => void;
|
|
@@ -1222,6 +1311,35 @@ declare class RealtimeClient {
|
|
|
1222
1311
|
disconnect(): void;
|
|
1223
1312
|
private emitError;
|
|
1224
1313
|
private dispatch;
|
|
1314
|
+
/**
|
|
1315
|
+
* Dedup + dispatch + acknowledge one `message.new` envelope. Never
|
|
1316
|
+
* rejects.
|
|
1317
|
+
*
|
|
1318
|
+
* Resolves `true` when the envelope is safe to acknowledge: every
|
|
1319
|
+
* handler settled without throwing (async handlers awaited), or the
|
|
1320
|
+
* message id was already in the dedup cache — prior successful
|
|
1321
|
+
* processing is the proof, so a duplicate skips dispatch but is still
|
|
1322
|
+
* acked. Resolves `false` when any handler threw or rejected: the
|
|
1323
|
+
* message is NOT acked on any path and the server re-offers it.
|
|
1324
|
+
*
|
|
1325
|
+
* Ack routing: live frames (including server-pushed reconnect backlog
|
|
1326
|
+
* and gap-fill rows) send a WS `{type:'ack'}` frame when ack-mode was
|
|
1327
|
+
* negotiated; REST-drain rows are covered by the drain's sync/ack
|
|
1328
|
+
* cursor instead — the drain awaits this settlement before advancing
|
|
1329
|
+
* that cursor.
|
|
1330
|
+
*/
|
|
1331
|
+
private dispatchMessageNew;
|
|
1332
|
+
/**
|
|
1333
|
+
* Best-effort delivery ack for one processed message. No-op unless the
|
|
1334
|
+
* server negotiated ack-mode on this connection. Send failures are
|
|
1335
|
+
* swallowed by design: a dying socket leaves the envelope `stored`
|
|
1336
|
+
* server-side, the next drain re-offers it, and the dedup cache absorbs
|
|
1337
|
+
* the duplicate.
|
|
1338
|
+
*/
|
|
1339
|
+
private sendAckFrame;
|
|
1340
|
+
private dedupHit;
|
|
1341
|
+
private dedupAdd;
|
|
1342
|
+
private extractMessageId;
|
|
1225
1343
|
private isMessageNew;
|
|
1226
1344
|
private processOrderedMessage;
|
|
1227
1345
|
private handleGapTimer;
|
|
@@ -1439,4 +1557,4 @@ declare function parseRetryAfter(raw: string | null | undefined): number | null;
|
|
|
1439
1557
|
|
|
1440
1558
|
declare const VERSION: string;
|
|
1441
1559
|
|
|
1442
|
-
export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, 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 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, 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, verifyWebhook };
|
|
1560
|
+
export { ALLOWED_ATTACHMENT_MIME, type AddContactRequest, type AddMemberRequest, type AddMemberResult, type Agent, AgentChatClient, 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 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, verifyWebhook };
|