@@ -91,6 +91,8 @@ const GO_UPSELL_ACCOUNT_RATE_LIMIT_DONT_SHOW = "go_upsell_account_rate_limit_don
9191const GO_UPSELL_WINDOW = 86_400_000 // 24 hrs
9292const GO_UPSELL_PROVIDERS = new Set ( [ "opencode" , "opencode-go" ] )
9393
94+ export const alwaysSeparate = new WeakSet < BoxRenderable > ( )
95+
9496type RetryAction = Extract < SessionStatus , { type : "retry" } > [ "action" ]
9597
9698function goUpsellKeys ( action : RetryAction ) {
@@ -160,7 +162,6 @@ const context = createContext<{
160162 showTimestamps : ( ) => boolean
161163 showDetails : ( ) => boolean
162164 showGenericToolOutput : ( ) => boolean
163- userMessageIDs : ( ) => ReadonlySet < string >
164165 diffWrapMode : ( ) => "word" | "none"
165166 providers : ( ) => ReadonlyMap < string , Provider >
166167 sync : ReturnType < typeof useSync >
@@ -218,14 +219,6 @@ export function Session() {
218219 )
219220 : [ ] ,
220221 )
221- const userMessageIDs = createMemo (
222- ( ) =>
223- new Set (
224- messages ( )
225- . filter ( ( message ) => message . role === "user" )
226- . map ( ( message ) => message . id ) ,
227- ) ,
228- )
229222 const permissions = createMemo ( ( ) => {
230223 if ( session ( ) ?. parentID ) return [ ]
231224 return children ( ) . flatMap ( ( x ) => sync . data . permission [ x . id ] ?? [ ] )
@@ -1158,7 +1151,6 @@ export function Session() {
11581151 showTimestamps,
11591152 showDetails,
11601153 showGenericToolOutput,
1161- userMessageIDs,
11621154 diffWrapMode,
11631155 providers,
11641156 sync,
@@ -1395,6 +1387,7 @@ function UserMessage(props: {
13951387 < Show when = { text ( ) } >
13961388 < box
13971389 id = { props . message . id }
1390+ ref = { ( el : BoxRenderable ) => alwaysSeparate . add ( el ) }
13981391 border = { [ "left" ] }
13991392 borderColor = { color ( ) }
14001393 customBorderChars = { SplitBorder . customBorderChars }
@@ -1532,7 +1525,7 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
15321525 </ Show >
15331526 < Show when = { props . message . error && props . message . error . name !== "MessageAbortedError" } >
15341527 < box
1535- id = { `assistant-error- ${ props . message . id } ` }
1528+ ref = { ( el : BoxRenderable ) => alwaysSeparate . add ( el ) }
15361529 border = { [ "left" ] }
15371530 paddingTop = { 1 }
15381531 paddingBottom = { 1 }
@@ -1547,7 +1540,7 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
15471540 </ Show >
15481541 < Switch >
15491542 < Match when = { props . last || final ( ) || props . message . error ?. name === "MessageAbortedError" } >
1550- < box id = { `assistant-summary- ${ props . message . id } ` } paddingLeft = { 3 } >
1543+ < box ref = { ( el : BoxRenderable ) => alwaysSeparate . add ( el ) } paddingLeft = { 3 } >
15511544 < text marginTop = { 1 } >
15521545 < span
15531546 style = { {
@@ -1613,7 +1606,7 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass
16131606 return (
16141607 < Show when = { content ( ) } >
16151608 < box
1616- id = { `text- ${ props . part . messageID } - ${ props . part . id } ` }
1609+ ref = { ( el : BoxRenderable ) => alwaysSeparate . add ( el ) }
16171610 paddingLeft = { 3 }
16181611 marginTop = { 1 }
16191612 flexDirection = "column"
@@ -1695,7 +1688,7 @@ function TextPart(props: { last: boolean; part: TextPart; message: AssistantMess
16951688 const { theme, syntax } = useTheme ( )
16961689 return (
16971690 < Show when = { props . part . text . trim ( ) } >
1698- < box id = { `text- ${ props . part . messageID } - ${ props . part . id } ` } paddingLeft = { 3 } marginTop = { 1 } flexShrink = { 0 } >
1691+ < box ref = { ( el : BoxRenderable ) => alwaysSeparate . add ( el ) } paddingLeft = { 3 } marginTop = { 1 } flexShrink = { 0 } >
16991692 < markdown
17001693 syntaxStyle = { syntax ( ) }
17011694 streaming = { true }
@@ -1845,7 +1838,6 @@ function InlineTool(props: {
18451838 pending : string
18461839 failure ?: string
18471840 spinner ?: boolean
1848- subagent ?: boolean
18491841 children : JSX . Element
18501842 part : ToolPart
18511843 onClick ?: ( ) => void
@@ -1886,7 +1878,6 @@ function InlineTool(props: {
18861878
18871879 return (
18881880 < InlineToolRow
1889- id = { `tool-inline-${ props . subagent ? "subagent-" : "" } ${ props . part . messageID } -${ props . part . id } ` }
18901881 icon = { props . icon }
18911882 iconColor = { props . iconColor }
18921883 color = { fg ( ) }
@@ -1899,8 +1890,6 @@ function InlineTool(props: {
18991890 pending = { props . pending }
19001891 failure = { props . failure }
19011892 spinner = { props . spinner }
1902- subagent = { props . subagent }
1903- separateAfter = { ( id ) => id !== undefined && ctx . userMessageIDs ( ) . has ( id ) }
19041893 onMouseOver = { ( ) => clickable ( ) && setHover ( true ) }
19051894 onMouseOut = { ( ) => setHover ( false ) }
19061895 onMouseUp = { ( ) => {
@@ -1918,7 +1907,6 @@ function InlineTool(props: {
19181907}
19191908
19201909export function InlineToolRow ( props : {
1921- id ?: string
19221910 icon : string
19231911 iconColor ?: RGBA
19241912 color ?: RGBA
@@ -1931,32 +1919,20 @@ export function InlineToolRow(props: {
19311919 pending : string
19321920 failure ?: string
19331921 spinner ?: boolean
1934- subagent ?: boolean
19351922 children : JSX . Element
1936- separateAfter ?: ( id : string | undefined ) => boolean
19371923 onMouseOver ?: ( ) => void
19381924 onMouseOut ?: ( ) => void
19391925 onMouseUp ?: ( ) => void
19401926} ) {
19411927 return (
19421928 < box
1943- id = { props . id }
19441929 paddingLeft = { 3 }
19451930 onMouseOver = { props . onMouseOver }
19461931 onMouseOut = { props . onMouseOut }
19471932 onMouseUp = { props . onMouseUp }
19481933 ref = { ( el : BoxRenderable ) => {
19491934 setPreLayoutSiblingMargin ( el , ( previous ) => {
1950- const previousInline = previous ?. id . startsWith ( "tool-inline-" ) ?? false
1951- const previousSubagent = previous ?. id . startsWith ( "tool-inline-subagent-" ) ?? false
1952- return previous ?. id . startsWith ( "text-" ) ||
1953- previous ?. id . startsWith ( "tool-block-" ) ||
1954- previous ?. id . startsWith ( "assistant-error-" ) ||
1955- previous ?. id . startsWith ( "assistant-summary-" ) ||
1956- ( previousInline && previousSubagent !== Boolean ( props . subagent ) ) ||
1957- props . separateAfter ?.( previous ?. id )
1958- ? 1
1959- : 0
1935+ return previous instanceof BoxRenderable && ( previous . height > 1 || alwaysSeparate . has ( previous ) ) ? 1 : 0
19601936 } )
19611937 } }
19621938 >
@@ -2018,7 +1994,7 @@ function BlockTool(props: {
20181994 const error = createMemo ( ( ) => ( props . part ?. state . status === "error" ? props . part . state . error : undefined ) )
20191995 return (
20201996 < box
2021- id = { props . part ? `tool-block- ${ props . part . messageID } - ${ props . part . id } ` : undefined }
1997+ ref = { ( el : BoxRenderable ) => alwaysSeparate . add ( el ) }
20221998 border = { [ "left" ] }
20231999 paddingTop = { 1 }
20242000 paddingBottom = { 1 }
@@ -2184,8 +2160,8 @@ function Read(props: ToolProps) {
21842160 Read { pathFormatter . format ( stringValue ( props . input . filePath ) ) } { input ( props . input , [ "filePath" ] ) }
21852161 </ InlineTool >
21862162 < For each = { loaded ( ) } >
2187- { ( filepath , index ) => (
2188- < box id = { `tool-inline-loaded- ${ props . part . messageID } - ${ props . part . id } - ${ index ( ) } ` } paddingLeft = { 3 } >
2163+ { ( filepath ) => (
2164+ < box paddingLeft = { 3 } >
21892165 < text paddingLeft = { 3 } fg = { theme . textMuted } >
21902166 ↳ Loaded { pathFormatter . format ( filepath ) }
21912167 </ text >
@@ -2305,7 +2281,6 @@ function Task(props: ToolProps) {
23052281 return (
23062282 < InlineTool
23072283 icon = { props . part . state . status === "completed" ? "✓" : "│" }
2308- subagent = { true }
23092284 color = { retry ( ) ? theme . error : undefined }
23102285 spinner = { isRunning ( ) }
23112286 complete = { stringValue ( props . input . description ) }
0 commit comments