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