feat(chat): collapse tool calls by run
This commit is contained in:
@@ -8,7 +8,8 @@ describe('groupRunMessages', () => {
|
||||
it('groups text across tool calls and marks completion only when the run ends', () => {
|
||||
const input = [message('u', 'user', 'question'), message('a', 'assistant', 'first'), message('t', 'tool'), message('b', 'assistant', 'second')]
|
||||
const active = groupRunMessages(input, true)
|
||||
expect(active.map(m => m.role)).toEqual(['user', 'assistant', 'tool'])
|
||||
expect(active.map(m => m.role)).toEqual(['user', 'assistant', 'system'])
|
||||
expect(active[2]).toMatchObject({ systemType: 'tool-group', toolMessages: [input[2]] })
|
||||
expect(active[1]).toMatchObject({ id: 'b', content: 'first\n\nsecond' })
|
||||
const finished = groupRunMessages(input, false)
|
||||
expect(finished.at(-1)?.systemType).toBe('run-end')
|
||||
@@ -19,4 +20,10 @@ describe('groupRunMessages', () => {
|
||||
expect(groupRunMessages(input, false).filter(m => m.role === 'assistant').map(m => m.content)).toEqual(['one', 'two', 'three'])
|
||||
expect(groupRunMessages(input, false).filter(m => m.systemType === 'run-end')).toHaveLength(3)
|
||||
})
|
||||
|
||||
it('keeps tool calls grouped within their own turn', () => {
|
||||
const input = [message('u', 'user'), message('a', 'tool'), message('b', 'tool'), message('u2', 'user'), message('c', 'tool')]
|
||||
const groups = groupRunMessages(input, false).filter(m => m.systemType === 'tool-group')
|
||||
expect(groups.map(group => group.toolMessages?.map(tool => tool.id))).toEqual([['a', 'b'], ['c']])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -316,6 +316,9 @@ test('renders tool trace and sends explicit approval decisions over the chat-run
|
||||
})
|
||||
}, run.session_id)
|
||||
|
||||
await expect(page.locator('.live-tool-group')).not.toHaveAttribute('open', '')
|
||||
await expect(page.getByText('write_file', { exact: true })).toBeHidden()
|
||||
await page.locator('.live-tool-group > summary').click()
|
||||
await expect(page.getByText('write_file', { exact: true })).toBeVisible()
|
||||
await expect(page.getByText('Writing approved file')).toBeVisible()
|
||||
await expect(page.locator('.message.tool .tool-line')).toHaveCount(0)
|
||||
@@ -393,6 +396,8 @@ test('renders tool trace and sends explicit approval decisions over the chat-run
|
||||
|
||||
const persistedToolTrace = page.locator('.message.tool .tool-line').filter({ hasText: 'write_file' })
|
||||
await expect(persistedToolTrace).toHaveCount(1)
|
||||
await expect(persistedToolTrace).toBeHidden()
|
||||
await page.locator('.tool-group:not(.live-tool-group) > summary').click()
|
||||
await persistedToolTrace.click()
|
||||
const toolDetails = page.locator('.message.tool .tool-details')
|
||||
await expect(toolDetails).toContainText('/tmp/approved.txt')
|
||||
@@ -593,6 +598,8 @@ test('keeps completed same-run tool traces hidden until the run finishes', async
|
||||
await expect(page.locator('.tool-calls-panel .tool-call-name').filter({ hasText: 'read_file' })).toHaveCount(0)
|
||||
await expect(page.locator('.tool-calls-panel .tool-call-name').filter({ hasText: 'shell_exec' })).toHaveCount(0)
|
||||
await expect(page.locator('.message.tool .tool-error-badge')).toHaveCount(1)
|
||||
await expect(page.locator('.tool-group:not(.live-tool-group) > summary')).toHaveText('Tool calls (2)')
|
||||
await page.locator('.tool-group:not(.live-tool-group) > summary').click()
|
||||
await transcriptTools.filter({ hasText: 'shell_exec' }).click()
|
||||
await expect(page.locator('.message.tool .tool-details')).toContainText('exit status 1')
|
||||
await expect(page.getByText('Multi-tool fallback should stay hidden.')).toHaveCount(0)
|
||||
@@ -849,6 +856,8 @@ test('restores named resumed tool traces from assistant tool calls after session
|
||||
await expect(page.getByText('Named history answer visible.')).toBeVisible()
|
||||
const restoredTrace = page.locator('.message.tool .tool-line').filter({ hasText: 'read_file' })
|
||||
await expect(restoredTrace).toHaveCount(1)
|
||||
await expect(restoredTrace).toBeHidden()
|
||||
await page.locator('.tool-group > summary').click()
|
||||
await restoredTrace.click()
|
||||
await expect(page.locator('.message.tool .tool-details')).toContainText('/tmp/history.txt')
|
||||
expect(api.unexpectedRequests).toEqual([])
|
||||
|
||||
Reference in New Issue
Block a user