Message Queue
The Message Queue feature provides automatic message buffering when the connection is unavailable. Messages are queued locally and automatically sent when the connection is restored.
Overview
When you call agent.send() while disconnected:
- The message is added to an internal queue
- The SDK continues without throwing an error
- When connection is restored, queued messages are sent automatically
- A
queueFlushedevent is emitted with the count of sent messages
This provides a seamless experience for users even with intermittent connectivity.
Quick Start
Message queuing works automatically:
typescript
import { AiAgent } from "@egain/ai-agent-sdk";
const agent = new AiAgent({
id: "agent-id",
endpoint: "https://your-endpoint.com"
});
await agent.initialize();
// This works even if disconnected!
await agent.send("Hello!"); // Queued if offline
// Check queue status
const queueSize = agent.getQueueSize();
console.log(`${queueSize} messages waiting`);
// Clear the queue if needed
agent.clearQueue();1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Configuration
Configure queue behavior when creating the agent:
typescript
const agent = new AiAgent({
id: "agent-id",
endpoint: "https://your-endpoint.com",
maxQueueSize: 1000 // Maximum messages to queue (default: 1000)
});1
2
3
4
5
2
3
4
5
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
maxQueueSize | number | 1000 | Maximum number of messages to queue |
Queue Events
Listen for queue-related events:
typescript
// When queued messages are sent after reconnection
agent.on("queueFlushed", (event) => {
console.log(`Sent ${event.payload.count} queued messages`);
});
// When connection state changes
agent.on("stateChanged", (event) => {
const { state, previousState } = event.payload;
if (state === "RECONNECTING") {
console.log("Reconnecting... messages will be queued");
}
if (state === "CONNECTED" && previousState === "RECONNECTING") {
console.log("Reconnected! Queued messages will be sent");
}
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Queue Methods
Check Queue Size
typescript
const size = agent.getQueueSize();
console.log(`${size} messages in queue`);1
2
2
Clear Queue
typescript
// Remove all queued messages
agent.clearQueue();1
2
2
How It Works
Normal Flow (Connected)
User sends message → SDK sends immediately → Server receives1
Offline Flow
User sends message → SDK queues locally → Connection restored → SDK sends queued messages1
Automatic Flush
When the connection is established (or re-established), the SDK automatically:
- Checks for queued messages
- Sends them in order (FIFO)
- Emits
queueFlushedevent with count
typescript
agent.on("connected", () => {
// Queue is automatically flushed after this
});
agent.on("queueFlushed", (event) => {
console.log(`${event.payload.count} queued messages sent`);
});1
2
3
4
5
6
7
2
3
4
5
6
7
Retry Behavior
The queue includes automatic retry logic:
| Behavior | Description |
|---|---|
| Max Attempts | Each message is retried up to 3 times |
| Failure Handling | Failed messages are removed after max attempts |
| Error Events | An error event is emitted for failed messages |
typescript
agent.on("error", (event) => {
// Handle permanently failed messages
console.error("Message failed:", event.payload.error);
});1
2
3
4
2
3
4
UI Integration
Show Queue Status
typescript
function updateQueueIndicator() {
const size = agent.getQueueSize();
if (size > 0) {
showBadge(`${size} pending`);
} else {
hideBadge();
}
}
// Update on state changes
agent.on("stateChanged", updateQueueIndicator);
agent.on("queueFlushed", updateQueueIndicator);1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
React Example
tsx
function ConnectionStatus() {
const [queueSize, setQueueSize] = useState(0);
const [isConnected, setIsConnected] = useState(false);
useEffect(() => {
const updateStatus = () => {
setQueueSize(agent.getQueueSize());
setIsConnected(agent.isConnected());
};
agent.on("stateChanged", updateStatus);
agent.on("queueFlushed", updateStatus);
return () => {
agent.off("stateChanged", updateStatus);
agent.off("queueFlushed", updateStatus);
};
}, []);
return (
<div className="status">
{isConnected ? (
<span className="online">● Connected</span>
) : (
<span className="offline">
○ Offline
{queueSize > 0 && ` (${queueSize} pending)`}
</span>
)}
</div>
);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Vue Example
vue
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const queueSize = ref(0);
const isConnected = ref(false);
function updateStatus() {
queueSize.value = agent.getQueueSize();
isConnected.value = agent.isConnected();
}
onMounted(() => {
agent.on('stateChanged', updateStatus);
agent.on('queueFlushed', updateStatus);
updateStatus();
});
onUnmounted(() => {
agent.off('stateChanged', updateStatus);
agent.off('queueFlushed', updateStatus);
});
</script>
<template>
<div class="status">
<span v-if="isConnected" class="online">● Connected</span>
<span v-else class="offline">
○ Offline
<template v-if="queueSize > 0">({{ queueSize }} pending)</template>
</span>
</div>
</template>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Handling Offline State
Optimistic UI Updates
Show messages immediately in the UI, even when queued:
typescript
async function sendMessage(text: string) {
// Add to UI immediately (optimistic)
addMessageToUI({
text,
status: agent.isConnected() ? "sent" : "pending"
});
// Send (queued if offline)
const messageId = await agent.send(text);
return messageId;
}
// Update status when flushed
agent.on("queueFlushed", () => {
updatePendingMessagesStatus("sent");
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Show Pending Indicator
typescript
function sendMessage(text: string) {
const message = {
id: Date.now().toString(),
text,
status: "sending"
};
addMessageToUI(message);
agent.send(text).then(() => {
if (agent.isConnected()) {
updateMessageStatus(message.id, "sent");
} else {
updateMessageStatus(message.id, "queued");
}
});
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Queue Limits
Max Queue Size
When the queue is full, send() will throw an error:
typescript
try {
await agent.send("Message");
} catch (error) {
if (error.message.includes("Queue is full")) {
alert("Too many pending messages. Please wait for connection.");
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
Handling Queue Full
typescript
async function safeSend(text: string) {
const queueSize = agent.getQueueSize();
const maxSize = 1000; // Your configured max
if (queueSize >= maxSize * 0.9) {
showWarning("Message queue is almost full");
}
if (queueSize >= maxSize) {
showError("Cannot send: too many pending messages");
return null;
}
return await agent.send(text);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Best Practices
1. Show Queue Status to Users
typescript
agent.on("stateChanged", (event) => {
if (event.payload.state === "RECONNECTING") {
showToast("Reconnecting... messages will be sent when online");
}
});1
2
3
4
5
2
3
4
5
2. Handle Queue Full Gracefully
typescript
const MAX_QUEUE_WARNING = 900;
if (agent.getQueueSize() > MAX_QUEUE_WARNING) {
disableSendButton();
showWarning("Please wait for connection to restore");
}1
2
3
4
5
6
2
3
4
5
6
3. Clear Queue on Logout
typescript
function logout() {
agent.clearQueue(); // Don't send pending messages
agent.disconnect();
}1
2
3
4
2
3
4
4. Don't Clear Queue on Reconnect
The queue auto-flushes on reconnect. Don't clear it manually unless intentional:
typescript
// ❌ Don't do this
agent.on("connected", () => {
agent.clearQueue(); // This loses messages!
});
// ✅ Let it auto-flush
agent.on("queueFlushed", (event) => {
console.log(`Sent ${event.payload.count} pending messages`);
});1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9