{ if (Date.now() > settleUntil) { pinned = nearBottom(); } }} bind:this={scroller} >
{#if failure} {:else if messages === null}

Loading the thread…

{:else if messages.length === 0 && tail.length === 0} {:else} {#each messages as message, index (index)} {@const parts = blocks(message)} {@const isResultOnly = parts.every((b) => b.type === "tool_result")} {@const system = systemText(message)} {@const newDay = message.ts && dayOf(message.ts) !== dayOf(messages[index - 1]?.ts)} {@const newMinute = message.ts && minuteOf(message.ts) !== minuteOf(messages[index - 1]?.ts)} {@const spoken = message.role === "user" || parts.some((b) => b.type === "text" && Boolean(b.text))} {#if newDay}

{fmtDateTime(message.ts).replace(DAY_TIME, "")}

{/if} {#if system}
{#if message.ts} {minuteOf(message.ts)} {/if}
{:else if !(isResultOnly && !showResults)}
{#if message.ts && (newMinute || spoken) && !isResultOnly} {minuteOf(message.ts)} {/if} {#each parts as block, blockIndex (blockIndex)} {#if block.type === "text" && block.text} {:else if block.type === "tool_use"}

{toolLabel(block.name ?? "?")} {clip(summarizeInput(block.name ?? "", block.input), 160)}

{:else if block.type === "tool_result" && showResults}
{clip(resultText(block), RESULT_CLIP)}
{:else if block.type === "thinking"}

thinking

{/if} {/each}
{/if} {/each} {/if} {#if model.question} {/if} {#each tail as turn (turn.id)} {/each}