From 86a58258ac6571f97301dc33f1422f975ece4342 Mon Sep 17 00:00:00 2001 From: haikdc Date: Sat, 18 Apr 2026 03:05:44 -0700 Subject: [PATCH] [Haik]: refactor agents extra reducers to use backend-bridge thunks and fix return types for update_system_prompt, delete_session, stop_agent, switch_branch, and close_session --- .../src/shared/backend-bridge/apps/agents.ts | 32 ++-- .../src/shared/state/agentsExtraReducers.ts | 178 ++++++++++-------- 2 files changed, 116 insertions(+), 94 deletions(-) diff --git a/frontend/src/shared/backend-bridge/apps/agents.ts b/frontend/src/shared/backend-bridge/apps/agents.ts index cec28dc1..5699a503 100644 --- a/frontend/src/shared/backend-bridge/apps/agents.ts +++ b/frontend/src/shared/backend-bridge/apps/agents.ts @@ -76,14 +76,14 @@ const update_system_prompt_endpoint: string = `${AGENTS_API}/update_system_promp async function update_system_prompt_function(payload: { sessionId: string; systemPrompt: string; -}): Promise { +}): Promise<{ sessionId: string; systemPrompt: string }> { const res = await fetch(update_system_prompt_endpoint, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_id: payload.sessionId, system_prompt: payload.systemPrompt }), }); - const data = await res.json(); - return data.ok as string; + await res.json(); + return { sessionId: payload.sessionId, systemPrompt: payload.systemPrompt }; } export const UPDATE_SYSTEM_PROMPT = createAsyncThunk( update_system_prompt_endpoint, @@ -93,14 +93,14 @@ export const UPDATE_SYSTEM_PROMPT = createAsyncThunk( const delete_session_endpoint: string = `${AGENTS_API}/delete_session`; -async function delete_session_function(sessionId: string): Promise<{ ok: boolean }> { +async function delete_session_function(sessionId: string): Promise { const res = await fetch(delete_session_endpoint, { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_id: sessionId }), }); - const data = await res.json(); - return data as { ok: boolean }; + await res.json(); + return sessionId; } export const DELETE_SESSION = createAsyncThunk( delete_session_endpoint, @@ -155,14 +155,14 @@ export const SEND_MESSAGE = createAsyncThunk( const stop_agent_endpoint: string = `${AGENTS_API}/stop_agent`; -async function stop_agent_function(sessionId: string): Promise<{ ok: boolean }> { +async function stop_agent_function(sessionId: string): Promise { const res = await fetch(stop_agent_endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_id: sessionId }), }); - const data = await res.json(); - return data as { ok: boolean }; + await res.json(); + return sessionId; } export const STOP_AGENT = createAsyncThunk( stop_agent_endpoint, @@ -233,14 +233,14 @@ const switch_branch_endpoint: string = `${AGENTS_API}/switch_branch`; async function switch_branch_function(payload: { sessionId: string; branchId: string; -}): Promise<{ ok: boolean }> { +}): Promise<{ sessionId: string; branchId: string }> { const res = await fetch(switch_branch_endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_id: payload.sessionId, branch_id: payload.branchId }), }); - const data = await res.json(); - return data as { ok: boolean }; + await res.json(); + return { sessionId: payload.sessionId, branchId: payload.branchId }; } export const SWITCH_BRANCH = createAsyncThunk( switch_branch_endpoint, @@ -256,14 +256,14 @@ export const SWITCH_BRANCH = createAsyncThunk( const close_session_endpoint: string = `${AGENTS_API}/close_session`; -async function close_session_function(sessionId: string): Promise<{ ok: boolean }> { +async function close_session_function(sessionId: string): Promise { const res = await fetch(close_session_endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_id: sessionId }), }); - const data = await res.json(); - return data as { ok: boolean }; + await res.json(); + return sessionId; } export const CLOSE_SESSION = createAsyncThunk( close_session_endpoint, @@ -288,7 +288,7 @@ export const RESUME_SESSION = createAsyncThunk( ); - +// NOTE: is a duplicate endpoint even needed? Can't we just do this via branch? const duplicate_session_endpoint: string = `${AGENTS_API}/duplicate_session`; async function duplicate_session_function(sessionId: string): Promise<{ session: AgentSession }> { const res = await fetch(duplicate_session_endpoint, { diff --git a/frontend/src/shared/state/agentsExtraReducers.ts b/frontend/src/shared/state/agentsExtraReducers.ts index 28db89bf..d083a3e9 100644 --- a/frontend/src/shared/state/agentsExtraReducers.ts +++ b/frontend/src/shared/state/agentsExtraReducers.ts @@ -7,13 +7,29 @@ import type { AgentsState, HistorySession } from './agentsTypes'; // closeSession, deleteSession, fetchHistory, resumeSession, // fetchSession, fetchBrowserAgentChildren, searchHistory, // } from './agentsThunks'; +import { + GET_ALL_SESSIONS, + LAUNCH_AGENT, + UPDATE_SYSTEM_PROMPT, + SEND_MESSAGE, + EDIT_MESSAGE, + STOP_AGENT, + HANDLE_APPROVAL, + SWITCH_BRANCH, + DUPLICATE_SESSION, + CLOSE_SESSION, + DELETE_SESSION, + GET_HISTORY, + RESUME_SESSION, + GET_SESSION, +} from '@/shared/backend-bridge/apps/agents'; export function buildExtraReducers(builder: ActionReducerMapBuilder) { builder - .addCase(fetchSessions.pending, (state) => { + .addCase(GET_ALL_SESSIONS.pending, (state) => { state.loading = true; }) - .addCase(fetchSessions.fulfilled, (state, action) => { + .addCase(GET_ALL_SESSIONS.fulfilled, (state, action) => { state.loading = false; const fetchedIds = new Set(action.payload.map((s) => s.id)); const activeStatuses = new Set(['running', 'waiting_approval']); @@ -39,61 +55,65 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder } } }) - .addCase(fetchSessions.rejected, (state) => { + .addCase(GET_ALL_SESSIONS.rejected, (state) => { state.loading = false; }) - .addCase(launchAgent.fulfilled, (state, action) => { - state.sessions[action.payload.id] = { ...action.payload, streamingMessage: null, tool_group_meta: action.payload.tool_group_meta ?? {} }; - state.activeSessionId = action.payload.id; - if (!state.expandedSessionIds.includes(action.payload.id)) { - state.expandedSessionIds.push(action.payload.id); - } - if (!state.trackedNotificationIds.includes(action.payload.id)) { - state.trackedNotificationIds.push(action.payload.id); - } - }) - .addCase(launchAndSendFirstMessage.fulfilled, (state, action) => { - const { draftId, session } = action.payload; - const shouldExpand = action.meta.arg.expand !== false; - delete state.sessions[draftId]; + .addCase(LAUNCH_AGENT.fulfilled, (state, action) => { + const session = action.payload.session; state.sessions[session.id] = { ...session, streamingMessage: null, tool_group_meta: session.tool_group_meta ?? {} }; state.activeSessionId = session.id; - state.expandedSessionIds = state.expandedSessionIds.map((id) => (id === draftId ? session.id : id)); - if (shouldExpand && !state.expandedSessionIds.includes(session.id)) { + if (!state.expandedSessionIds.includes(session.id)) { state.expandedSessionIds.push(session.id); } if (!state.trackedNotificationIds.includes(session.id)) { state.trackedNotificationIds.push(session.id); } }) - .addCase(generateTitle.fulfilled, (state, action) => { - const session = state.sessions[action.payload.sessionId]; - if (session) session.name = action.payload.title; - }) - .addCase(generateGroupMeta.fulfilled, (state, action) => { - const session = state.sessions[action.payload.sessionId]; - if (session) { - session.tool_group_meta[action.payload.groupId] = { - id: action.payload.groupId, - name: action.payload.name, - svg: action.payload.svg, - is_refined: action.payload.isRefined, - }; - } - }) - .addCase(updateSystemPrompt.fulfilled, (state, action) => { + // TODO: Re-implement this??? + // .addCase(launchAndSendFirstMessage.fulfilled, (state, action) => { + // const { draftId, session } = action.payload; + // const shouldExpand = action.meta.arg.expand !== false; + // delete state.sessions[draftId]; + // state.sessions[session.id] = { ...session, streamingMessage: null, tool_group_meta: session.tool_group_meta ?? {} }; + // state.activeSessionId = session.id; + // state.expandedSessionIds = state.expandedSessionIds.map((id) => (id === draftId ? session.id : id)); + // if (shouldExpand && !state.expandedSessionIds.includes(session.id)) { + // state.expandedSessionIds.push(session.id); + // } + // if (!state.trackedNotificationIds.includes(session.id)) { + // state.trackedNotificationIds.push(session.id); + // } + // }) + // TODO: Re-implement this??? + // .addCase(generateTitle.fulfilled, (state, action) => { + // const session = state.sessions[action.payload.sessionId]; + // if (session) session.name = action.payload.title; + // }) + // TODO: Re-implement this??? + // .addCase(generateGroupMeta.fulfilled, (state, action) => { + // const session = state.sessions[action.payload.sessionId]; + // if (session) { + // session.tool_group_meta[action.payload.groupId] = { + // id: action.payload.groupId, + // name: action.payload.name, + // svg: action.payload.svg, + // is_refined: action.payload.isRefined, + // }; + // } + // }) + .addCase(UPDATE_SYSTEM_PROMPT.fulfilled, (state, action) => { const session = state.sessions[action.payload.sessionId]; if (session) session.system_prompt = action.payload.systemPrompt; }) - .addCase(sendMessage.pending, (state, action) => { + .addCase(SEND_MESSAGE.pending, (state, action) => { const session = state.sessions[action.meta.arg.sessionId]; if (session) session.status = 'running'; }) - .addCase(editMessage.pending, (state, action) => { + .addCase(EDIT_MESSAGE.pending, (state, action) => { const session = state.sessions[action.meta.arg.sessionId]; if (session) session.status = 'running'; }) - .addCase(stopAgent.fulfilled, (state, action) => { + .addCase(STOP_AGENT.fulfilled, (state, action) => { const session = state.sessions[action.payload]; if (session) { session.status = 'stopped'; @@ -101,24 +121,25 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder session.pending_approvals = []; } }) - .addCase(handleApproval.fulfilled, (state, action) => { + .addCase(HANDLE_APPROVAL.fulfilled, (state, action) => { for (const session of Object.values(state.sessions)) { session.pending_approvals = session.pending_approvals.filter( (r) => r.id !== action.payload.requestId ); } }) - .addCase(handleApproval.rejected, (_state, action) => { + .addCase(HANDLE_APPROVAL.rejected, (_state, action) => { console.error('Approval request failed:', action.error.message); }) - .addCase(switchBranch.fulfilled, (state, action) => { + .addCase(SWITCH_BRANCH.fulfilled, (state, action) => { const session = state.sessions[action.payload.sessionId]; if (session) session.active_branch_id = action.payload.branchId; }) - .addCase(duplicateSession.fulfilled, (state, action) => { - state.sessions[action.payload.id] = action.payload; + .addCase(DUPLICATE_SESSION.fulfilled, (state, action) => { + const session = action.payload.session; + state.sessions[session.id] = session; }) - .addCase(closeSession.fulfilled, (state, action) => { + .addCase(CLOSE_SESSION.fulfilled, (state, action) => { const sessionId = action.payload; const session = state.sessions[sessionId]; if (session) { @@ -134,8 +155,8 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder state.expandedSessionIds = state.expandedSessionIds.filter((id) => id !== sessionId); state.trackedNotificationIds = state.trackedNotificationIds.filter((id) => id !== sessionId); }) - .addCase(closeSession.rejected, (state, action) => { - const sessionId = action.meta.arg.sessionId; + .addCase(CLOSE_SESSION.rejected, (state, action) => { + const sessionId = action.meta.arg; const session = state.sessions[sessionId]; if (session) { state.history[sessionId] = { @@ -150,7 +171,7 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder state.expandedSessionIds = state.expandedSessionIds.filter((id) => id !== sessionId); state.trackedNotificationIds = state.trackedNotificationIds.filter((id) => id !== sessionId); }) - .addCase(deleteSession.fulfilled, (state, action) => { + .addCase(DELETE_SESSION.fulfilled, (state, action) => { const sessionId = action.payload; delete state.history[sessionId]; delete state.sessions[sessionId]; @@ -158,19 +179,19 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder state.expandedSessionIds = state.expandedSessionIds.filter((id) => id !== sessionId); state.trackedNotificationIds = state.trackedNotificationIds.filter((id) => id !== sessionId); }) - .addCase(fetchHistory.fulfilled, (state, action) => { + .addCase(GET_HISTORY.fulfilled, (state, action) => { const history: Record = {}; - for (const s of action.payload) history[s.id] = s; + for (const s of action.payload.sessions) history[s.id] = s; state.history = history; }) - .addCase(resumeSession.fulfilled, (state, action) => { + .addCase(RESUME_SESSION.fulfilled, (state, action) => { const session = action.payload; state.sessions[session.id] = { ...session, streamingMessage: null, tool_group_meta: session.tool_group_meta ?? {} }; delete state.history[session.id]; state.activeSessionId = session.id; if (!state.expandedSessionIds.includes(session.id)) state.expandedSessionIds.push(session.id); }) - .addCase(fetchSession.fulfilled, (state, action) => { + .addCase(GET_SESSION.fulfilled, (state, action) => { const session = action.payload; const existing = state.sessions[session.id]; state.sessions[session.id] = { @@ -180,31 +201,32 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder tool_group_meta: session.tool_group_meta ?? existing?.tool_group_meta ?? {}, }; }) - .addCase(fetchBrowserAgentChildren.fulfilled, (state, action) => { - for (const session of action.payload) { - if (!state.sessions[session.id]) { - state.sessions[session.id] = { - ...session, streamingMessage: null, tool_group_meta: session.tool_group_meta ?? {}, - }; - } - } - }) - .addCase(searchHistory.pending, (state) => { - state.historySearch.loading = true; - }) - .addCase(searchHistory.fulfilled, (state, action) => { - const { sessions, total, hasMore, query, offset } = action.payload; - if (offset === 0) { - state.historySearch.results = sessions; - } else { - state.historySearch.results = [...state.historySearch.results, ...sessions]; - } - state.historySearch.total = total; - state.historySearch.hasMore = hasMore; - state.historySearch.query = query; - state.historySearch.loading = false; - }) - .addCase(searchHistory.rejected, (state) => { - state.historySearch.loading = false; - }); + // TODO: Re-implement this??? + // .addCase(fetchBrowserAgentChildren.fulfilled, (state, action) => { + // for (const session of action.payload) { + // if (!state.sessions[session.id]) { + // state.sessions[session.id] = { + // ...session, streamingMessage: null, tool_group_meta: session.tool_group_meta ?? {}, + // }; + // } + // } + // }) + // .addCase(searchHistory.pending, (state) => { + // state.historySearch.loading = true; + // }) + // .addCase(searchHistory.fulfilled, (state, action) => { + // const { sessions, total, hasMore, query, offset } = action.payload; + // if (offset === 0) { + // state.historySearch.results = sessions; + // } else { + // state.historySearch.results = [...state.historySearch.results, ...sessions]; + // } + // state.historySearch.total = total; + // state.historySearch.hasMore = hasMore; + // state.historySearch.query = query; + // state.historySearch.loading = false; + // }) + // .addCase(searchHistory.rejected, (state) => { + // state.historySearch.loading = false; + // }); }