mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-30 03:00:41 -04:00
fix(copilot): restore client auto-approve with 5s server grace to fix UI not updating
When the server was the sole auto-approver (both at 60s, client removed), users who stayed in the session saw nothing happen — the server fired the turn but the frontend had no SSE subscription to receive the events. Restore the client-side auto-approve effect so it fires at 60s (creating the SSE subscription), and add a 5s server grace (server fires at 65s). When the client IS present, it fires first → SSE → user sees the build. The server wakes 5s later, sees the client's message, skips. When the client is gone (tab closed), the server fires at 65s as the fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,11 +23,15 @@ MAX_STEPS = 8
|
||||
DEFAULT_ACTION = "add_block"
|
||||
VALID_ACTIONS = {"add_block", "connect_blocks", "configure", "add_input", "add_output"}
|
||||
|
||||
# Auto-approve countdown — single source of truth for both client and server.
|
||||
# The frontend reads ``auto_approve_seconds`` from the tool response and runs
|
||||
# the visible countdown. The server fires at the same deadline.
|
||||
# Auto-approve countdown — the frontend reads ``auto_approve_seconds`` from the
|
||||
# tool response and runs the visible countdown (60s). The server fires 5s later
|
||||
# as a fallback for the "user closed the tab" case. The 5s gap ensures the
|
||||
# client always fires first when present, creating the SSE subscription that
|
||||
# lets the user see the build in real-time. When the server wakes at 65s, it
|
||||
# checks the predicate and skips (the client's message is already there).
|
||||
AUTO_APPROVE_CLIENT_SECONDS = 60
|
||||
AUTO_APPROVE_SERVER_SECONDS = AUTO_APPROVE_CLIENT_SECONDS
|
||||
AUTO_APPROVE_SERVER_GRACE_SECONDS = 5
|
||||
AUTO_APPROVE_SERVER_SECONDS = AUTO_APPROVE_CLIENT_SECONDS + AUTO_APPROVE_SERVER_GRACE_SECONDS
|
||||
AUTO_APPROVE_MESSAGE = "Approved. Please build the agent."
|
||||
|
||||
# Redis key prefix for cross-process cancel signalling. The cancel
|
||||
|
||||
@@ -209,11 +209,17 @@ export function DecomposeGoalTool({
|
||||
return () => clearInterval(interval);
|
||||
}, [showActions, timerActive, part.toolCallId]);
|
||||
|
||||
// The server-side timer is the sole auto-approver (sends the synthetic
|
||||
// "Approved" message and enqueues the next copilot turn). The client
|
||||
// countdown is purely visual — no client-side approve() call when it
|
||||
// hits 0. This avoids the duplicate-message bug where both client and
|
||||
// server fire at ~60s. User clicks (Start now / Approve) still work.
|
||||
// Auto-approve when countdown reaches 0. The client fires at 60s; the
|
||||
// server fires 5s later as a fallback for the "user closed the tab" case.
|
||||
// When the client IS present, its approve() creates the SSE subscription
|
||||
// so the user sees the build in real-time. The server's predicate then
|
||||
// sees the user's message and skips — no duplicate.
|
||||
// approve() is stable via approvedRef — safe to omit from deps.
|
||||
useEffect(() => {
|
||||
if (secondsLeft === 0 && timerActive && actionsEnabled) {
|
||||
approve();
|
||||
}
|
||||
}, [secondsLeft, timerActive, actionsEnabled]);
|
||||
|
||||
const progress = secondsLeft / countdownSeconds;
|
||||
const dashOffset = CIRCUMFERENCE * (1 - progress);
|
||||
|
||||
Reference in New Issue
Block a user