Make MessageBlock output reactive via Show
This commit is contained in:
@@ -226,12 +226,6 @@ export default function MessageStreamV2(props: MessageStreamV2Props) {
|
|||||||
const store = createMemo(() => messageStoreBus.getOrCreate(props.instanceId))
|
const store = createMemo(() => messageStoreBus.getOrCreate(props.instanceId))
|
||||||
const messageIds = createMemo(() => store().getSessionMessageIds(props.sessionId))
|
const messageIds = createMemo(() => store().getSessionMessageIds(props.sessionId))
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
const ids = messageIds()
|
|
||||||
console.info("[MessageStreamV2] messageIds", { sessionId: props.sessionId, ids })
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const sessionRevision = createMemo(() => store().getSessionRevision(props.sessionId))
|
const sessionRevision = createMemo(() => store().getSessionRevision(props.sessionId))
|
||||||
const usageSnapshot = createMemo(() => store().getSessionUsage(props.sessionId))
|
const usageSnapshot = createMemo(() => store().getSessionUsage(props.sessionId))
|
||||||
const sessionInfo = createMemo(() =>
|
const sessionInfo = createMemo(() =>
|
||||||
@@ -703,7 +697,6 @@ function MessageBlock(props: MessageBlockProps) {
|
|||||||
const block = createMemo<MessageDisplayBlock | null>(() => {
|
const block = createMemo<MessageDisplayBlock | null>(() => {
|
||||||
const current = record()
|
const current = record()
|
||||||
if (!current) {
|
if (!current) {
|
||||||
console.warn("[MessageBlock] missing record", { messageId: props.messageId, sessionId: props.sessionId })
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -877,107 +870,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