Spaces:
Running
Running
File size: 4,651 Bytes
7694ee5 90bab83 7694ee5 90bab83 7694ee5 90bab83 7694ee5 90bab83 7694ee5 90bab83 7694ee5 90bab83 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | """Patch useAgentChat.ts - auto-continue feature."""
USE_AGENT_CHAT = "/source/frontend/src/hooks/useAgentChat.ts"
def patch():
import os
if not os.path.exists(USE_AGENT_CHAT):
print(f"SKIP: {USE_AGENT_CHAT} not found")
return
with open(USE_AGENT_CHAT, "r", encoding="utf-8") as f:
content = f.read()
# 1. Add useState to imports
if "useState" not in content:
content = content.replace(
"import { useCallback, useEffect, useMemo, useRef } from 'react';",
"import { useCallback, useEffect, useMemo, useRef, useState } from 'react';"
)
# 2. Add state declarations after callbacksRef.current = { ... }
state_decl = '''
// Auto-continue state for free models when task incomplete
const autoContinueTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const [showAutoContinue, setShowAutoContinue] = useState(false);
const [taskIncompleteInfo, setTaskIncompleteInfo] = useState<{
incompletePlan: Array<{ id: string; content: string; status: string }>;
} | null>(null);
'''
if "autoContinueTimerRef" not in content:
content = content.replace(
"callbacksRef.current = { onReady, onError, onSessionDead };",
"callbacksRef.current = { onReady, onError, onSessionDead };" + state_decl
)
# 3. Add onTaskIncomplete to SideChannelCallbacks interface
if "onTaskIncomplete:" not in content and "onInterrupted:" in content:
content = content.replace(
" onInterrupted: () => void;",
" onInterrupted: () => void;\n onTaskIncomplete: (incompletePlan: Array<{ id: string; content: string; status: string }>) => void;"
)
# 4. Add onTaskIncomplete handler in sideChannel
sidechannel_handler = ''' onTaskIncomplete: (incompletePlan) => {
setTaskIncompleteInfo({ incompletePlan });
setShowAutoContinue(true);
// Auto-start 10s timer for free models
if (autoContinueTimerRef.current) {
clearTimeout(autoContinueTimerRef.current);
}
autoContinueTimerRef.current = setTimeout(() => {
startAutoContinue();
}, 10000);
},'''
if "onTaskIncomplete: (incompletePlan)" not in content:
content = content.replace(
" onInterrupted: () => { /* no-op — handled by stop() caller */ },",
sidechannel_handler + "\n onInterrupted: () => { /* no-op — handled by stop() caller */ },"
)
# 5. Add auto-continue functions before return
auto_funcs = '''
// -- Auto-continue for free models when task incomplete -----------------
const startAutoContinue = useCallback(() => {
setShowAutoContinue(false);
setTaskIncompleteInfo(null);
if (autoContinueTimerRef.current) {
clearTimeout(autoContinueTimerRef.current);
autoContinueTimerRef.current = null;
}
// Build continuation message from incomplete plan
const incompleteItems = taskIncompleteInfo?.incompletePlan || [];
const continuationText = incompleteItems.length > 0
? `Tiếp tục từ các task chưa hoàn thành:\\n${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;
}
}, []);
// Cleanup timer on unmount
useEffect(() => {
return () => {
if (autoContinueTimerRef.current) {
clearTimeout(autoContinueTimerRef.current);
}
};
}, []);
'''
if "startAutoContinue" not in content:
content = content.replace(
'\n return {\n messages: chat.messages,',
auto_funcs + '\n return {\n messages: chat.messages,'
)
# 6. Update return to include new values
if "showAutoContinue," not in content:
content = content.replace(
"refreshMessages,\n };",
"refreshMessages,\n showAutoContinue,\n taskIncompleteInfo,\n startAutoContinue,\n cancelAutoContinue,\n };"
)
with open(USE_AGENT_CHAT, "w", encoding="utf-8") as f:
f.write(content)
print(f"OK: Complete patch applied to {USE_AGENT_CHAT}")
if __name__ == "__main__":
patch() |