Make MessageBlock rerender via keyed Show
This commit is contained in:
@@ -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>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user