- apps/api: FastAPI backend with Dockerfile - apps/web: Next.js frontend with Dockerfile - apps/sensor: Signal collection agent - packages: shared packages Co-Authored-By: Claude <noreply@anthropic.com>
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
/**
|
|
* Agent Hooks - OpenClaw 狀態與操作
|
|
*/
|
|
|
|
'use client'
|
|
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
import { apiClient } from '@/lib/api-client'
|
|
import { useAgentStore } from '@/stores/agent.store'
|
|
import { useEffect } from 'react'
|
|
|
|
/**
|
|
* 取得 Agent 狀態 (輪詢)
|
|
*/
|
|
export function useAgentStatus(pollInterval = 5000) {
|
|
const setStatus = useAgentStore((s) => s.setStatus)
|
|
const setCurrentTask = useAgentStore((s) => s.setCurrentTask)
|
|
|
|
const query = useQuery({
|
|
queryKey: ['agent', 'status'],
|
|
queryFn: () => apiClient.getAgentStatus(),
|
|
refetchInterval: pollInterval,
|
|
})
|
|
|
|
// Sync to Zustand store
|
|
useEffect(() => {
|
|
if (query.data) {
|
|
setStatus(query.data.status)
|
|
setCurrentTask(query.data.current_task)
|
|
}
|
|
}, [query.data, setStatus, setCurrentTask])
|
|
|
|
return query
|
|
}
|
|
|
|
/**
|
|
* 與 Agent 對話
|
|
*/
|
|
export function useAgentChat() {
|
|
const queryClient = useQueryClient()
|
|
const setStatus = useAgentStore((s) => s.setStatus)
|
|
const setConversationId = useAgentStore((s) => s.setConversationId)
|
|
const conversationId = useAgentStore((s) => s.conversationId)
|
|
|
|
return useMutation({
|
|
mutationFn: (message: string) =>
|
|
apiClient.chat(message, conversationId ?? undefined),
|
|
onMutate: () => {
|
|
setStatus('thinking')
|
|
},
|
|
onSuccess: (data) => {
|
|
setConversationId(data.conversation_id)
|
|
setStatus(data.requires_approval ? 'waiting_approval' : 'idle')
|
|
// Invalidate status query
|
|
queryClient.invalidateQueries({ queryKey: ['agent', 'status'] })
|
|
},
|
|
onError: () => {
|
|
setStatus('idle')
|
|
},
|
|
})
|
|
}
|