import { useState, useEffect, useCallback } from 'react';
import {
getAgents,
getSessionMessages,
fetchWithAuth,
updateAgentConfig,
getUserConfig,
clearSessionHistory,
getSessionTokenStatus,
getAgentTriggers,
createAgentTrigger,
deleteAgentTrigger,
getUserAccessibleNodes,
getSkills,
resetAgentMetrics,
getAgentCortexFiles,
getAgentCortexFile
} from '../../../services/apiService';
export const useAgentDrillDown = (agentId) => {
const [agent, setAgent] = useState(null);
const [chatHistory, setChatHistory] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [overrideText, setOverrideText] = useState("");
// UI State
const [activeTab, setActiveTab] = useState('config');
const [editConfig, setEditConfig] = useState(null);
const [saving, setSaving] = useState(false);
const [userConfig, setUserConfig] = useState(null);
const [tokenUsage, setTokenUsage] = useState({ token_count: 0, token_limit: 0, percentage: 0 });
const [tokenError, setTokenError] = useState(null);
const [clearing, setClearing] = useState(false);
const [triggers, setTriggers] = useState([]);
const [newTriggerType, setNewTriggerType] = useState('cron');
const [newCronValue, setNewCronValue] = useState('0 * * * *');
const [newIntervalValue, setNewIntervalValue] = useState(600);
const [newDefaultPrompt, setNewDefaultPrompt] = useState('');
const [creatingTrigger, setCreatingTrigger] = useState(false);
const [modalConfig, setModalConfig] = useState(null);
const [nodes, setNodes] = useState([]);
const [allSkills, setAllSkills] = useState([]);
const [flippedCards, setFlippedCards] = useState({ runtime: false, tokens: false });
// Evaluation Hub State
const [cortexFiles, setCortexFiles] = useState([]);
const [feedbackContent, setFeedbackContent] = useState("");
const [rubricContent, setRubricContent] = useState("");
const [coworkerContent, setCoworkerContent] = useState("");
const [historyLog, setHistoryLog] = useState([]);
const [savingGroundTruth, setSavingGroundTruth] = useState(false);
const [selectedAuditId, setSelectedAuditId] = useState(null);
// Monitoring & Timer States
const [runningSeconds, setRunningSeconds] = useState(0);
const [lastTotalConsumption, setLastTotalConsumption] = useState(null);
const [previousStatus, setPreviousStatus] = useState('idle');
const [currentAction, setCurrentAction] = useState(null);
const [lastAction, setLastAction] = useState(null);
const [lastActionDuration, setLastActionDuration] = useState(null);
const [actionStartTime, setActionStartTime] = useState(0);
const fetchData = useCallback(async () => {
try {
const allAgents = await getAgents();
const found = allAgents.find(a => a.id === agentId);
if (!found) throw new Error("Agent not found");
setAgent(found);
setEditConfig(prev => prev || {
name: found.template?.name || "",
system_prompt: found.template?.system_prompt_content || found.template?.system_prompt_path || "",
max_loop_iterations: found.template?.max_loop_iterations || 20,
mesh_node_id: found.mesh_node_id || "",
provider_name: found.session?.provider_name || "",
restrict_skills: found.session?.restrict_skills || false,
allowed_skill_ids: found.session?.skills ? found.session.skills.map(s => s.id) : [],
is_locked: found.session?.is_locked || false,
auto_clear_history: found.session?.auto_clear_history || false,
co_worker_quality_gate: found.template?.co_worker_quality_gate || false,
rework_threshold: found.template?.rework_threshold || 80,
max_rework_attempts: found.template?.max_rework_attempts || 3
});
if (found.session_id) {
const historyResp = await getSessionMessages(found.session_id);
const formatted = (historyResp.messages || []).map(m => ({
text: m.content,
isUser: m.sender === 'user',
reasoning: m.reasoning_content,
status: null,
sender: m.sender,
timestamp: m.created_at,
id: m.id,
tool_calls: m.tool_calls,
message_metadata: m.message_metadata
}));
setChatHistory(formatted);
try {
const usage = await getSessionTokenStatus(found.session_id);
if (usage.error) {
setTokenError(usage.error);
setTokenUsage({ token_count: 0, token_limit: 0, percentage: 0 });
} else {
setTokenUsage(usage);
setTokenError(null);
}
} catch(e) {
setTokenError(e.message);
}
}
try {
const tList = await getAgentTriggers(agentId);
setTriggers(tList);
} catch(e) {}
const sid = found.session?.sync_workspace_id || found.session_id;
const nodeId = found.mesh_node_id || "hub";
if (sid) {
try {
const cFilesListing = await getAgentCortexFiles(agentId, nodeId, sid);
const files = cFilesListing.files || [];
setCortexFiles(files);
const fileExists = (name) => files.some(f => f.name === name || f.path === `.cortex/${name}`);
if (fileExists("feedback.md")) {
try {
const feedback = await getAgentCortexFile(agentId, nodeId, sid, "feedback.md");
setFeedbackContent(feedback?.content || "");
} catch (e) {}
}
if (fileExists("rubric.md")) {
try {
const rubric = await getAgentCortexFile(agentId, nodeId, sid, "rubric.md");
setRubricContent(rubric?.content || "");
} catch (e) {}
}
try {
const coworker = await getAgentCortexFile(agentId, nodeId, sid, ".coworker.md");
setCoworkerContent(coworker?.content || "");
} catch (e) {}
if (fileExists("history.log")) {
try {
const logs = await getAgentCortexFile(agentId, nodeId, sid, "history.log");
if (logs?.content) {
try {
const parsed = JSON.parse(logs.content);
setHistoryLog(Array.isArray(parsed) ? parsed : []);
} catch (e) {
setHistoryLog(logs.content.split('\n').filter(l => l.trim()).map(line => ({ message: line })));
}
}
} catch (e) {}
}
} catch (e) {}
}
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, [agentId]);
useEffect(() => {
const loadConf = async () => {
try {
const [conf, nList, sList] = await Promise.all([
getUserConfig(),
getUserAccessibleNodes(),
getSkills()
]);
setUserConfig(conf);
setNodes(nList);
setAllSkills(sList);
} catch (e) {}
};
loadConf();
}, []);
useEffect(() => {
fetchData();
const interval = setInterval(fetchData, 2500);
return () => clearInterval(interval);
}, [agentId, fetchData]);
useEffect(() => {
let timer = null;
const isRunning = agent?.status === 'active' || agent?.status === 'starting';
if (isRunning) {
timer = setInterval(() => {
setRunningSeconds(s => s + 1);
}, 1000);
} else if (previousStatus === 'active' || previousStatus === 'starting') {
setLastTotalConsumption(runningSeconds);
}
setPreviousStatus(agent?.status || 'idle');
return () => { if (timer) clearInterval(timer); };
}, [agent?.status, previousStatus, runningSeconds]);
useEffect(() => {
const isRunning = agent?.status === 'active' || agent?.status === 'starting';
if (!isRunning) return;
if (previousStatus !== 'active' && previousStatus !== 'starting') {
setRunningSeconds(0);
setLastTotalConsumption(null);
setCurrentAction(null);
setLastAction(null);
setLastActionDuration(null);
setActionStartTime(0);
}
const rawStatus = agent?.evaluation_status || 'Orchestrating task payload...';
if (rawStatus !== (currentAction?.raw || '')) {
const lowStatus = rawStatus.toLowerCase();
const hasPrefix = lowStatus.includes('agent:') || lowStatus.includes('audit:') || lowStatus.includes('co-worker:');
let cleanStatus = rawStatus;
if (!hasPrefix) {
cleanStatus = (lowStatus.includes('audit') || lowStatus.includes('worker') || lowStatus.includes('evaluat'))
? `🛡️ Co-Worker Audit: ${rawStatus}`
: `🤖 Main Agent: ${rawStatus}`;
}
if (currentAction) {
setLastAction(currentAction);
setLastActionDuration(runningSeconds - actionStartTime);
}
setCurrentAction({ display: cleanStatus, raw: rawStatus });
setActionStartTime(runningSeconds);
}
}, [agent?.status, agent?.evaluation_status, previousStatus, currentAction, runningSeconds, actionStartTime]);
const handleAction = async (targetStatus) => {
try {
await fetchWithAuth(`/agents/${agentId}/status`, {
method: 'PATCH',
body: { status: targetStatus }
});
fetchData();
} catch (err) {
setModalConfig({ title: 'Status Change Failed', message: err.message, type: 'error' });
}
};
const handleClearHistory = () => {
if (!agent?.session_id) return;
setModalConfig({
title: 'Confirm Memory Wipe',
message: "Are you sure you want to clear the agent's memory? This cannot be undone.",
type: 'error',
confirmText: 'Clear Memory',
confirmAction: async () => {
try {
setClearing(true);
if (agent?.session?.is_locked && editConfig?.is_locked === false) {
await updateAgentConfig(agent.id, {
is_locked: false,
mesh_node_id: agent.mesh_node_id || "hub"
});
}
await clearSessionHistory(agent.session_id);
setChatHistory([]);
setSelectedAuditId(null);
fetchData();
} catch (err) {
setModalConfig({ title: 'Clear Failed', message: err.message, type: 'error' });
} finally {
setClearing(false);
}
}
});
};
const handleSaveConfig = async () => {
try {
setSaving(true);
const payload = {
name: editConfig.name,
system_prompt: editConfig.system_prompt,
max_loop_iterations: parseInt(editConfig.max_loop_iterations, 10) || 20,
mesh_node_id: editConfig.mesh_node_id,
provider_name: editConfig.provider_name,
restrict_skills: editConfig.restrict_skills,
allowed_skill_ids: editConfig.allowed_skill_ids,
is_locked: editConfig.is_locked,
auto_clear_history: editConfig.auto_clear_history,
co_worker_quality_gate: editConfig.co_worker_quality_gate,
rework_threshold: parseInt(editConfig.rework_threshold, 10),
max_rework_attempts: parseInt(editConfig.max_rework_attempts, 10)
};
try {
await fetchWithAuth(`/agents/${agentId}/status`, { method: "PATCH", body: { status: "idle" } });
} catch (e) {}
await updateAgentConfig(agentId, payload);
fetchData();
setModalConfig({ title: 'Success', message: 'Configuration Saved Successfully!', type: 'success' });
} catch (err) {
setModalConfig({ title: 'Save Failed', message: err.message, type: 'error' });
} finally {
setSaving(false);
}
};
const handleSaveGroundTruth = async () => {
try {
setSavingGroundTruth(true);
const sid = agent.session?.sync_workspace_id || agent.session_id;
const nodeId = agent.mesh_node_id || "hub";
await fetchWithAuth(`/nodes/${nodeId}/fs/touch?X-User-ID=${userConfig?.id || 'agent_ui'}`, {
method: "POST",
body: {
path: ".coworker.md",
content: coworkerContent,
is_dir: false,
session_id: sid
}
});
setModalConfig({ title: 'Success', message: 'Auditor Guidelines synced to node workspace.', type: 'success' });
fetchData();
} catch (err) {
setModalConfig({ title: 'Update Failed', message: err.message, type: 'error' });
} finally {
setSavingGroundTruth(false);
}
};
const handleAddTrigger = async () => {
try {
setCreatingTrigger(true);
const payload = {
trigger_type: newTriggerType,
default_prompt: newDefaultPrompt
};
if (newTriggerType === 'cron') payload.cron_expression = newCronValue;
if (newTriggerType === 'interval') payload.interval_seconds = parseInt(newIntervalValue) || 600;
await createAgentTrigger(agentId, payload);
setNewDefaultPrompt('');
setNewCronValue('0 * * * *');
setNewIntervalValue(600);
fetchData();
} catch (err) {
setModalConfig({ title: 'Trigger Failed', message: err.message, type: 'error' });
} finally {
setCreatingTrigger(false);
}
};
const handleDeleteTrigger = async (triggerId) => {
try {
await deleteAgentTrigger(triggerId);
fetchData();
} catch (err) {
setModalConfig({ title: 'Delete Failed', message: err.message, type: 'error' });
}
};
const handleFireTrigger = async (triggerPrompt) => {
try {
await fetchWithAuth(`/agents/${agentId}/run`, {
method: 'POST',
body: { prompt: triggerPrompt }
});
setModalConfig({ title: 'Success', message: 'Agent manual execution started successfully!', type: 'success' });
fetchData();
} catch (err) {
setModalConfig({ title: 'Execution Failed', message: err.message, type: 'error' });
}
};
const handleFireWebhook = async (token, triggerPrompt) => {
try {
await fetchWithAuth(`/agents/${agentId}/webhook?token=${token}`, {
method: 'POST',
body: { prompt: triggerPrompt || "Manual test from UI" }
});
setModalConfig({ title: 'Success', message: 'Webhook test trigger sent successfully!', type: 'success' });
fetchData();
} catch (err) {
setModalConfig({ title: 'Webhook Failed', message: err.message, type: 'error' });
}
};
const handleResetMetrics = async () => {
setModalConfig({
title: 'Confirm Reset Metrics',
message: "Are you sure you want to reset all execution metrics for this agent? This cannot be undone.",
type: 'error',
confirmText: 'Reset Metrics',
confirmAction: async () => {
try {
setClearing(true);
await resetAgentMetrics(agentId);
fetchData();
} catch (err) {
setModalConfig({ title: 'Reset Failed', message: err.message, type: 'error' });
} finally {
setClearing(false);
}
}
});
};
const handleInjectOverride = async (e) => {
e.preventDefault();
if (!overrideText.trim() || !agent?.session_id) return;
try {
await fetchWithAuth(`/agents/${agentId}/run`, {
method: "POST",
body: { prompt: overrideText }
});
setOverrideText("");
fetchData();
} catch (err) {
setModalConfig({ title: 'Injection Failed', message: err.message, type: 'error' });
}
};
return {
agent, chatHistory, loading, error, activeTab, setActiveTab,
editConfig, setEditConfig, saving, userConfig, tokenUsage, tokenError,
clearing, triggers, newTriggerType, setNewTriggerType, newCronValue, setNewCronValue,
newIntervalValue, setNewIntervalValue, newDefaultPrompt, setNewDefaultPrompt,
creatingTrigger, modalConfig, setModalConfig, nodes, allSkills, flippedCards, setFlippedCards,
cortexFiles, feedbackContent, rubricContent, coworkerContent, setCoworkerContent,
historyLog, savingGroundTruth, selectedAuditId, setSelectedAuditId,
runningSeconds, lastTotalConsumption, currentAction, lastAction, lastActionDuration,
handleAction, handleClearHistory, handleSaveConfig, handleSaveGroundTruth, fetchData,
handleAddTrigger, handleDeleteTrigger, handleFireTrigger, handleFireWebhook,
handleResetMetrics, handleInjectOverride, overrideText, setOverrideText
};
};