Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Commit ·
cb3e47e
1
Parent(s): e35ce5d
fix: reset approval UI state when new approval round arrives
Browse filesAfter submitting a rejection with feedback, isSubmitting was never reset
on success. When the agent made a second tool call requiring approval,
the InlineApproval component was blocked by the stale isSubmitting=true.
Track submitted tool IDs and reset submission state when new (unseen)
pending tools arrive in the same ToolCallGroup instance.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
frontend/src/components/Chat/ToolCallGroup.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { useCallback, useMemo, useRef, useState } from 'react';
|
| 2 |
import { Box, Stack, Typography, Chip, Button, TextField, IconButton, Link, CircularProgress } from '@mui/material';
|
| 3 |
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
|
| 4 |
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
|
|
@@ -329,6 +329,20 @@ export default function ToolCallGroup({ tools, approveTools }: ToolCallGroupProp
|
|
| 329 |
const [isSubmitting, setIsSubmitting] = useState(false);
|
| 330 |
const submittingRef = useRef(false);
|
| 331 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
const { scriptLabelMap, toolDisplayMap } = useMemo(() => {
|
| 333 |
const hfJobs = tools.filter(t => t.toolName === 'hf_jobs' && (t.input as Record<string, unknown>)?.script);
|
| 334 |
const scriptMap: Record<string, string> = {};
|
|
@@ -368,6 +382,8 @@ export default function ToolCallGroup({ tools, approveTools }: ToolCallGroupProp
|
|
| 368 |
|
| 369 |
const ok = await approveTools(approvals);
|
| 370 |
if (ok) {
|
|
|
|
|
|
|
| 371 |
lockPanel();
|
| 372 |
} else {
|
| 373 |
logger.error('Batch approval failed');
|
|
|
|
| 1 |
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
| 2 |
import { Box, Stack, Typography, Chip, Button, TextField, IconButton, Link, CircularProgress } from '@mui/material';
|
| 3 |
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
|
| 4 |
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
|
|
|
|
| 329 |
const [isSubmitting, setIsSubmitting] = useState(false);
|
| 330 |
const submittingRef = useRef(false);
|
| 331 |
|
| 332 |
+
// Track which toolCallIds we've already submitted so we can detect new approval rounds
|
| 333 |
+
const submittedIdsRef = useRef<Set<string>>(new Set());
|
| 334 |
+
|
| 335 |
+
// Reset submission state when new (unseen) pending tools arrive — e.g. second approval round
|
| 336 |
+
useEffect(() => {
|
| 337 |
+
if (!isSubmitting || pendingTools.length === 0) return;
|
| 338 |
+
const hasNewPending = pendingTools.some(t => !submittedIdsRef.current.has(t.toolCallId));
|
| 339 |
+
if (hasNewPending) {
|
| 340 |
+
submittingRef.current = false;
|
| 341 |
+
setIsSubmitting(false);
|
| 342 |
+
setDecisions({});
|
| 343 |
+
}
|
| 344 |
+
}, [pendingTools, isSubmitting]);
|
| 345 |
+
|
| 346 |
const { scriptLabelMap, toolDisplayMap } = useMemo(() => {
|
| 347 |
const hfJobs = tools.filter(t => t.toolName === 'hf_jobs' && (t.input as Record<string, unknown>)?.script);
|
| 348 |
const scriptMap: Record<string, string> = {};
|
|
|
|
| 382 |
|
| 383 |
const ok = await approveTools(approvals);
|
| 384 |
if (ok) {
|
| 385 |
+
// Track which tool IDs were submitted so we can detect new approval rounds
|
| 386 |
+
for (const a of approvals) submittedIdsRef.current.add(a.tool_call_id);
|
| 387 |
lockPanel();
|
| 388 |
} else {
|
| 389 |
logger.error('Batch approval failed');
|