mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-26 11:34:50 +02:00
[eric] agents: mid-turn provider backoff shows a muted retrying pill instead of a dead card, and transient pills survive session status frames
This commit is contained in:
@@ -69,7 +69,7 @@ import { isShowUiPair, isAskUiPair, extractPendingAskUi } from './tool-ui/showUi
|
||||
import { composerPlaceholder } from './composerPlaceholder';
|
||||
import ApprovalBar, { BatchApprovalBar } from './shell/ApprovalBar';
|
||||
import ForceStopAgentBar from './ForceStopAgentBar';
|
||||
import { RateLimitPill } from './shell/RateLimitPill';
|
||||
import { ProviderRetryPill, RateLimitPill } from './shell/RateLimitPill';
|
||||
import { ContextRecoveredPill } from './shell/ContextRecoveredPill';
|
||||
import ChatInput, { ChatInputHandle } from './ChatInput';
|
||||
import FollowupChips from './FollowupChips';
|
||||
@@ -2132,6 +2132,7 @@ const AgentChat: React.FC<AgentChatProps> = ({ sessionId: sessionIdProp, onClose
|
||||
)}
|
||||
|
||||
<RateLimitPill sessionId={session.id} />
|
||||
<ProviderRetryPill sessionId={session.id} />
|
||||
<ContextRecoveredPill sessionId={session.id} />
|
||||
|
||||
{isGlowing ? (
|
||||
|
||||
@@ -3,10 +3,55 @@ import Box from '@mui/material/Box';
|
||||
import Fade from '@mui/material/Fade';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import ScheduleIcon from '@mui/icons-material/Schedule';
|
||||
import AutorenewIcon from '@mui/icons-material/Autorenew';
|
||||
import { useAppDispatch, useAppSelector } from '@/shared/hooks';
|
||||
import { clearRateLimited } from '@/shared/state/agentsSlice';
|
||||
import { clearProviderRetrying, clearRateLimited } from '@/shared/state/agentsSlice';
|
||||
import { useClaudeTokens } from '@/shared/styles/ThemeContext';
|
||||
|
||||
/** Mid-turn CLI backoff pill (ENG-178): the provider 500/429'd and the CLI is silently waiting up
|
||||
* to tens of seconds; without this the card just sits dead. Auto-clears after the announced delay
|
||||
* plus slack, and each new retry event refreshes it. Same muted grammar as the rate-limit pill. */
|
||||
export const ProviderRetryPill: React.FC<{ sessionId: string }> = ({ sessionId }) => {
|
||||
const c = useClaudeTokens();
|
||||
const dispatch = useAppDispatch();
|
||||
const pr = useAppSelector((s) => s.agents.sessions[sessionId]?.provider_retrying);
|
||||
|
||||
useEffect(() => {
|
||||
if (!pr) return;
|
||||
const ms = Math.min(Math.max((pr.delay_ms ?? 15_000) + 15_000, 10_000), 120_000);
|
||||
const t = setTimeout(() => dispatch(clearProviderRetrying({ sessionId })), ms);
|
||||
return () => clearTimeout(t);
|
||||
}, [pr, sessionId, dispatch]);
|
||||
|
||||
const label = pr?.attempt ? `Provider busy, retrying (attempt ${pr.attempt})` : 'Provider busy, retrying';
|
||||
const lastLabel = useRef(label);
|
||||
if (pr) lastLabel.current = label;
|
||||
|
||||
return (
|
||||
<Fade in={!!pr} timeout={{ enter: 200, exit: 220 }} unmountOnExit>
|
||||
<Box
|
||||
title="The AI provider had a hiccup; the agent is waiting it out and will continue on its own"
|
||||
sx={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 0.6,
|
||||
alignSelf: 'flex-start',
|
||||
mx: 2,
|
||||
mb: 1,
|
||||
px: 1.25,
|
||||
py: 0.5,
|
||||
borderRadius: 999,
|
||||
bgcolor: c.bg.secondary,
|
||||
color: c.text.tertiary,
|
||||
}}
|
||||
>
|
||||
<AutorenewIcon sx={{ fontSize: 14, animation: 'osw-retry-spin 1.6s linear infinite', '@keyframes osw-retry-spin': { to: { transform: 'rotate(360deg)' } } }} />
|
||||
<Typography sx={{ fontSize: '0.75rem', fontWeight: 500 }}>{lastLabel.current}</Typography>
|
||||
</Box>
|
||||
</Fade>
|
||||
);
|
||||
};
|
||||
|
||||
// Muted, transient pill shown only after a real provider throttle outlasted the silent backoff. No card, no red, no CTA; it fades and auto-clears once the window should have passed. The "why" lives in the hover, not on the surface.
|
||||
export const RateLimitPill: React.FC<{ sessionId: string }> = ({ sessionId }) => {
|
||||
const c = useClaudeTokens();
|
||||
|
||||
Reference in New Issue
Block a user