From 1c905a114e513f37e1af6419bd4dfc8294040753 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 11 Aug 2026 19:28:35 +0200 Subject: [PATCH] Remove unused session message processing (#3231) * perf(app): remove unused session message state The legacy message accumulator had no readers but copied its full array for each activity and updated Zustand for every assistant chunk. Keep only the live voice-abort notification and voice transcription behavior. * test(app): use live session action in task subscription test --- packages/app/src/contexts/session-context.tsx | 131 +----------------- packages/app/src/stores/session-store.test.ts | 2 +- packages/app/src/stores/session-store.ts | 100 ------------- 3 files changed, 3 insertions(+), 230 deletions(-) diff --git a/packages/app/src/contexts/session-context.tsx b/packages/app/src/contexts/session-context.tsx index 76eb78521..2de5bc523 100644 --- a/packages/app/src/contexts/session-context.tsx +++ b/packages/app/src/contexts/session-context.tsx @@ -10,7 +10,7 @@ import { createSetAgentInitializing, refreshAgentInitializationTimeout, } from "@/hooks/use-agent-initialization"; -import { generateMessageId, type StreamItem } from "@/types/stream"; +import type { StreamItem } from "@/types/stream"; import { createSessionAgentStreamReducerQueue, deriveAgentStreamTurnLiveness, @@ -43,7 +43,6 @@ import type { AudioPlaybackSource } from "@/voice/audio-engine-types"; import { selectAgentTimelineState, useSessionStore, - type MessageEntry, type SessionState, } from "@/stores/session-store"; import { useWorkspaceSetupStore } from "@/stores/workspace-setup-store"; @@ -71,7 +70,6 @@ import { revalidateSessionAfterResume } from "@/contexts/session-resume-revalida // Re-export types from session-store and draft-store for backward compatibility export type { DraftInput } from "@/stores/draft-store"; export type { - MessageEntry, Agent, ExplorerEntry, ExplorerFile, @@ -275,30 +273,6 @@ function finalizeTimelineApplication(input: { } } -function applyToolResultToMessages( - toolCallId: string, - result: unknown, -): (prev: MessageEntry[]) => MessageEntry[] { - return (prev) => - prev.map((msg) => - msg.type === "tool_call" && msg.id === toolCallId - ? { ...msg, result, status: "completed" as const } - : msg, - ); -} - -function applyToolErrorToMessages( - toolCallId: string, - error: unknown, -): (prev: MessageEntry[]) => MessageEntry[] { - return (prev) => - prev.map((msg) => - msg.type === "tool_call" && msg.id === toolCallId - ? { ...msg, error, status: "failed" as const } - : msg, - ); -} - function notifyVoiceAbortFailure( data: Extract["payload"], notifyError: (message: string) => void, @@ -342,8 +316,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider // Zustand store actions const setIsPlayingAudio = useSessionStore((state) => state.setIsPlayingAudio); - const setMessages = useSessionStore((state) => state.setMessages); - const setCurrentAssistantMessage = useSessionStore((state) => state.setCurrentAssistantMessage); const setAgentStreamTail = useSessionStore((state) => state.setAgentStreamTail); const setAgentStreamHead = useSessionStore((state) => state.setAgentStreamHead); const setAgentStreamState = useSessionStore((state) => state.setAgentStreamState); @@ -935,98 +907,7 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider const unsubActivity = client.on("activity_log", (message) => { if (message.type !== "activity_log") return; - const data = message.payload; - if (data.type === "system" && data.content.includes("Transcribing")) { - return; - } - - if (data.type === "tool_call" && data.metadata) { - const toolCallId = - typeof data.metadata.toolCallId === "string" ? data.metadata.toolCallId : ""; - const toolName = typeof data.metadata.toolName === "string" ? data.metadata.toolName : ""; - const args = data.metadata.arguments; - - setMessages(serverId, (prev) => [ - ...prev, - { - type: "tool_call", - id: toolCallId, - timestamp: Date.now(), - toolName, - args, - status: "executing", - }, - ]); - return; - } - - if (data.type === "tool_result" && data.metadata) { - const toolCallId = - typeof data.metadata.toolCallId === "string" ? data.metadata.toolCallId : ""; - const result = data.metadata.result; - - const applyToolResult = applyToolResultToMessages(toolCallId, result); - setMessages(serverId, applyToolResult); - return; - } - - if (data.type === "error" && data.metadata && "toolCallId" in data.metadata) { - const toolCallId = - typeof data.metadata.toolCallId === "string" ? data.metadata.toolCallId : ""; - const error = data.metadata.error; - - const applyToolError = applyToolErrorToMessages(toolCallId, error); - setMessages(serverId, applyToolError); - } - - notifyVoiceAbortFailure(data, toast.error); - - let activityType: "system" | "info" | "success" | "error" = "info"; - if (data.type === "error") activityType = "error"; - - if (data.type === "transcript") { - setMessages(serverId, (prev) => [ - ...prev, - { - type: "user", - id: generateMessageId(), - timestamp: Date.now(), - message: data.content, - }, - ]); - return; - } - - if (data.type === "assistant") { - setMessages(serverId, (prev) => [ - ...prev, - { - type: "assistant", - id: generateMessageId(), - timestamp: Date.now(), - message: data.content, - }, - ]); - setCurrentAssistantMessage(serverId, ""); - return; - } - - setMessages(serverId, (prev) => [ - ...prev, - { - type: "activity", - id: generateMessageId(), - timestamp: Date.now(), - activityType, - message: data.content, - metadata: data.metadata, - }, - ]); - }); - - const unsubChunk = client.on("assistant_chunk", (message) => { - if (message.type !== "assistant_chunk") return; - setCurrentAssistantMessage(serverId, (prev) => prev + message.payload.chunk); + notifyVoiceAbortFailure(message.payload, toast.error); }); const unsubTranscription = client.on("transcription_result", (message) => { @@ -1034,11 +915,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider const transcriptText = message.payload.text.trim(); voiceRuntime?.onTranscriptionResult(serverId, transcriptText); - if (!transcriptText) { - return; - } - - setCurrentAssistantMessage(serverId, ""); }); const unsubVoiceInputState = client.on("voice_input_state", (message) => { @@ -1081,7 +957,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider unsubPermissionResolved(); unsubAudioOutput(); unsubActivity(); - unsubChunk(); unsubTranscription(); unsubVoiceInputState(); unsubTerminalAttention(); @@ -1092,8 +967,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider queryClient, serverId, setIsPlayingAudio, - setMessages, - setCurrentAssistantMessage, setAgentStreamTail, setAgentStreamHead, setAgentStreamState, diff --git a/packages/app/src/stores/session-store.test.ts b/packages/app/src/stores/session-store.test.ts index f8ea1a4b1..201dddaf4 100644 --- a/packages/app/src/stores/session-store.test.ts +++ b/packages/app/src/stores/session-store.test.ts @@ -97,7 +97,7 @@ describe("agent task state", () => { useSessionStore .getState() .setAgentStreamState("test-server", "agent-1", { taskSnapshot: tasks }); - useSessionStore.getState().setMessages("test-server", []); + useSessionStore.getState().setIsPlayingAudio("test-server", true); useSessionStore .getState() .setAgentStreamState("test-server", "agent-1", { taskSnapshot: [...tasks] }); diff --git a/packages/app/src/stores/session-store.ts b/packages/app/src/stores/session-store.ts index c8ca04cb2..758b02c28 100644 --- a/packages/app/src/stores/session-store.ts +++ b/packages/app/src/stores/session-store.ts @@ -62,47 +62,6 @@ import { type TurnLivenessTransition, } from "@/timeline/turn-liveness"; -// Re-export types that were in session-context -export type MessageEntry = - | { - type: "user"; - id: string; - timestamp: number; - message: string; - } - | { - type: "assistant"; - id: string; - timestamp: number; - message: string; - } - | { - type: "activity"; - id: string; - timestamp: number; - activityType: "system" | "info" | "success" | "error"; - message: string; - metadata?: Record; - } - | { - type: "artifact"; - id: string; - timestamp: number; - artifactId: string; - artifactType: string; - title: string; - } - | { - type: "tool_call"; - id: string; - timestamp: number; - toolName: string; - args: unknown; - result?: unknown; - error?: unknown; - status: "executing" | "completed" | "failed"; - }; - export interface AgentRuntimeInfo { provider: AgentProvider; sessionId: string | null; @@ -440,10 +399,6 @@ export interface SessionState { focusedAgentId: string | null; focusedTerminalId: string | null; - // Messages - messages: MessageEntry[]; - currentAssistantMessage: string; - // Stream state (head/tail model) agentStreamTail: Map; agentStreamHead: Map; @@ -515,16 +470,6 @@ interface SessionStoreActions { setFocusedAgentId: (serverId: string, agentId: string | null) => void; setFocusedTerminalId: (serverId: string, terminalId: string | null) => void; - // Messages - setMessages: ( - serverId: string, - messages: MessageEntry[] | ((prev: MessageEntry[]) => MessageEntry[]), - ) => void; - setCurrentAssistantMessage: ( - serverId: string, - message: string | ((prev: string) => string), - ) => void; - // Stream state (head/tail model) setAgentStreamTail: ( serverId: string, @@ -711,8 +656,6 @@ function createInitialSessionState( isPlayingAudio: false, focusedAgentId: null, focusedTerminalId: null, - messages: [], - currentAssistantMessage: "", agentStreamTail: new Map(), agentStreamHead: new Map(), agentTasks: new Map(), @@ -1050,49 +993,6 @@ export const useSessionStore = create()( }); }, - // Messages - setMessages: (serverId, messages) => { - set((prev) => { - const session = prev.sessions[serverId]; - if (!session) { - return prev; - } - const nextMessages = - typeof messages === "function" ? messages(session.messages) : messages; - if (session.messages === nextMessages) { - return prev; - } - return { - ...prev, - sessions: { - ...prev.sessions, - [serverId]: { ...session, messages: nextMessages }, - }, - }; - }); - }, - - setCurrentAssistantMessage: (serverId, message) => { - set((prev) => { - const session = prev.sessions[serverId]; - if (!session) { - return prev; - } - const nextMessage = - typeof message === "function" ? message(session.currentAssistantMessage) : message; - if (session.currentAssistantMessage === nextMessage) { - return prev; - } - return { - ...prev, - sessions: { - ...prev.sessions, - [serverId]: { ...session, currentAssistantMessage: nextMessage }, - }, - }; - }); - }, - // Stream state (head/tail model) setAgentStreamTail: (serverId, state) => { set((prev) => {