- Move leftSidebarMode from URL state to local useState in unified-shell,
avoiding force-dynamic router round-trip that made the button appear broken - Replace fileURLToPath(new URL(..., import.meta.url)) with process.cwd()
in bb-pi-bootstrap.ts — import.meta.url is a webpack:// URL in Next.js,
causing cross-realm TypeError when passed to Node.js fileURLToPath()
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
// src/components/agents/hooks/use-agent-status.ts
|
|
import { useState, useEffect, useRef } from 'react';
|
|
|
|
export type WorkerStatus = 'idle' | 'spawning' | 'working' | 'blocked' | 'completed' | 'failed';
|
|
|
|
export interface AgentStatus {
|
|
agentTypeId?: string;
|
|
workerStatus: WorkerStatus;
|
|
workerDisplayName?: string;
|
|
workerError?: string;
|
|
isLoading: boolean;
|
|
}
|
|
|
|
const POLL_INTERVAL_MS = 5000;
|
|
|
|
export function useAgentStatus(beadId: string): AgentStatus {
|
|
const [status, setStatus] = useState<AgentStatus>({
|
|
workerStatus: 'idle',
|
|
isLoading: true,
|
|
});
|
|
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
|
|
|
const fetchStatus = async () => {
|
|
if (!beadId) return;
|
|
|
|
try {
|
|
const response = await fetch(`/api/runtime/worker-status?beadId=${encodeURIComponent(beadId)}`);
|
|
if (!response.ok) {
|
|
// If API returns 404 or error, no worker exists yet
|
|
setStatus({ workerStatus: 'idle', isLoading: false });
|
|
return;
|
|
}
|
|
|
|
const data = await response.json();
|
|
setStatus({
|
|
workerStatus: data.status || 'idle',
|
|
workerDisplayName: data.displayName,
|
|
workerError: data.error,
|
|
agentTypeId: data.agentTypeId,
|
|
isLoading: false,
|
|
});
|
|
} catch (error) {
|
|
console.error('Failed to fetch worker status:', error);
|
|
setStatus({ workerStatus: 'idle', isLoading: false });
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!beadId) {
|
|
setStatus({ workerStatus: 'idle', isLoading: false });
|
|
return;
|
|
}
|
|
|
|
// Initial fetch
|
|
fetchStatus();
|
|
|
|
// Set up polling
|
|
intervalRef.current = setInterval(fetchStatus, POLL_INTERVAL_MS);
|
|
|
|
return () => {
|
|
if (intervalRef.current) {
|
|
clearInterval(intervalRef.current);
|
|
}
|
|
};
|
|
}, [beadId]);
|
|
|
|
return status;
|
|
}
|