diff --git a/src/renderer/components/team/activity/PendingRepliesBlock.tsx b/src/renderer/components/team/activity/PendingRepliesBlock.tsx
index 58de583a..a768869e 100644
--- a/src/renderer/components/team/activity/PendingRepliesBlock.tsx
+++ b/src/renderer/components/team/activity/PendingRepliesBlock.tsx
@@ -12,7 +12,7 @@ import {
} from '@renderer/utils/memberHelpers';
import { nameColorSet } from '@renderer/utils/projectColor';
import { formatDistanceToNowStrict } from 'date-fns';
-import { ShieldQuestion, Users } from 'lucide-react';
+import { Loader2, ShieldQuestion, Users } from 'lucide-react';
import type { ResolvedTeamMember } from '@shared/types';
@@ -83,6 +83,7 @@ export const PendingRepliesBlock = ({
);
const advisoryLabel = getMemberRuntimeAdvisoryLabel(member.runtimeAdvisory);
const advisoryTitle = getMemberRuntimeAdvisoryTitle(member.runtimeAdvisory);
+ const isRetrying = advisoryLabel !== null;
return (
-
-
+
+
{onMemberClick ? (
@@ -139,12 +144,15 @@ export const PendingRepliesBlock = ({
) : null}
{advisoryLabel ?? 'awaiting reply'}
+ {isRetrying ? (
+
+ ) : null}
{since}
diff --git a/src/renderer/components/team/members/MemberCard.tsx b/src/renderer/components/team/members/MemberCard.tsx
index 2370a900..1f6a5a38 100644
--- a/src/renderer/components/team/members/MemberCard.tsx
+++ b/src/renderer/components/team/members/MemberCard.tsx
@@ -179,11 +179,11 @@ export const MemberCard = ({
{!activityTask && isAwaitingReply ? (
<>
{runtimeAdvisoryLabel ?? 'awaiting reply'}
diff --git a/src/renderer/utils/memberHelpers.ts b/src/renderer/utils/memberHelpers.ts
index ae986f61..88be4052 100644
--- a/src/renderer/utils/memberHelpers.ts
+++ b/src/renderer/utils/memberHelpers.ts
@@ -214,13 +214,13 @@ export function getMemberRuntimeAdvisoryLabel(
}
const retryUntilMs = Date.parse(advisory.retryUntil);
if (!Number.isFinite(retryUntilMs)) {
- return 'SDK retrying';
+ return 'retrying now';
}
const remainingMs = retryUntilMs - nowMs;
if (remainingMs <= 0) {
- return 'SDK retrying';
+ return 'retrying now';
}
- return `SDK retrying · ${formatRetryCountdown(remainingMs)}`;
+ return `retrying now · ${formatRetryCountdown(remainingMs)}`;
}
export function getMemberRuntimeAdvisoryTitle(
@@ -229,7 +229,10 @@ export function getMemberRuntimeAdvisoryTitle(
if (!advisory || advisory.kind !== 'sdk_retrying') {
return undefined;
}
- return advisory.message?.trim() || 'The SDK is retrying after a provider error.';
+ return (
+ advisory.message?.trim() ||
+ 'The SDK is retrying this request after a provider or backend error.'
+ );
}
export const TASK_STATUS_STYLES: Record = {
diff --git a/test/renderer/utils/memberHelpers.test.ts b/test/renderer/utils/memberHelpers.test.ts
index 848e2f3c..e908f749 100644
--- a/test/renderer/utils/memberHelpers.test.ts
+++ b/test/renderer/utils/memberHelpers.test.ts
@@ -1,6 +1,8 @@
import {
getSpawnAwareDotClass,
getSpawnAwarePresenceLabel,
+ getMemberRuntimeAdvisoryLabel,
+ getMemberRuntimeAdvisoryTitle,
} from '@renderer/utils/memberHelpers';
import type { ResolvedTeamMember } from '@shared/types';
@@ -59,4 +61,29 @@ describe('memberHelpers spawn-aware presence', () => {
)
).toBe('starting');
});
+
+ it('renders unified retry advisory labels for provider retries', () => {
+ expect(
+ getMemberRuntimeAdvisoryLabel(
+ {
+ kind: 'sdk_retrying',
+ observedAt: '2026-04-07T09:00:00.000Z',
+ retryUntil: '2026-04-07T09:00:45.000Z',
+ retryDelayMs: 45_000,
+ message: 'Gemini cli backend error: capacity exceeded.',
+ },
+ Date.parse('2026-04-07T09:00:00.000Z')
+ )
+ ).toBe('retrying now · 45s');
+
+ expect(
+ getMemberRuntimeAdvisoryTitle({
+ kind: 'sdk_retrying',
+ observedAt: '2026-04-07T09:00:00.000Z',
+ retryUntil: '2026-04-07T09:00:45.000Z',
+ retryDelayMs: 45_000,
+ message: 'Gemini cli backend error: capacity exceeded.',
+ })
+ ).toContain('capacity exceeded');
+ });
});