mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 16:43:16 +00:00
* 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>
135 lines
4.2 KiB
TypeScript
135 lines
4.2 KiB
TypeScript
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>
|
|
);
|
|
}
|