# Auto-Continue Feature for Free Models ## Tổng quan Khi model miễn phí dùng OpenRouter phản hồi bị dừng nhưng nhiệm vụ chưa hoàn thành, hệ thống sẽ: 1. Phát hiện task incomplete dựa vào trạng thái plan 2. Hiển thị 2 nút: "Tự động tiếp tục (10s)" và "Tạm dừng" ## Các file cần sửa ### 1. frontend/src/hooks/useAgentChat.ts ```typescript // Thêm vào import import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; // Trong useAgentChat function, sau callbacksRef const autoContinueTimerRef = useRef | null>(null); const [showAutoContinue, setShowAutoContinue] = useState(false); const [taskIncompleteInfo, setTaskIncompleteInfo] = useState<{ incompletePlan: Array<{ id: string; content: string; status: string }>; } | null>(null); // Thêm vào SideChannelCallbacks interface export interface SideChannelCallbacks { // ... existing callbacks ... onTaskIncomplete: (incompletePlan: Array<{ id: string; content: string; status: string }>) => void; } // Thêm vào sideChannel trong useMemo onTaskIncomplete: (incompletePlan) => { setTaskIncompleteInfo({ incompletePlan }); setShowAutoContinue(true); if (autoContinueTimerRef.current) { clearTimeout(autoContinueTimerRef.current); } autoContinueTimerRef.current = setTimeout(() => { startAutoContinue(); }, 10000); }, // Thêm hàm mới const startAutoContinue = useCallback(() => { setShowAutoContinue(false); setTaskIncompleteInfo(null); if (autoContinueTimerRef.current) { clearTimeout(autoContinueTimerRef.current); autoContinueTimerRef.current = null; } const incompleteItems = taskIncompleteInfo?.incompletePlan || []; const continuationText = incompleteItems.length > 0 ? `Tiếp tục từ các task chưa hoàn thành: ${incompleteItems.map(i => `- ${i.content}`).join('\n')}` : 'Tiếp tục nhiệm vụ.'; chat.sendMessage({ text: `[TỰ ĐỘNG TIẾP TỤC] ${continuationText}`, metadata: { createdAt: new Date().toISOString() } }); }, [taskIncompleteInfo, chat]); const cancelAutoContinue = useCallback(() => { setShowAutoContinue(false); setTaskIncompleteInfo(null); if (autoContinueTimerRef.current) { clearTimeout(autoContinueTimerRef.current); autoContinueTimerRef.current = null; } }, []); // Thêm vào return return { messages: chat.messages, sendMessage: chat.sendMessage, stop, status: chat.status, undoLastTurn, editAndRegenerate, approveTools, refreshMessages, showAutoContinue, taskIncompleteInfo, startAutoContinue, cancelAutoContinue, }; ``` ### 2. frontend/src/components/Chat/ChatInput.tsx ```typescript // Thêm import import { Box, IconButton, Stack, Tooltip, Button } from '@mui/material'; // Thêm props interface ChatInputProps { // ... existing props showAutoContinue?: boolean; taskIncompleteInfo?: { incompletePlan: Array<{ id: string; content: string; status: string }> } | null; startAutoContinue?: () => void; cancelAutoContinue?: () => void; } // Thêm UI buttons (trước hoặc sau input area) {showAutoContinue && taskIncompleteInfo && ( )} ``` ### 3. frontend/src/lib/sse-chat-transport.ts ```typescript // Thêm vào case trong createEventToChunkStream case 'task_incomplete': sideChannel.onTaskIncomplete( (event.data?.incomplete_plan as Array<{ id: string; content: string; status: string }>) || [], ); break; ``` ### 4. agent/core/agent_loop.py ```python # Trong run_agent, sau khi xử lý LLM response def _check_task_incomplete(session: Session, llm_result: LLMResult) -> bool: """Kiểm tra nếu model dừng nhưng task chưa hoàn thành.""" if llm_result.tool_calls_acc: return False # Có tool calls thì chưa incomplete plan = getattr(session, "current_plan", None) or [] unfinished = [item for item in plan if item.get("status") in ("pending", "in_progress")] return len(unfinished) > 0 # Gọi sau khi nhận kết quả LLM: if _check_task_incomplete(session, llm_result): unfinished = [item for item in plan if item.get("status") in ("pending", "in_progress")] await session.send_event( Event( event_type="task_incomplete", data={ "incomplete_plan": unfinished, "message": "Model stopped streaming but task is incomplete." } ) ) ``` ## Logic hoạt động 1. Khi agent loop phát hiện model trả lời không có tool calls nhưng plan còn incomplete 2. Backend gửi event `task_incomplete` với danh sách task chưa hoàn thành 3. Frontend nhận event qua `onTaskIncomplete` callback 4. Hiển thị 2 nút: - **Tự động tiếp tục (10s)**: Sau 10 giây sẽ tự động gửi tin nhắn tiếp tục - **Tạm dừng**: Hủy timer, cho phép user nhập nội dung mới ## Áp dụng patch ```bash # Tải source git clone https://huggingface.co/spaces/smolagents/ml-intern /tmp/source # Sửa các file trên # Sau đó rebuild frontend cd /tmp/source/frontend npm install && npm run build ```