fix: eliminate duplicate WebSocket messages during agent history priming
- Skip dispatching individual agent_stream events when replaying history (the snapshot is sent after priming anyway, so individual events were wasted) - Add WebSocket message logging on client (type, size, id) for debugging - Change default daemon URL from dev to localhost - Clean up unused imports in session.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ const REGISTRY_STORAGE_KEY = "@paseo:daemon-registry";
|
|||||||
const LEGACY_SETTINGS_KEY = "@paseo:settings";
|
const LEGACY_SETTINGS_KEY = "@paseo:settings";
|
||||||
const FALLBACK_DAEMON_URL = "ws://localhost:6767/ws";
|
const FALLBACK_DAEMON_URL = "ws://localhost:6767/ws";
|
||||||
const DEFAULT_DAEMONS: Array<{ label: string; wsUrl: string; restUrl?: string | null }> = [
|
const DEFAULT_DAEMONS: Array<{ label: string; wsUrl: string; restUrl?: string | null }> = [
|
||||||
{ label: "dev", wsUrl: "ws://dev:6767/ws" },
|
{ label: "localhost", wsUrl: "ws://localhost:6767/ws" },
|
||||||
{ label: "macbook", wsUrl: "ws://mohameds-macbook-pro:6767/ws" },
|
{ label: "macbook", wsUrl: "ws://mohameds-macbook-pro:6767/ws" },
|
||||||
];
|
];
|
||||||
const DAEMON_REGISTRY_QUERY_KEY = ["daemon-registry"];
|
const DAEMON_REGISTRY_QUERY_KEY = ["daemon-registry"];
|
||||||
|
|||||||
@@ -123,12 +123,17 @@ export function useWebSocket(url: string, conversationId?: string | null): UseWe
|
|||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
try {
|
try {
|
||||||
const wsMessage: WSOutboundMessage = JSON.parse(event.data);
|
const rawData = event.data;
|
||||||
|
const size = typeof rawData === "string" ? rawData.length : 0;
|
||||||
|
const wsMessage: WSOutboundMessage = JSON.parse(rawData);
|
||||||
|
|
||||||
// Only session messages trigger handlers
|
// Only session messages trigger handlers
|
||||||
if (wsMessage.type === "session") {
|
if (wsMessage.type === "session") {
|
||||||
const sessionMessage = wsMessage.message;
|
const sessionMessage = wsMessage.message;
|
||||||
console.log(`[WS] Received session message type: ${sessionMessage.type}`);
|
const id = (sessionMessage as { requestId?: string }).requestId ??
|
||||||
|
(sessionMessage as { agentId?: string }).agentId ??
|
||||||
|
(sessionMessage as { payload?: { agentId?: string } }).payload?.agentId;
|
||||||
|
console.log(`[WS] ← ${sessionMessage.type}`, { size, id: id ?? "-" });
|
||||||
|
|
||||||
// Track conversation ID when loaded
|
// Track conversation ID when loaded
|
||||||
if (sessionMessage.type === "conversation_loaded") {
|
if (sessionMessage.type === "conversation_loaded") {
|
||||||
@@ -147,8 +152,8 @@ export function useWebSocket(url: string, conversationId?: string | null): UseWe
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// pong - just log
|
// pong
|
||||||
console.log(`[WS] Received ${wsMessage.type}`);
|
console.log(`[WS] ← ${wsMessage.type}`, { size });
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("[WS] Failed to parse message:", err);
|
console.error("[WS] Failed to parse message:", err);
|
||||||
@@ -200,7 +205,14 @@ export function useWebSocket(url: string, conversationId?: string | null): UseWe
|
|||||||
|
|
||||||
const send = useCallback((message: WSInboundMessage) => {
|
const send = useCallback((message: WSInboundMessage) => {
|
||||||
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
||||||
wsRef.current.send(JSON.stringify(message));
|
const payload = JSON.stringify(message);
|
||||||
|
const type = message.type === "session" ? message.message.type : message.type;
|
||||||
|
const id = message.type === "session"
|
||||||
|
? (message.message as { requestId?: string; agentId?: string }).requestId ??
|
||||||
|
(message.message as { agentId?: string }).agentId
|
||||||
|
: undefined;
|
||||||
|
console.log(`[WS] → ${type}`, { size: payload.length, id: id ?? "-" });
|
||||||
|
wsRef.current.send(payload);
|
||||||
} else {
|
} else {
|
||||||
console.warn("[WS] Cannot send message - not connected");
|
console.warn("[WS] Cannot send message - not connected");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -707,7 +707,11 @@ export class AgentManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dispatchStream(agent.id, event);
|
// Skip dispatching individual stream events during history replay.
|
||||||
|
// The caller will send a batched agent_stream_snapshot after priming.
|
||||||
|
if (!options?.fromHistory) {
|
||||||
|
this.dispatchStream(agent.id, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private recordTimeline(agent: ManagedAgent, item: AgentTimelineItem): void {
|
private recordTimeline(agent: ManagedAgent, item: AgentTimelineItem): void {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { readFile, mkdir, writeFile } from "fs/promises";
|
import { readFile, mkdir, writeFile } from "fs/promises";
|
||||||
import { exec, spawn } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { promisify, inspect } from "util";
|
import { promisify, inspect } from "util";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import invariant from "tiny-invariant";
|
import invariant from "tiny-invariant";
|
||||||
|
|||||||
Reference in New Issue
Block a user