fix thinking tool rows to fill chat width
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s

This commit is contained in:
2026-10-22 15:08:36 +08:00
parent 3ca960f388
commit 99e5687ce0
3 changed files with 56 additions and 1 deletions
@@ -0,0 +1,16 @@
---
date: 2026-10-22
feature: Thinking tool call row width
impact: Use the available chat width instead of a fixed 520px row
---
PR/commit: pending.
MessageList tool-call rows now use 100% of their panel width. The existing
flex shrinking, ellipsis and max-width rules keep long arguments within the
viewport. This also applies to the compression and abort status rows sharing
the same class. Assistant reply sizing and chat events are unchanged.
Validation: Playwright reproduces the fixed-width failure and passes after the
change at 1920px, 900px and 390px, including long tool arguments and overflow
checks. Production build and harness checks pass.
@@ -1502,7 +1502,7 @@ defineExpose({
display: flex;
align-items: center;
gap: 6px;
width: 520px;
width: 100%;
max-width: 100%;
min-width: 0;
box-sizing: border-box;
+39
View File
@@ -0,0 +1,39 @@
import { expect, test } from '@playwright/test'
import { authenticate, mockChatSocket, mockHermesApi, TEST_ACCESS_KEY } from './fixtures'
test('thinking tool rows fill the chat width and shrink without overflowing', async ({ page }) => {
await page.setViewportSize({ width: 1920, height: 1080 })
await authenticate(page, TEST_ACCESS_KEY, 'research')
await mockHermesApi(page)
await mockChatSocket(page)
await page.goto('/#/hermes/chat')
await page.locator('textarea.input-textarea').fill('Inspect the working directory')
await page.getByRole('button', { name: 'Send', exact: true }).click()
await page.waitForFunction(() => (window as any).__PW_CHAT_SOCKET__?.emitted.some((event: any) => event.event === 'run'))
await page.evaluate(() => {
const state = (window as any).__PW_CHAT_SOCKET__
const sid = state.emitted.find((event: any) => event.event === 'run').payload.session_id
const common = { session_id: sid, run_id: 'width-run' }
state.latest.__trigger('run.started', { ...common, event: 'run.started' })
state.latest.__trigger('tool.started', {
...common, event: 'tool.started', tool_call_id: 'width-tool', tool: 'terminal',
preview: 'Read a long project path and inspect the current repository state '.repeat(30),
arguments: JSON.stringify({ command: 'git status --short' }),
})
})
const panel = page.locator('.tool-calls-panel')
const row = panel.locator('.tool-call-item').first()
await expect(row).toBeVisible()
for (const width of [1920, 900, 390]) {
await page.setViewportSize({ width, height: 1080 })
await expect.poll(async () => {
const panelBox = await panel.boundingBox()
const rowBox = await row.boundingBox()
return panelBox && rowBox ? Math.abs(rowBox.width - panelBox.width) : Infinity
}).toBeLessThan(2)
const fits = await panel.evaluate(element => element.scrollWidth <= element.clientWidth + 1)
expect(fits).toBe(true)
const box = await row.boundingBox()
expect(box!.x + box!.width).toBeLessThanOrEqual(width)
}
})