Files
web-page/src/pages/agent-office/hooks/useAgentManager.js

112 lines
3.2 KiB
JavaScript

// src/pages/agent-office/hooks/useAgentManager.js
import { useState, useEffect, useRef, useCallback } from 'react';
const WS_RECONNECT_DELAY = 3000;
export function useAgentManager() {
const [agents, setAgents] = useState({}); // { agentId: { state, detail, task_id } }
const [pendingTasks, setPendingTasks] = useState([]); // [{id, agent_id, task_type, input_data}]
const [notifications, setNotifications] = useState({}); // { agentId: count }
const [connected, setConnected] = useState(false);
const [refreshTrigger, setRefreshTrigger] = useState(0); // 탭 데이터 리프레시용
const wsRef = useRef(null);
const reconnectRef = useRef(null);
const connect = useCallback(() => {
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
const ws = new WebSocket(`${protocol}://${window.location.host}/api/agent-office/ws`);
wsRef.current = ws;
ws.onopen = () => setConnected(true);
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
switch (msg.type) {
case 'init': {
// 에이전트 초기 상태 세팅
const agentMap = {};
for (const a of msg.agents) {
agentMap[a.agent_id] = { state: a.state, detail: a.detail || '', task_id: a.task_id };
}
setAgents(agentMap);
setPendingTasks(msg.pending || []);
break;
}
case 'agent_state':
setAgents(prev => ({
...prev,
[msg.agent]: { state: msg.state, detail: msg.detail || '', task_id: msg.task_id }
}));
// idle 전환 시 데이터 리프레시
if (msg.state === 'idle') {
setRefreshTrigger(n => n + 1);
}
break;
case 'task_complete':
setRefreshTrigger(n => n + 1);
break;
case 'notification':
setNotifications(prev => ({
...prev,
[msg.agent]: (prev[msg.agent] || 0) + 1
}));
break;
case 'command_result':
// 사이드 패널에서 처리
break;
default:
break;
}
};
ws.onclose = () => {
setConnected(false);
reconnectRef.current = setTimeout(connect, WS_RECONNECT_DELAY);
};
ws.onerror = () => ws.close();
}, []);
useEffect(() => {
connect();
return () => {
if (wsRef.current) wsRef.current.close();
if (reconnectRef.current) clearTimeout(reconnectRef.current);
};
}, [connect]);
const sendCommand = useCallback((agent, action, params = {}) => {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsRef.current.send(JSON.stringify({ type: 'command', agent, action, params }));
}
}, []);
const sendApproval = useCallback((agent, taskId, approved) => {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsRef.current.send(JSON.stringify({ type: 'approval', agent, task_id: taskId, approved }));
}
}, []);
const clearNotifications = useCallback((agentId) => {
setNotifications(prev => ({ ...prev, [agentId]: 0 }));
}, []);
return {
agents,
pendingTasks,
notifications,
connected,
refreshTrigger,
sendCommand,
sendApproval,
clearNotifications
};
}