mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-12-01 01:23:14 +00:00
feat: agent templates and seeding premade agents (#1910)
* feat: agent templates and seeding premade agents * fix: ensure ObjectId is used for source reference in agent configuration * fix: improve source handling in DatabaseSeeder and update tool config processing * feat: add prompt handling in DatabaseSeeder for agent configuration * Docs premade agents * link to prescraped docs * feat: add template agent retrieval and adopt agent functionality * feat: simplify agent descriptions in premade_agents.yaml added docs --------- Co-authored-by: Pavel <pabin@yandex.ru> Co-authored-by: Alex <a@tushynski.me>
This commit is contained in:
134
frontend/src/agents/AgentsList.tsx
Normal file
134
frontend/src/agents/AgentsList.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import Spinner from '../components/Spinner';
|
||||
import {
|
||||
setConversation,
|
||||
updateConversationId,
|
||||
} from '../conversation/conversationSlice';
|
||||
import {
|
||||
selectSelectedAgent,
|
||||
selectToken,
|
||||
setSelectedAgent,
|
||||
} from '../preferences/preferenceSlice';
|
||||
import AgentCard from './AgentCard';
|
||||
import { agentSectionsConfig } from './agents.config';
|
||||
import { Agent } from './types';
|
||||
|
||||
export default function AgentsList() {
|
||||
const dispatch = useDispatch();
|
||||
const token = useSelector(selectToken);
|
||||
const selectedAgent = useSelector(selectSelectedAgent);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(setConversation([]));
|
||||
dispatch(
|
||||
updateConversationId({
|
||||
query: { conversationId: null },
|
||||
}),
|
||||
);
|
||||
if (selectedAgent) dispatch(setSelectedAgent(null));
|
||||
}, [token]);
|
||||
return (
|
||||
<div className="p-4 md:p-12">
|
||||
<h1 className="text-eerie-black mb-0 text-[32px] font-bold lg:text-[40px] dark:text-[#E0E0E0]">
|
||||
Agents
|
||||
</h1>
|
||||
<p className="dark:text-gray-4000 mt-5 text-[15px] text-[#71717A]">
|
||||
Discover and create custom versions of DocsGPT that combine
|
||||
instructions, extra knowledge, and any combination of skills
|
||||
</p>
|
||||
{agentSectionsConfig.map((sectionConfig) => (
|
||||
<AgentSection key={sectionConfig.id} config={sectionConfig} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AgentSection({
|
||||
config,
|
||||
}: {
|
||||
config: (typeof agentSectionsConfig)[number];
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const token = useSelector(selectToken);
|
||||
const agents = useSelector(config.selectData);
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const updateAgents = (updatedAgents: Agent[]) => {
|
||||
dispatch(config.updateAction(updatedAgents));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const getAgents = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await config.fetchAgents(token);
|
||||
if (!response.ok)
|
||||
throw new Error(`Failed to fetch ${config.id} agents`);
|
||||
const data = await response.json();
|
||||
dispatch(config.updateAction(data));
|
||||
} catch (error) {
|
||||
console.error(`Error fetching ${config.id} agents:`, error);
|
||||
dispatch(config.updateAction([]));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
getAgents();
|
||||
}, [token, config, dispatch]);
|
||||
return (
|
||||
<div className="mt-8 flex flex-col gap-4">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h2 className="text-[18px] font-semibold text-[#18181B] dark:text-[#E0E0E0]">
|
||||
{config.title}
|
||||
</h2>
|
||||
<p className="text-[13px] text-[#71717A]">{config.description}</p>
|
||||
</div>
|
||||
{config.showNewAgentButton && (
|
||||
<button
|
||||
className="bg-purple-30 hover:bg-violets-are-blue rounded-full px-4 py-2 text-sm text-white"
|
||||
onClick={() => navigate('/agents/new')}
|
||||
>
|
||||
New Agent
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{loading ? (
|
||||
<div className="flex h-72 w-full items-center justify-center">
|
||||
<Spinner />
|
||||
</div>
|
||||
) : agents && agents.length > 0 ? (
|
||||
<div className="grid grid-cols-1 gap-4 sm:flex sm:flex-wrap">
|
||||
{agents.map((agent) => (
|
||||
<AgentCard
|
||||
key={agent.id}
|
||||
agent={agent}
|
||||
agents={agents}
|
||||
updateAgents={updateAgents}
|
||||
section={config.id}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-72 w-full flex-col items-center justify-center gap-3 text-base text-[#18181B] dark:text-[#E0E0E0]">
|
||||
<p>{config.emptyStateDescription}</p>
|
||||
{config.showNewAgentButton && (
|
||||
<button
|
||||
className="bg-purple-30 hover:bg-violets-are-blue ml-2 rounded-full px-4 py-2 text-sm text-white"
|
||||
onClick={() => navigate('/agents/new')}
|
||||
>
|
||||
New Agent
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user