Make MessageBlock rerender via keyed Show

This commit is contained in:
Shantur Rathore
2025-11-30 20:56:17 +00:00
parent c5011e4ece
commit 9423326193

View File

@@ -883,107 +883,108 @@ function MessageBlock(props: MessageBlockProps) {
return resultBlock return resultBlock
}) })
const resolvedBlock = block()
if (!resolvedBlock) return null
return ( return (
<div class="message-stream-block" data-message-id={resolvedBlock.record.id}> <Show when={block()} keyed>
<For each={resolvedBlock.items}> {(resolvedBlock) => (
{(item) => ( <div class="message-stream-block" data-message-id={resolvedBlock.record.id}>
<Switch> <For each={resolvedBlock.items}>
<Match when={item.type === "content"}> {(item) => (
<MessageItem <Switch>
record={(item as ContentDisplayItem).record} <Match when={item.type === "content"}>
messageInfo={(item as ContentDisplayItem).messageInfo} <MessageItem
combinedParts={(item as ContentDisplayItem).parts} record={(item as ContentDisplayItem).record}
orderedParts={(item as ContentDisplayItem).parts} messageInfo={(item as ContentDisplayItem).messageInfo}
instanceId={props.instanceId} combinedParts={(item as ContentDisplayItem).parts}
sessionId={props.sessionId} orderedParts={(item as ContentDisplayItem).parts}
isQueued={(item as ContentDisplayItem).isQueued} instanceId={props.instanceId}
showAgentMeta={(item as ContentDisplayItem).showAgentMeta} sessionId={props.sessionId}
onRevert={props.onRevert} isQueued={(item as ContentDisplayItem).isQueued}
onFork={props.onFork} showAgentMeta={(item as ContentDisplayItem).showAgentMeta}
/> onRevert={props.onRevert}
</Match> onFork={props.onFork}
<Match when={item.type === "tool"}> />
{(() => { </Match>
const toolItem = item as ToolDisplayItem <Match when={item.type === "tool"}>
const toolState = toolItem.toolPart.state as ToolState | undefined {(() => {
const hasToolState = const toolItem = item as ToolDisplayItem
Boolean(toolState) && (isToolStateRunning(toolState) || isToolStateCompleted(toolState) || isToolStateError(toolState)) const toolState = toolItem.toolPart.state as ToolState | undefined
const taskSessionId = hasToolState ? extractTaskSessionId(toolState) : "" const hasToolState =
const taskLocation = taskSessionId ? findTaskSessionLocation(taskSessionId) : null Boolean(toolState) && (isToolStateRunning(toolState) || isToolStateCompleted(toolState) || isToolStateError(toolState))
const handleGoToTaskSession = (event: MouseEvent) => { const taskSessionId = hasToolState ? extractTaskSessionId(toolState) : ""
event.preventDefault() const taskLocation = taskSessionId ? findTaskSessionLocation(taskSessionId) : null
event.stopPropagation() const handleGoToTaskSession = (event: MouseEvent) => {
if (!taskLocation) return event.preventDefault()
navigateToTaskSession(taskLocation) event.stopPropagation()
} if (!taskLocation) return
navigateToTaskSession(taskLocation)
}
return ( return (
<div class="tool-call-message" data-key={toolItem.key}> <div class="tool-call-message" data-key={toolItem.key}>
<div class="tool-call-header-label"> <div class="tool-call-header-label">
<div class="tool-call-header-meta"> <div class="tool-call-header-meta">
<span class="tool-call-icon">{TOOL_ICON}</span> <span class="tool-call-icon">{TOOL_ICON}</span>
<span>Tool Call</span> <span>Tool Call</span>
<span class="tool-name">{toolItem.toolPart.tool || "unknown"}</span> <span class="tool-name">{toolItem.toolPart.tool || "unknown"}</span>
</div>
<Show when={taskSessionId}>
<button
class="tool-call-header-button"
type="button"
disabled={!taskLocation}
onClick={handleGoToTaskSession}
title={!taskLocation ? "Session not available yet" : "Go to session"}
>
Go to Session
</button>
</Show>
</div>
<ToolCall
toolCall={toolItem.toolPart}
toolCallId={toolItem.key}
messageId={toolItem.messageId}
messageVersion={toolItem.messageVersion}
partVersion={toolItem.partVersion}
instanceId={props.instanceId}
sessionId={props.sessionId}
/>
</div> </div>
<Show when={taskSessionId}> )
<button })()}
class="tool-call-header-button" </Match>
type="button" <Match when={item.type === "step-start"}>
disabled={!taskLocation} <StepCard
onClick={handleGoToTaskSession} kind="start"
title={!taskLocation ? "Session not available yet" : "Go to session"} part={(item as StepDisplayItem).part}
> messageInfo={(item as StepDisplayItem).messageInfo}
Go to Session showAgentMeta
</button> />
</Show> </Match>
</div> <Match when={item.type === "step-finish"}>
<ToolCall <StepCard
toolCall={toolItem.toolPart} kind="finish"
toolCallId={toolItem.key} part={(item as StepDisplayItem).part}
messageId={toolItem.messageId} messageInfo={(item as StepDisplayItem).messageInfo}
messageVersion={toolItem.messageVersion} showUsage={props.showUsageMetrics()}
partVersion={toolItem.partVersion} borderColor={(item as StepDisplayItem).accentColor}
instanceId={props.instanceId} />
sessionId={props.sessionId} </Match>
/> <Match when={item.type === "reasoning"}>
</div> <ReasoningCard
) part={(item as ReasoningDisplayItem).part}
})()} messageInfo={(item as ReasoningDisplayItem).messageInfo}
</Match> instanceId={props.instanceId}
<Match when={item.type === "step-start"}> sessionId={props.sessionId}
<StepCard showAgentMeta={(item as ReasoningDisplayItem).showAgentMeta}
kind="start" defaultExpanded={(item as ReasoningDisplayItem).defaultExpanded}
part={(item as StepDisplayItem).part} />
messageInfo={(item as StepDisplayItem).messageInfo} </Match>
showAgentMeta </Switch>
/> )}
</Match> </For>
<Match when={item.type === "step-finish"}> </div>
<StepCard )}
kind="finish" </Show>
part={(item as StepDisplayItem).part}
messageInfo={(item as StepDisplayItem).messageInfo}
showUsage={props.showUsageMetrics()}
borderColor={(item as StepDisplayItem).accentColor}
/>
</Match>
<Match when={item.type === "reasoning"}>
<ReasoningCard
part={(item as ReasoningDisplayItem).part}
messageInfo={(item as ReasoningDisplayItem).messageInfo}
instanceId={props.instanceId}
sessionId={props.sessionId}
showAgentMeta={(item as ReasoningDisplayItem).showAgentMeta}
defaultExpanded={(item as ReasoningDisplayItem).defaultExpanded}
/>
</Match>
</Switch>
)}
</For>
</div>
) )
} }