@canonmsg/agent-sdk 3.2.2 → 3.2.4
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/canon-agent.js +7 -5
- package/dist/realtime.d.ts +2 -0
- package/dist/realtime.js +12 -3
- package/package.json +2 -2
package/dist/canon-agent.js
CHANGED
|
@@ -910,9 +910,10 @@ export class CanonAgent {
|
|
|
910
910
|
}
|
|
911
911
|
async handleRuntimePrimitiveEvent(event) {
|
|
912
912
|
// Requests only belong to this runtime once primitive handlers exist —
|
|
913
|
-
//
|
|
913
|
+
// defer otherwise: the request stays in RTDB AND unseen, so a handler
|
|
914
|
+
// registered via onPrimitive() after start still receives it.
|
|
914
915
|
if (!this.hasRuntimePrimitiveSupport())
|
|
915
|
-
return {
|
|
916
|
+
return { defer: true };
|
|
916
917
|
const { conversationId, requestId, value } = event;
|
|
917
918
|
const primitive = value.id;
|
|
918
919
|
// Unknown primitives and unhandled ids fall through so the poller
|
|
@@ -935,10 +936,11 @@ export class CanonAgent {
|
|
|
935
936
|
});
|
|
936
937
|
}
|
|
937
938
|
async handleRuntimeSignalEvent(event) {
|
|
938
|
-
// Signals only belong to this runtime once signal handlers exist —
|
|
939
|
-
//
|
|
939
|
+
// Signals only belong to this runtime once signal handlers exist — defer
|
|
940
|
+
// otherwise: the signal stays in RTDB AND unseen, so a handler registered
|
|
941
|
+
// via on('interrupt' | ...) after start still receives it.
|
|
940
942
|
if (!this.hasRuntimeSignalSupport())
|
|
941
|
-
return {
|
|
943
|
+
return { defer: true };
|
|
942
944
|
const { conversationId, type: signal, updatedAt } = event;
|
|
943
945
|
const handler = signal === 'new_session'
|
|
944
946
|
? this.newSessionHandler
|
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
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/agent-sdk",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.4",
|
|
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.
|
|
31
|
+
"@canonmsg/core": "^2.6.0"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|