feat: workflow和chat分离

1,增加了创建workflow的页面
2.删除了event
This commit is contained in:
2026-05-14 15:51:28 +00:00
parent c0e4fd34ae
commit 78bd6adc48
30 changed files with 1196 additions and 760 deletions
+37 -27
View File
@@ -8,11 +8,11 @@ interface LeftPanelProps {
activeTab: string;
selectedWorkflow: string | null;
setSelectedWorkflow: (id: string | null) => void;
// Hoisted state props (optional, since this panel is used for workflows too)
chatSessions?: ChatSession[];
setChatSessions?: React.Dispatch<React.SetStateAction<ChatSession[]>>;
activeSessionId?: string | null;
setActiveSessionId?: React.Dispatch<React.SetStateAction<string | null>>;
onSessionsChanged?: () => void;
}
export function LeftPanel({
@@ -23,6 +23,7 @@ export function LeftPanel({
setChatSessions,
activeSessionId,
setActiveSessionId,
onSessionsChanged,
}: LeftPanelProps) {
const [workflows, setWorkflows] = useState<Workflow[]>([]);
const [loadingWorkflows, setLoadingWorkflows] = useState(false);
@@ -60,23 +61,31 @@ export function LeftPanel({
};
}, [activeTab]);
const handleNewChat = () => {
if (!setChatSessions || !setActiveSessionId) return;
const newSession: ChatSession = {
id: Date.now().toString(),
title: 'New Chat',
messages: [
{
id: Date.now().toString(),
role: 'assistant',
content: 'Hello! I am kilostar Assistant. How can I help you today?',
timestamp: Date.now(),
},
],
updatedAt: Date.now(),
};
setChatSessions((prev) => [newSession, ...prev]);
setActiveSessionId(newSession.id);
const handleNewChat = async () => {
if (!setChatSessions || !setActiveSessionId || !onSessionsChanged) return;
try {
const response = await apiClient.post('/api/v1/chat', {
title: '新对话',
initial_message: '你好',
});
const chatId: string = response.data.chat_id;
const reply: string = response.data.reply || '你好!我是 kilostar 助手,有什么可以帮你的吗?';
const newSession: ChatSession = {
id: chatId,
title: '新对话',
messages: [
{ id: chatId + '_user', role: 'user', content: '你好', timestamp: Date.now() },
{ id: chatId + '_ai', role: 'assistant', content: reply, timestamp: Date.now() },
],
updatedAt: Date.now(),
};
setChatSessions((prev) => [newSession, ...prev]);
setActiveSessionId(chatId);
onSessionsChanged();
} catch (error) {
console.error('Failed to create chat session', error);
}
};
const handleDeleteChat = (e: React.MouseEvent, id: string) => {
@@ -91,7 +100,6 @@ export function LeftPanel({
return (
<div className="w-72 bg-white border-r border-slate-100 flex flex-col z-0 shrink-0">
{/* Bottom: Tab Selection */}
<div className="flex-1 flex flex-col overflow-hidden">
<div className="flex items-center justify-between p-3 border-b border-slate-100 bg-slate-50">
@@ -103,7 +111,7 @@ export function LeftPanel({
if (activeTab === 'chats') {
handleNewChat();
} else {
setSelectedWorkflow('new'); // 设置为一个特殊值,表示进入新建工作流向导
setSelectedWorkflow('new');
}
}}
className="p-1.5 bg-blue-100 text-blue-600 rounded hover:bg-blue-200 transition-colors"
@@ -123,10 +131,10 @@ export function LeftPanel({
) : (
workflows.map((wf) => (
<div
key={wf.event_id}
onClick={() => setSelectedWorkflow(wf.event_id)}
key={wf.trace_id}
onClick={() => setSelectedWorkflow(wf.trace_id)}
className={`p-3 rounded-lg border cursor-pointer transition-all ${
selectedWorkflow === wf.event_id
selectedWorkflow === wf.trace_id
? 'border-blue-300 bg-blue-50 shadow-sm'
: 'border-slate-100 hover:border-blue-200 hover:bg-slate-50'
}`}
@@ -134,22 +142,24 @@ export function LeftPanel({
<div className="flex justify-between items-center mb-1">
<span
className={`font-medium text-sm ${
selectedWorkflow === wf.event_id ? 'text-blue-700' : 'text-slate-700'
selectedWorkflow === wf.trace_id ? 'text-blue-700' : 'text-slate-700'
}`}
>
{wf.workflow_title || 'Unnamed Workflow'}
{wf.title || 'Unnamed Workflow'}
</span>
<span
className={`flex h-2 w-2 rounded-full ${
wf.status === 'llm_working' || wf.status === 'tool_working'
wf.status && (wf.status.includes('working'))
? 'bg-green-400 animate-pulse'
: wf.status === 'failed'
? 'bg-red-400'
: wf.status === 'completed'
? 'bg-green-500'
: 'bg-slate-300'
}`}
></span>
</div>
<p className="text-xs text-slate-500 font-mono line-clamp-1">ID: {wf.event_id}</p>
<p className="text-xs text-slate-500 font-mono line-clamp-1">ID: {wf.trace_id}</p>
</div>
))
)}