feat: Enhance agent selection and conversation handling

- Added functionality to select agents in the Navigation component, allowing users to reset conversations and set the selected agent.
- Updated the MessageInput component to conditionally show source and tool buttons based on the selected agent.
- Modified the Conversation component to handle agent-specific queries and manage file uploads.
- Improved conversation fetching logic to include agent IDs and handle attachments.
- Introduced new types for conversation summaries and results to streamline API responses.
- Refactored Redux slices to manage selected agent state and improve overall state management.
- Enhanced error handling and loading states across components for better user experience.
This commit is contained in:
Siddhant Rai
2025-04-15 11:53:53 +05:30
parent fa1f9d7009
commit 7c69e99914
16 changed files with 445 additions and 237 deletions

View File

@@ -1,6 +1,7 @@
import conversationService from '../api/services/conversationService';
import userService from '../api/services/userService';
import { Doc, GetDocsResponse } from '../models/misc';
import { GetConversationsResult, ConversationSummary } from './types';
//Fetches all JSON objects from the source. We only use the objects with the "model" property in SelectDocsModal.tsx. Hopefully can clean up the source file later.
export async function getDocs(token: string | null): Promise<Doc[] | null> {
@@ -49,23 +50,37 @@ export async function getDocsWithPagination(
}
}
export async function getConversations(token: string | null): Promise<{
data: { name: string; id: string }[] | null;
loading: boolean;
}> {
export async function getConversations(
token: string | null,
): Promise<GetConversationsResult> {
try {
const response = await conversationService.getConversations(token);
const data = await response.json();
const conversations: { name: string; id: string }[] = [];
if (!response.ok) {
console.error('Error fetching conversations:', response.statusText);
return { data: null, loading: false };
}
data.forEach((conversation: object) => {
conversations.push(conversation as { name: string; id: string });
});
const rawData: unknown = await response.json();
if (!Array.isArray(rawData)) {
console.error(
'Invalid data format received from API: Expected an array.',
rawData,
);
return { data: null, loading: false };
}
const conversations: ConversationSummary[] = rawData.map((item: any) => ({
id: item.id,
name: item.name,
agent_id: item.agent_id ?? null,
}));
return { data: conversations, loading: false };
} catch (error) {
console.log(error);
console.error(
'An unexpected error occurred while fetching conversations:',
error,
);
return { data: null, loading: false };
}
}

View File

@@ -1,12 +1,14 @@
import {
PayloadAction,
createListenerMiddleware,
createSlice,
isAnyOf,
PayloadAction,
} from '@reduxjs/toolkit';
import { setLocalApiKey, setLocalRecentDocs } from './preferenceApi';
import { RootState } from '../store';
import { Agent } from '../agents/types';
import { ActiveState, Doc } from '../models/misc';
import { RootState } from '../store';
import { setLocalApiKey, setLocalRecentDocs } from './preferenceApi';
export interface Preference {
apiKey: string;
@@ -22,6 +24,7 @@ export interface Preference {
token: string | null;
modalState: ActiveState;
paginatedDocuments: Doc[] | null;
selectedAgent: Agent | null;
}
const initialState: Preference = {
@@ -46,6 +49,7 @@ const initialState: Preference = {
token: localStorage.getItem('authToken') || null,
modalState: 'INACTIVE',
paginatedDocuments: null,
selectedAgent: null,
};
export const prefSlice = createSlice({
@@ -82,6 +86,9 @@ export const prefSlice = createSlice({
setModalStateDeleteConv: (state, action: PayloadAction<ActiveState>) => {
state.modalState = action.payload;
},
setSelectedAgent: (state, action) => {
state.selectedAgent = action.payload;
},
},
});
@@ -96,6 +103,7 @@ export const {
setTokenLimit,
setModalStateDeleteConv,
setPaginatedDocuments,
setSelectedAgent,
} = prefSlice.actions;
export default prefSlice.reducer;
@@ -170,3 +178,5 @@ export const selectTokenLimit = (state: RootState) =>
state.preference.token_limit;
export const selectPaginatedDocuments = (state: RootState) =>
state.preference.paginatedDocuments;
export const selectSelectedAgent = (state: RootState) =>
state.preference.selectedAgent;

View File

@@ -0,0 +1,10 @@
export type ConversationSummary = {
id: string;
name: string;
agent_id: string | null;
};
export type GetConversationsResult = {
data: ConversationSummary[] | null;
loading: boolean;
};