[Haik]: migrate launchAndSendFirstMessage and searchHistory from agentsSlice to backend-bridge thunks (META_LAUNCH_AND_SEND, GET_HISTORY); wire up new thunks in useAgentChat, useToolbarActions, useDashboardToolbar, agentsExtraReducers, and dashboardLayoutSlice; normalize backend response key from SESSIONS to sessions; remove dashboardId param from history search calls; replace any types with AgentSession, CardPosition, and AgentConfig; remove stale settingsApplied useEffect; split image payload into separate data and media_type arrays for SEND_MESSAGE

This commit is contained in:
haikdc
2026-04-18 04:04:44 -07:00
parent 1ba5f11591
commit c329c0f837
7 changed files with 148 additions and 94 deletions
@@ -1,7 +1,7 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import { API_BASE } from '@/shared/backend-bridge/base_routes';
import type {
AgentSession, HistorySession,
AgentSession, HistorySession, LaunchAndSendPayload
} from '@/shared/state/agentsTypes';
const AGENTS_API: string = `${API_BASE}/agents`;
@@ -327,4 +327,42 @@ async function get_history_function(payload: {
export const GET_HISTORY = createAsyncThunk(
get_history_endpoint,
get_history_function,
);
// ---------------------------------------------------------------------------
// Meta Functions (Not actual endpoints in the backend)
// ---------------------------------------------------------------------------
const meta_launch_and_send_endpoint: string = 'agents/meta_launch_and_send';
async function meta_launch_and_send_function(
payload: LaunchAndSendPayload,
): Promise<{ draftId: string; session: AgentSession }> {
const { session } = await launch_agent_function({
model: payload.model,
mode: payload.mode,
system_prompt: payload.config.system_prompt ?? '',
max_turns: payload.config.max_turns ?? 100,
});
await send_message_function({
sessionId: session.id,
prompt: payload.prompt,
mode: payload.mode,
model: payload.model,
images: payload.images?.map((img) => img.data),
imageMediaTypes: payload.images?.map((img) => img.media_type),
contextPaths: payload.contextPaths,
forcedTools: payload.forcedTools,
attachedSkills: payload.attachedSkills,
});
return { draftId: payload.draftId, session };
}
export const META_LAUNCH_AND_SEND = createAsyncThunk(
meta_launch_and_send_endpoint,
meta_launch_and_send_function,
);
@@ -1,12 +1,5 @@
import type { ActionReducerMapBuilder } from '@reduxjs/toolkit';
import type { AgentsState, HistorySession } from './agentsTypes';
// import {
// fetchSessions, launchAgent, launchAndSendFirstMessage, generateTitle,
// generateGroupMeta, updateSystemPrompt, sendMessage, editMessage,
// stopAgent, handleApproval, switchBranch, duplicateSession,
// closeSession, deleteSession, fetchHistory, resumeSession,
// fetchSession, fetchBrowserAgentChildren, searchHistory,
// } from './agentsThunks';
import {
GET_ALL_SESSIONS,
LAUNCH_AGENT,
@@ -22,6 +15,7 @@ import {
GET_HISTORY,
RESUME_SESSION,
GET_SESSION,
META_LAUNCH_AND_SEND,
} from '@/shared/backend-bridge/apps/agents';
export function buildExtraReducers(builder: ActionReducerMapBuilder<AgentsState>) {
@@ -70,20 +64,20 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder<AgentsState>
}
})
// 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);
// }
// })
.addCase(META_LAUNCH_AND_SEND.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];
@@ -201,22 +195,27 @@ export function buildExtraReducers(builder: ActionReducerMapBuilder<AgentsState>
tool_group_meta: session.tool_group_meta ?? existing?.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;
// });
.addCase(GET_HISTORY.pending, (state) => {
state.historySearch.loading = true;
})
.addCase(GET_HISTORY.fulfilled, (state, action) => {
const { sessions, total, has_more } = action.payload;
const offset = action.meta.arg.offset ?? 0;
if (offset === 0) {
state.historySearch.results = sessions;
} else {
state.historySearch.results = [...state.historySearch.results, ...sessions];
}
state.historySearch.total = total;
state.historySearch.hasMore = has_more;
state.historySearch.query = action.meta.arg.q ?? '';
state.historySearch.loading = false;
const history: Record<string, HistorySession> = {};
for (const s of sessions) history[s.id] = s;
state.history = offset === 0 ? history : { ...state.history, ...history };
})
.addCase(GET_HISTORY.rejected, (state) => {
state.historySearch.loading = false;
})
}
@@ -2,7 +2,7 @@ import { createSlice } from '@reduxjs/toolkit';
import { initialState } from './dashboardLayoutTypes';
import { dashboardLayoutReducers } from './dashboardLayoutReducers';
import { fetchLayout } from './dashboardLayoutThunks';
import { launchAndSendFirstMessage } from './agentsSlice';
import { META_LAUNCH_AND_SEND } from '@/shared/backend-bridge/apps/agents';
const dashboardLayoutSlice = createSlice({
name: 'dashboardLayout',
@@ -40,7 +40,7 @@ const dashboardLayoutSlice = createSlice({
state.loading = false;
state.initialized = true;
})
.addCase(launchAndSendFirstMessage.fulfilled, (state, action) => {
.addCase(META_LAUNCH_AND_SEND.fulfilled, (state, action) => {
const { draftId, session } = action.payload;
const card = state.cards[draftId];
if (card) {