feat: Implement AI Router for Dynamic Agent Selection (#15227)

Adds intelligent routing system that automatically selects the best
agent for user queries based on conversation context.

### Changes:
- Added `routerModel` column to workspace table for configurable router
LLM selection
- Implemented `RouterService` with conversation history analysis and
agent matching logic
- Created router settings UI in AI Settings page with model dropdown
- Removed agent-specific thread associations - threads are now
agent-agnostic
- Added real-time routing status notification in chat UI with shimmer
effect
- Removed automatic default assistant agent creation
- Renamed GraphQL operations from agent-specific to generic (e.g.,
`agentChatThreads` → `chatThreads`)

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
Abdul Rahman
2025-10-22 18:32:41 +05:30
committed by GitHub
parent 1c27206b41
commit 32558673c6
102 changed files with 2262 additions and 1912 deletions
@@ -1,37 +1,15 @@
import { AIChatThreadsList } from '@/ai/components/AIChatThreadsList';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
const StyledContainer = styled.div`
height: 100%;
width: 100%;
`;
const StyledEmptyState = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.secondary};
display: flex;
font-size: ${({ theme }) => theme.font.size.md};
height: 100%;
justify-content: center;
`;
export const CommandMenuAIChatThreadsPage = () => {
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const agentId = currentWorkspace?.defaultAgent?.id;
if (!agentId) {
return (
<StyledContainer>
<StyledEmptyState>No AI Agent found.</StyledEmptyState>
</StyledContainer>
);
}
return (
<StyledContainer>
<AIChatThreadsList agentId={agentId} />
<AIChatThreadsList />
</StyledContainer>
);
};