import { useState, useEffect } from 'react'; import apiClient from '../../api/client'; import { Save, Plus, Edit2, Trash2, X } from 'lucide-react'; import type { Provider } from '../../types'; interface WorkerIndividual { agent_id: string; agent_name: string; agent_type: string; description?: string; provider_title: string; model_id: string; system_prompt?: string; output_template?: string; // Change to string for the form state bound_skill?: string; // Change to string for the form state workspace?: string; // Change to string for the form state } export function WorkerIndividualSettings() { const [providers, setProviders] = useState([]); const [workers, setWorkers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [isEditing, setIsEditing] = useState(false); const [editData, setEditData] = useState>({}); const [isNew, setIsNew] = useState(false); const [modalMessage, setModalMessage] = useState(''); const fetchData = async () => { setLoading(true); try { const [provRes, workRes] = await Promise.all([ apiClient.get('/api/v1/provider/list'), apiClient.get('/api/v1/agent/worker') ]); setProviders(Object.values(provRes.data.provider_list || {})); setWorkers(workRes.data.workers || []); } catch (err: any) { console.error(err); setError('Failed to load data'); } finally { setLoading(false); } }; useEffect(() => { fetchData(); }, []); const handleEdit = (worker: any) => { // Accept the backend object which might have objects instead of strings setEditData({ ...worker, output_template: typeof worker.output_template === 'string' ? worker.output_template : JSON.stringify(worker.output_template || {}), bound_skill: typeof worker.bound_skill === 'string' ? worker.bound_skill : JSON.stringify(worker.bound_skill || {}), workspace: typeof worker.workspace === 'string' ? worker.workspace : JSON.stringify(worker.workspace || []) }); setIsNew(false); setIsEditing(true); setModalMessage(''); }; const handleAddNew = () => { setEditData({ agent_name: '', agent_type: 'OrdinaryIndividual', description: '', provider_title: providers.length > 0 ? providers[0].provider_title : '', model_id: '', system_prompt: '', output_template: '{}', bound_skill: '{}', workspace: '[]' }); setIsNew(true); setIsEditing(true); setModalMessage(''); }; const handleDelete = async (agent_id: string) => { if (!confirm('Are you sure you want to delete this agent?')) return; try { await apiClient.delete(`/api/v1/agent/worker/${agent_id}`); fetchData(); } catch (err: any) { console.error(err); alert('Failed to delete agent'); } }; const handleModalSave = async (e: React.FormEvent) => { e.preventDefault(); setModalMessage(''); try { const payload = { ...editData, output_template: JSON.parse(editData.output_template || '{}'), bound_skill: JSON.parse(editData.bound_skill || '{}'), workspace: JSON.parse(editData.workspace || '[]') }; if (isNew) { await apiClient.post('/api/v1/agent/worker', payload); } else { await apiClient.put(`/api/v1/agent/worker/${editData.agent_id}`, payload); } setIsEditing(false); fetchData(); } catch (err: any) { console.error(err); setModalMessage(err.response?.data?.detail || err.message || 'Failed to save'); } }; return (

Worker Individuals

Manage all system nodes and custom workers.

{error &&
{error}
}
{loading ? (
Loading...
) : workers.length === 0 ? (
No workers found.
) : ( {workers.map((w) => ( ))}
Name Type Provider / Model ID Actions
{w.agent_name} {w.agent_type} {w.provider_title} / {w.model_id}
)}
{/* Edit/Create Modal */} {isEditing && (

{isNew ? 'Create Worker' : 'Edit Worker'}

setEditData({...editData, agent_name: e.target.value})} className="w-full px-4 py-2 border border-slate-200 rounded-lg focus:ring-2 focus:ring-indigo-500" />
{(() => { const selectedProvider = providers.find(p => p.provider_title === editData.provider_title); const models = selectedProvider?.provider_models || []; return ( ); })()}