@@ -91,6 +91,7 @@ import {
9191import { BackgroundFinishChip , SubagentResultCard , SubagentSpawnCard } from "./SubagentActivityCards" ;
9292import { ChatUserMinimap } from "./ChatUserMinimap" ;
9393import { AgentCliAuthCard , type AgentCliAuthCardInfo } from "./AgentCliAuthCard" ;
94+ import { classifyProviderFailure , ProviderFailureRecoveryCard } from "./ProviderFailureRecoveryCard" ;
9495import { HighlightedCode } from "./CodeHighlighter" ;
9596import { MosaicCard } from "./MosaicCard" ;
9697import { MOSAIC_FENCE_LANGUAGE } from "../../../shared/chatMosaic" ;
@@ -2635,6 +2636,8 @@ function renderEvent(
26352636 options ?: {
26362637 onApproval ?: ( itemId : string , decision : AgentChatApprovalDecision , responseText ?: string | null , answers ?: Record < string , string | string [ ] > ) => void ;
26372638 onCodexRecovery ?: ( args : AgentChatRecoverCodexTurnArgs ) => Promise < AgentChatRecoverCodexTurnResult > ;
2639+ onRetryProviderFailure ?: ( turnId : string | null ) => void ;
2640+ onChooseProviderFailureModel ?: ( ) => void ;
26382641 turnModel ?: { label : string ; modelId ?: string ; model ?: string } | null ;
26392642 surfaceMode ?: ChatSurfaceMode ;
26402643 surfaceProfile ?: ChatSurfaceProfile ;
@@ -3617,6 +3620,7 @@ function renderEvent(
36173620 const errorCopyValue = event . detail ?. trim ( ) . length
36183621 ? `${ event . message } \n\n${ event . detail } `
36193622 : event . message ;
3623+ const recovery = classifyProviderFailure ( event ) ;
36203624 const renderAgentCliAuthCard = ( ) => agentCliInfo ? (
36213625 < AgentCliAuthCard
36223626 agentCli = { agentCliInfo }
@@ -3680,10 +3684,24 @@ function renderEvent(
36803684 { event . detail }
36813685 </ div >
36823686 ) : null }
3687+ { recovery ? (
3688+ < ProviderFailureRecoveryCard
3689+ recovery = { recovery }
3690+ disabled = { Boolean ( options ?. turnActive ) }
3691+ onRetry = { options ?. onRetryProviderFailure
3692+ ? ( ) => options . onRetryProviderFailure ?.( event . turnId ?? null )
3693+ : undefined }
3694+ onChooseModel = { options ?. onChooseProviderFailureModel }
3695+ />
3696+ ) : null }
36833697 { renderAgentCliAuthCard ( ) }
36843698 { event . errorInfo && ! agentCliInfo ? (
3685- < div className = "mt-2 font-mono text-[length:calc(var(--chat-font-size)*10/14)] text-muted-fg/40" >
3686- { typeof event . errorInfo === "string" ? event . errorInfo : `${ event . errorInfo . provider ? `${ event . errorInfo . provider } ` : "" } ${ event . errorInfo . model ? ` / ${ event . errorInfo . model } ` : "" } ` }
3699+ < div
3700+ className = "mt-2 font-mono text-[length:calc(var(--chat-font-size)*10/14)] text-muted-fg/40"
3701+ title = { typeof event . errorInfo === "string" ? event . errorInfo : undefined }
3702+ >
3703+ { recovery ?. label
3704+ ?? ( typeof event . errorInfo === "string" ? event . errorInfo : `${ event . errorInfo . provider ? `${ event . errorInfo . provider } ` : "" } ${ event . errorInfo . model ? ` / ${ event . errorInfo . model } ` : "" } ` ) }
36873705 </ div >
36883706 ) : null }
36893707 </ div >
@@ -4143,6 +4161,8 @@ type EventRowProps = {
41434161 turnEndDurationMs ?: number | null ;
41444162 onApproval ?: ( itemId : string , decision : AgentChatApprovalDecision , responseText ?: string | null , answers ?: Record < string , string | string [ ] > ) => void ;
41454163 onCodexRecovery ?: ( args : AgentChatRecoverCodexTurnArgs ) => Promise < AgentChatRecoverCodexTurnResult > ;
4164+ onRetryProviderFailure ?: ( turnId : string | null ) => void ;
4165+ onChooseProviderFailureModel ?: ( ) => void ;
41464166 surfaceMode ?: ChatSurfaceMode ;
41474167 surfaceProfile ?: ChatSurfaceProfile ;
41484168 assistantLabel ?: string ;
@@ -4176,6 +4196,8 @@ const EventRow = React.memo(function EventRow({
41764196 turnEndDurationMs,
41774197 onApproval,
41784198 onCodexRecovery,
4199+ onRetryProviderFailure,
4200+ onChooseProviderFailureModel,
41794201 surfaceMode = "standard" ,
41804202 surfaceProfile = "standard" ,
41814203 assistantLabel,
@@ -4243,6 +4265,8 @@ const EventRow = React.memo(function EventRow({
42434265 : renderEvent ( envelope as RenderEnvelope , {
42444266 onApproval,
42454267 onCodexRecovery,
4268+ onRetryProviderFailure,
4269+ onChooseProviderFailureModel,
42464270 turnModel,
42474271 surfaceMode,
42484272 surfaceProfile,
@@ -4571,6 +4595,8 @@ function AgentChatMessageListMain({
45714595 className,
45724596 onApproval,
45734597 onCodexRecovery,
4598+ onRetryProviderFailure,
4599+ onChooseProviderFailureModel,
45744600 surfaceMode = "standard" ,
45754601 surfaceProfile = "standard" ,
45764602 assistantLabel,
@@ -4595,6 +4621,8 @@ function AgentChatMessageListMain({
45954621 className ?: string ;
45964622 onApproval ?: ( itemId : string , decision : AgentChatApprovalDecision , responseText ?: string | null , answers ?: Record < string , string | string [ ] > ) => void ;
45974623 onCodexRecovery ?: ( args : AgentChatRecoverCodexTurnArgs ) => Promise < AgentChatRecoverCodexTurnResult > ;
4624+ onRetryProviderFailure ?: ( turnId : string | null ) => void ;
4625+ onChooseProviderFailureModel ?: ( ) => void ;
45984626 surfaceMode ?: ChatSurfaceMode ;
45994627 surfaceProfile ?: ChatSurfaceProfile ;
46004628 assistantLabel ?: string ;
@@ -5397,6 +5425,8 @@ function AgentChatMessageListMain({
53975425 turnEndDurationMs = { turnEndDurationMs }
53985426 onApproval = { handleApproval }
53995427 onCodexRecovery = { onCodexRecovery }
5428+ onRetryProviderFailure = { onRetryProviderFailure }
5429+ onChooseProviderFailureModel = { onChooseProviderFailureModel }
54005430 surfaceMode = { surfaceMode }
54015431 surfaceProfile = { surfaceProfile }
54025432 assistantLabel = { assistantLabel }
@@ -5433,6 +5463,8 @@ function AgentChatMessageListMain({
54335463 turnModel = { turnModel }
54345464 onApproval = { handleApproval }
54355465 onCodexRecovery = { onCodexRecovery }
5466+ onRetryProviderFailure = { onRetryProviderFailure }
5467+ onChooseProviderFailureModel = { onChooseProviderFailureModel }
54365468 surfaceMode = { surfaceMode }
54375469 surfaceProfile = { surfaceProfile }
54385470 assistantLabel = { assistantLabel }
@@ -5458,7 +5490,7 @@ function AgentChatMessageListMain({
54585490 assistantTurnCopy = { assistantTurnCopy }
54595491 />
54605492 ) ;
5461- } , [ activeTurnId , anchoredRowKey , assistantLabel , assistantTurnCopyByRowKey , surfaceMode , surfaceProfile , groupedRows , latestWorkLogIndex , turnModelState , handleApproval , handleMeasure , openWorkspacePath , handleNavigateSuggestion , handleReviewChanges , onCodexRecovery , onInsertDraft , onRevealChatTerminal , onRewindFiles , turnDiffSummaries , respondingApprovalIds , pendingApprovalIds , resolvedInputStates , laneId , sessionId , sessionEnded , runtimeName , mosaic , scrollToRowKey ] ) ;
5493+ } , [ activeTurnId , anchoredRowKey , assistantLabel , assistantTurnCopyByRowKey , surfaceMode , surfaceProfile , groupedRows , latestWorkLogIndex , turnModelState , handleApproval , handleMeasure , openWorkspacePath , handleNavigateSuggestion , handleReviewChanges , onCodexRecovery , onRetryProviderFailure , onChooseProviderFailureModel , onInsertDraft , onRevealChatTerminal , onRewindFiles , turnDiffSummaries , respondingApprovalIds , pendingApprovalIds , resolvedInputStates , laneId , sessionId , sessionEnded , runtimeName , mosaic , scrollToRowKey ] ) ;
54625494
54635495 // Compute the bottom spacer height for virtualized mode.
54645496 const bottomSpacerHeight = useMemo ( ( ) => {
0 commit comments