diff --git a/__LOCAL_LLMs/dashboard/src/app/(workspace)/c/[id]/page.tsx b/__LOCAL_LLMs/dashboard/src/app/(workspace)/c/[id]/page.tsx index d0681b59..9ea0d597 100644 --- a/__LOCAL_LLMs/dashboard/src/app/(workspace)/c/[id]/page.tsx +++ b/__LOCAL_LLMs/dashboard/src/app/(workspace)/c/[id]/page.tsx @@ -3,13 +3,14 @@ import Link from 'next/link'; import { useEffect, useState } from 'react'; import { useSearchParams } from 'next/navigation'; -import { getConversation, getMessages } from '../../../lib/db'; -import type { Conversation, Message } from '../../../lib/types'; +import { getAgent, getConversation, getMessages } from '../../../lib/db'; +import type { Agent, Conversation, Message } from '../../../lib/types'; import { ConversationView } from '../../components/ConversationView'; export default function ConversationPage({ params }: { params: { id: string } }) { const searchParams = useSearchParams(); const [conversation, setConversation] = useState(null); + const [agent, setAgent] = useState(null); const [messages, setMessages] = useState([]); const [loading, setLoading] = useState(true); @@ -21,7 +22,9 @@ export default function ConversationPage({ params }: { params: { id: string } }) return; } const msgRows = await getMessages(params.id, { limit: 200 }); + const agentRow = row.agentId ? await getAgent(row.agentId) : undefined; setConversation(row); + setAgent(agentRow || null); setMessages(msgRows); setLoading(false); }; @@ -54,6 +57,7 @@ export default function ConversationPage({ params }: { params: { id: string } }) conversation={conversation} initialMessages={messages} initialTemplate={searchParams.get('template') || ''} + agent={agent || undefined} /> ); } diff --git a/__LOCAL_LLMs/dashboard/src/app/(workspace)/components/AgentEditor.tsx b/__LOCAL_LLMs/dashboard/src/app/(workspace)/components/AgentEditor.tsx new file mode 100644 index 00000000..65c72985 --- /dev/null +++ b/__LOCAL_LLMs/dashboard/src/app/(workspace)/components/AgentEditor.tsx @@ -0,0 +1,232 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import type { Agent, AgentTool } from '../../lib/types'; + +interface AgentEditorProps { + open: boolean; + editing?: Agent | null; + onClose: () => void; + onSave: (agent: Agent) => Promise; +} + +const TOOL_OPTIONS: AgentTool[] = ['file_read', 'vision', 'voice_input']; + +export function AgentEditor({ open, editing, onClose, onSave }: AgentEditorProps) { + const [name, setName] = useState(''); + const [icon, setIcon] = useState('πŸ€–'); + const [description, setDescription] = useState(''); + const [model, setModel] = useState('chat'); + const [temperature, setTemperature] = useState(0.7); + const [systemPrompt, setSystemPrompt] = useState(''); + const [welcomeMessage, setWelcomeMessage] = useState(''); + const [examplePrompts, setExamplePrompts] = useState(''); + const [responseFormat, setResponseFormat] = useState('markdown'); + const [tools, setTools] = useState(['file_read']); + const [saving, setSaving] = useState(false); + + useEffect(() => { + if (!open) return; + if (editing) { + setName(editing.name); + setIcon(editing.icon); + setDescription(editing.description); + setModel(editing.model); + setTemperature(editing.temperature ?? 0.7); + setSystemPrompt(editing.systemPrompt); + setWelcomeMessage(editing.welcomeMessage || ''); + setExamplePrompts((editing.examplePrompts || []).join('\n')); + setResponseFormat(editing.responseFormat || 'markdown'); + setTools(editing.tools || ['file_read']); + return; + } + + setName(''); + setIcon('πŸ€–'); + setDescription(''); + setModel('chat'); + setTemperature(0.7); + setSystemPrompt(''); + setWelcomeMessage(''); + setExamplePrompts(''); + setResponseFormat('markdown'); + setTools(['file_read']); + }, [open, editing]); + + if (!open) return null; + + const canSave = name.trim().length > 0 && systemPrompt.trim().length > 0; + + return ( +
+
e.stopPropagation()} + > +

+ {editing ? 'Edit Agent' : 'Create Agent'} +

+ +
+ + + + + + + + + +