Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Commit ·
f0c7e64
1
Parent(s): 854c261
fix: approval UI not updating after approve click
Browse files
frontend/src/components/Chat/ToolCallGroup.tsx
CHANGED
|
@@ -32,6 +32,8 @@ function StatusIcon({ state }: { state: ToolPartState }) {
|
|
| 32 |
switch (state) {
|
| 33 |
case 'approval-requested':
|
| 34 |
return <HourglassEmptyIcon sx={{ fontSize: 16, color: 'var(--accent-yellow)' }} />;
|
|
|
|
|
|
|
| 35 |
case 'output-available':
|
| 36 |
return <CheckCircleOutlineIcon sx={{ fontSize: 16, color: 'success.main' }} />;
|
| 37 |
case 'output-error':
|
|
@@ -48,6 +50,7 @@ function StatusIcon({ state }: { state: ToolPartState }) {
|
|
| 48 |
function statusLabel(state: ToolPartState): string | null {
|
| 49 |
switch (state) {
|
| 50 |
case 'approval-requested': return 'awaiting approval';
|
|
|
|
| 51 |
case 'input-streaming':
|
| 52 |
case 'input-available': return 'running';
|
| 53 |
case 'output-denied': return 'denied';
|
|
@@ -59,6 +62,7 @@ function statusLabel(state: ToolPartState): string | null {
|
|
| 59 |
function statusColor(state: ToolPartState): string {
|
| 60 |
switch (state) {
|
| 61 |
case 'approval-requested': return 'var(--accent-yellow)';
|
|
|
|
| 62 |
case 'output-available': return 'var(--accent-green)';
|
| 63 |
case 'output-error': return 'var(--accent-red)';
|
| 64 |
case 'output-denied': return 'var(--muted-text)';
|
|
|
|
| 32 |
switch (state) {
|
| 33 |
case 'approval-requested':
|
| 34 |
return <HourglassEmptyIcon sx={{ fontSize: 16, color: 'var(--accent-yellow)' }} />;
|
| 35 |
+
case 'approval-responded':
|
| 36 |
+
return <CircularProgress size={14} thickness={5} sx={{ color: 'var(--accent-green)' }} />;
|
| 37 |
case 'output-available':
|
| 38 |
return <CheckCircleOutlineIcon sx={{ fontSize: 16, color: 'success.main' }} />;
|
| 39 |
case 'output-error':
|
|
|
|
| 50 |
function statusLabel(state: ToolPartState): string | null {
|
| 51 |
switch (state) {
|
| 52 |
case 'approval-requested': return 'awaiting approval';
|
| 53 |
+
case 'approval-responded': return 'approved';
|
| 54 |
case 'input-streaming':
|
| 55 |
case 'input-available': return 'running';
|
| 56 |
case 'output-denied': return 'denied';
|
|
|
|
| 62 |
function statusColor(state: ToolPartState): string {
|
| 63 |
switch (state) {
|
| 64 |
case 'approval-requested': return 'var(--accent-yellow)';
|
| 65 |
+
case 'approval-responded': return 'var(--accent-green)';
|
| 66 |
case 'output-available': return 'var(--accent-green)';
|
| 67 |
case 'output-error': return 'var(--accent-red)';
|
| 68 |
case 'output-denied': return 'var(--muted-text)';
|
frontend/src/components/SessionChat.tsx
CHANGED
|
@@ -49,6 +49,9 @@ export default function SessionChat({ sessionId, isActive, onSessionDead }: Sess
|
|
| 49 |
const hasPendingApproval = lastAssistant?.parts.some(
|
| 50 |
(p) => p.type === 'dynamic-tool' && p.state === 'approval-requested'
|
| 51 |
) ?? false;
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
if (hasPendingApproval) {
|
| 54 |
store.setActivityStatus({ type: 'waiting-approval' });
|
|
@@ -81,6 +84,10 @@ export default function SessionChat({ sessionId, isActive, onSessionDead }: Sess
|
|
| 81 |
}
|
| 82 |
useLayoutStore.getState().setRightPanelOpen(true);
|
| 83 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
} else {
|
| 85 |
// No pending approval — reset to idle
|
| 86 |
store.setActivityStatus({ type: 'idle' });
|
|
|
|
| 49 |
const hasPendingApproval = lastAssistant?.parts.some(
|
| 50 |
(p) => p.type === 'dynamic-tool' && p.state === 'approval-requested'
|
| 51 |
) ?? false;
|
| 52 |
+
const hasApprovedRunning = lastAssistant?.parts.some(
|
| 53 |
+
(p) => p.type === 'dynamic-tool' && p.state === 'approval-responded'
|
| 54 |
+
) ?? false;
|
| 55 |
|
| 56 |
if (hasPendingApproval) {
|
| 57 |
store.setActivityStatus({ type: 'waiting-approval' });
|
|
|
|
| 84 |
}
|
| 85 |
useLayoutStore.getState().setRightPanelOpen(true);
|
| 86 |
}
|
| 87 |
+
} else if (hasApprovedRunning) {
|
| 88 |
+
// Tools were approved but still executing — show processing state
|
| 89 |
+
store.setActivityStatus({ type: 'tool', toolName: 'running' });
|
| 90 |
+
store.setProcessing(true);
|
| 91 |
} else {
|
| 92 |
// No pending approval — reset to idle
|
| 93 |
store.setActivityStatus({ type: 'idle' });
|
frontend/src/hooks/useAgentChat.ts
CHANGED
|
@@ -331,6 +331,17 @@ export function useAgentChat({ sessionId, isActive, onReady, onError, onSessionD
|
|
| 331 |
const approveTools = useCallback(
|
| 332 |
async (approvals: Array<{ tool_call_id: string; approved: boolean; feedback?: string | null; edited_script?: string | null }>) => {
|
| 333 |
if (!transportRef.current) return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
const ok = await transportRef.current.approveTools(sessionId, approvals);
|
| 335 |
if (ok) {
|
| 336 |
// Clear needsAttention since user has responded
|
|
@@ -340,7 +351,7 @@ export function useAgentChat({ sessionId, isActive, onReady, onError, onSessionD
|
|
| 340 |
}
|
| 341 |
return ok;
|
| 342 |
},
|
| 343 |
-
[sessionId, setProcessing, setNeedsAttention],
|
| 344 |
);
|
| 345 |
|
| 346 |
return {
|
|
|
|
| 331 |
const approveTools = useCallback(
|
| 332 |
async (approvals: Array<{ tool_call_id: string; approved: boolean; feedback?: string | null; edited_script?: string | null }>) => {
|
| 333 |
if (!transportRef.current) return false;
|
| 334 |
+
|
| 335 |
+
// Transition SDK tool state from approval-requested → approval-responded
|
| 336 |
+
// so the approval UI disappears immediately (survives session switches).
|
| 337 |
+
for (const a of approvals) {
|
| 338 |
+
chat.addToolApprovalResponse({
|
| 339 |
+
id: `approval-${a.tool_call_id}`,
|
| 340 |
+
approved: a.approved,
|
| 341 |
+
reason: a.approved ? undefined : (a.feedback || 'Rejected by user'),
|
| 342 |
+
});
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
const ok = await transportRef.current.approveTools(sessionId, approvals);
|
| 346 |
if (ok) {
|
| 347 |
// Clear needsAttention since user has responded
|
|
|
|
| 351 |
}
|
| 352 |
return ok;
|
| 353 |
},
|
| 354 |
+
[sessionId, chat, setProcessing, setNeedsAttention],
|
| 355 |
);
|
| 356 |
|
| 357 |
return {
|