@canonmsg/agent-sdk 3.2.3 → 3.2.5
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/realtime.d.ts +2 -0
- package/dist/realtime.js +19 -4
- package/package.json +2 -2
package/dist/realtime.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export declare class RealtimeManager {
|
|
|
19
19
|
/** Lower bound for catch-up in conversations with no in-memory cursor. */
|
|
20
20
|
private readonly replaySyncStartedAt;
|
|
21
21
|
private replayCatchupInFlight;
|
|
22
|
+
private hasConnectedOnce;
|
|
22
23
|
private lastSseErrorKey;
|
|
23
24
|
private lastSseErrorAt;
|
|
24
25
|
private suppressedSseErrorCount;
|
|
@@ -33,6 +34,7 @@ export declare class RealtimeManager {
|
|
|
33
34
|
private onConnected;
|
|
34
35
|
private onDisconnected;
|
|
35
36
|
constructor(apiKey: string, debouncer: Debouncer, agentId: string, streamUrl?: string, apiClient?: CanonClient);
|
|
37
|
+
private queueReplayCatchup;
|
|
36
38
|
private hasSeenInboundMessage;
|
|
37
39
|
private recordSeenInboundMessage;
|
|
38
40
|
private pruneRecentInboundMessageIds;
|
package/dist/realtime.js
CHANGED
|
@@ -34,6 +34,7 @@ export class RealtimeManager {
|
|
|
34
34
|
/** Lower bound for catch-up in conversations with no in-memory cursor. */
|
|
35
35
|
replaySyncStartedAt = Date.now();
|
|
36
36
|
replayCatchupInFlight = null;
|
|
37
|
+
hasConnectedOnce = false;
|
|
37
38
|
lastSseErrorKey = null;
|
|
38
39
|
lastSseErrorAt = 0;
|
|
39
40
|
suppressedSseErrorCount = 0;
|
|
@@ -122,16 +123,19 @@ export class RealtimeManager {
|
|
|
122
123
|
},
|
|
123
124
|
onConnected: () => {
|
|
124
125
|
// Reset backoff is handled internally by CanonStream
|
|
126
|
+
const shouldCatchUp = this.hasConnectedOnce;
|
|
127
|
+
this.hasConnectedOnce = true;
|
|
125
128
|
this.onConnected?.();
|
|
129
|
+
if (shouldCatchUp) {
|
|
130
|
+
this.queueReplayCatchup();
|
|
131
|
+
}
|
|
126
132
|
},
|
|
127
133
|
onDisconnected: () => {
|
|
128
134
|
this.onDisconnected?.();
|
|
129
135
|
},
|
|
130
136
|
onReplayExpired: (payload) => {
|
|
131
137
|
console.error(`[canon-sdk] SSE replay window expired${payload.lastAvailableId ? ` (oldest available event: ${payload.lastAvailableId})` : ''} — catching up over REST`);
|
|
132
|
-
this.
|
|
133
|
-
this.replayCatchupInFlight = null;
|
|
134
|
-
});
|
|
138
|
+
this.queueReplayCatchup();
|
|
135
139
|
},
|
|
136
140
|
onError: (err) => {
|
|
137
141
|
this.logSseError(err);
|
|
@@ -139,6 +143,11 @@ export class RealtimeManager {
|
|
|
139
143
|
},
|
|
140
144
|
});
|
|
141
145
|
}
|
|
146
|
+
queueReplayCatchup() {
|
|
147
|
+
this.replayCatchupInFlight ??= this.runReplayCatchup().finally(() => {
|
|
148
|
+
this.replayCatchupInFlight = null;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
142
151
|
hasSeenInboundMessage(conversationId, messageId) {
|
|
143
152
|
return this.recentInboundMessageIds.has(`${conversationId}:${messageId}`);
|
|
144
153
|
}
|
|
@@ -202,7 +211,13 @@ export class RealtimeManager {
|
|
|
202
211
|
if (message.senderId === this.agentId)
|
|
203
212
|
continue;
|
|
204
213
|
const createdAtMs = messageCreatedAtMs(message.createdAt);
|
|
205
|
-
|
|
214
|
+
// Use a strict lower bound of `< lowerBoundMs` (not `<=`): a
|
|
215
|
+
// gap-dropped message can share the same createdAt millisecond as
|
|
216
|
+
// the last message seen over SSE (server timestamps collide under
|
|
217
|
+
// bursts — exactly the scenario catch-up targets). The id-dedupe on
|
|
218
|
+
// the next line suppresses the already-delivered boundary message,
|
|
219
|
+
// so excluding by `<=` would only drop never-seen same-ms peers.
|
|
220
|
+
if (!createdAtMs || createdAtMs < lowerBoundMs)
|
|
206
221
|
continue;
|
|
207
222
|
if (this.hasSeenInboundMessage(conversation.id, message.id))
|
|
208
223
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/agent-sdk",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.5",
|
|
4
4
|
"description": "Canon Agent SDK — build AI agents that participate in Canon conversations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=18.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@canonmsg/core": "^2.6.
|
|
31
|
+
"@canonmsg/core": "^2.6.2"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|