Merge pull request #65142 from NousResearch/bb/fix-image-tool-overflow

fix(desktop): keep generated images out of tool overflow
This commit is contained in:
brooklyn! 2026-07-15 14:13:16 -04:00 committed by GitHub
commit 91f87137b6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 7 deletions

View file

@ -1,13 +1,24 @@
import { describe, expect, it } from 'vitest'
import { shouldBoundToolGroup } from './fallback'
import { shouldBoundToolGroup, UNBOUNDABLE_TOOLS } from './fallback'
describe('shouldBoundToolGroup', () => {
it('bounds long runs of ordinary tool calls', () => {
expect(shouldBoundToolGroup(3, false)).toBe(true)
})
it('never bounds a run containing clarify', () => {
it('leaves short runs unbounded', () => {
expect(shouldBoundToolGroup(2, false)).toBe(false)
})
it('never bounds a run holding an unboundable tool', () => {
expect(shouldBoundToolGroup(3, true)).toBe(false)
})
})
describe('UNBOUNDABLE_TOOLS', () => {
it('exempts clarify forms and generated images from the window', () => {
expect(UNBOUNDABLE_TOOLS.has('clarify')).toBe(true)
expect(UNBOUNDABLE_TOOLS.has('image_generate')).toBe(true)
})
})

View file

@ -611,8 +611,13 @@ function ToolEntry({ part }: ToolEntryProps) {
// auto-scrolling window; fewer than this stays a plain inline stack.
const TOOL_GROUP_SCROLL_THRESHOLD = 3
export function shouldBoundToolGroup(childCount: number, containsClarify: boolean) {
return childCount >= TOOL_GROUP_SCROLL_THRESHOLD && !containsClarify
// Tools whose body (an interactive form, a full-size image) must never be
// trapped behind the window's max-height + fade mask. A run holding any of
// them stays a plain, fully-visible stack no matter how long it is.
export const UNBOUNDABLE_TOOLS = new Set(['clarify', 'image_generate'])
export function shouldBoundToolGroup(childCount: number, hasUnboundable: boolean) {
return childCount >= TOOL_GROUP_SCROLL_THRESHOLD && !hasUnboundable
}
// Pin-to-bottom + top-fade for the bounded tool window. Pins the newest row on
@ -688,15 +693,15 @@ export const ToolGroupSlot: FC<PropsWithChildren<{ endIndex: number; startIndex:
const messageId = useAuiState(s => s.message.id)
const messageRunning = useAuiState(selectMessageRunning)
const containsClarify = useAuiState(s =>
const hasUnboundable = useAuiState(s =>
s.message.parts
.slice(Math.max(0, startIndex), endIndex + 1)
.some(part => part.type === 'tool-call' && part.toolName === 'clarify')
.some(part => part.type === 'tool-call' && UNBOUNDABLE_TOOLS.has(part.toolName))
)
const enterRef = useEnterAnimation(messageRunning, `tool-group:${messageId}:${startIndex}`)
const bounded = shouldBoundToolGroup(Children.count(children), containsClarify)
const bounded = shouldBoundToolGroup(Children.count(children), hasUnboundable)
const { contentRef, faded, onScroll, scrollRef } = useToolWindow(bounded)
return (