mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 09:59:03 +08:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Small Assistant terminal-state fixes. ## Stack context This stack is based on #49352 (`chore/assistant-tool-outcomes`) and assumes #49350–#49352 merge first. Review bottom to top: 1. #49361 — assistant notebook run tool 2. #49362 — assistant notebook run UI 3. #49364 — terminal-state polish ## What is the current behavior? Completed notebook updates can be re-diffed against newer live content, and log-query failures can use SQL-specific or empty fallback UI. ## What is the new behavior? - Replaces completed notebook update previews with a stable success/error/skipped summary. - Keeps the Open notebook action on successful updates. - Uses logs-specific failure copy for Assistant log queries. - Shows an explicit fallback when a failed log tool input or output cannot be parsed. ## How to test manually ### Notebook update terminal states 1. Ask the AI Assistant to update an existing notebook, then approve the proposal. 2. Confirm the proposal becomes a compact **Notebook updated: [name]** summary instead of re-diffing against the newly saved notebook. 3. Click **Open notebook** and confirm it opens the updated notebook. 4. Request another notebook update and click **Skip**. Confirm the terminal summary says **Skipped notebook update**. 5. Refresh or reopen the conversation and confirm both summaries remain stable. ### Logs failure copy 1. Ask the Assistant to query Logs with an intentionally invalid table or column and approve the query. 2. Confirm the failed result says **Failed to query logs**, not **Failed to execute SQL**. 3. Confirm the failed tool remains visible rather than disappearing when its result cannot be rendered. ## Automated test The focused top-of-stack suite passes 9 test files and 85 tests. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added clearer failure messaging when query logs contain invalid input, missing results, or errors. - Added compact summaries for completed, failed, and skipped notebook updates. - Notebook update summaries include an “Open notebook” link when applicable. - **Bug Fixes** - Improved handling and display of query-log failures instead of showing blank content. - Preserved detailed previews for notebook updates that are still in progress. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import { screen } from '@testing-library/react'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
|
|
import { MessageProvider } from './Message.Context'
|
|
import { MessagePartQueryLogs } from './MessagePartQueryLogs'
|
|
import { customRender as render } from '@/tests/lib/custom-render'
|
|
|
|
vi.mock('@/components/interfaces/Explorer/QueryEditor', () => ({
|
|
QueryEditor: ({
|
|
query,
|
|
result,
|
|
}: {
|
|
query: { uncheckedSql: string }
|
|
result?: { error?: { message?: string } }
|
|
}) => (
|
|
<div data-testid="query-editor">
|
|
<span>{query.uncheckedSql}</span>
|
|
<span>{result?.error?.message}</span>
|
|
</div>
|
|
),
|
|
}))
|
|
vi.mock('@/lib/telemetry/track', () => ({ useTrack: () => vi.fn() }))
|
|
vi.mock('@/state/role-impersonation-state', () => ({
|
|
useLocalRoleImpersonationState: () => ({}),
|
|
}))
|
|
|
|
type QueryLogsToolPart = Parameters<typeof MessagePartQueryLogs>[0]['toolPart']
|
|
|
|
const messageInfo = {
|
|
id: 'message-1',
|
|
isLoading: false,
|
|
state: 'idle' as const,
|
|
}
|
|
|
|
const messageActions = {
|
|
onDelete: vi.fn(),
|
|
onEdit: vi.fn(),
|
|
onBranch: vi.fn(),
|
|
onCancelEdit: vi.fn(),
|
|
}
|
|
|
|
function renderPart(toolPart: Parameters<typeof MessagePartQueryLogs>[0]['toolPart']) {
|
|
return render(
|
|
<MessageProvider messageInfo={messageInfo} messageActions={messageActions}>
|
|
<MessagePartQueryLogs toolPart={toolPart} />
|
|
</MessageProvider>
|
|
)
|
|
}
|
|
|
|
describe('MessagePartQueryLogs', () => {
|
|
it('renders an output error using raw input when submitted input is unavailable', () => {
|
|
renderPart({
|
|
toolCallId: 'query-logs-1',
|
|
state: 'output-error',
|
|
input: undefined,
|
|
rawInput: { sql: 'select count(*) from edge_logs' },
|
|
errorText: 'Log query timed out',
|
|
} as QueryLogsToolPart)
|
|
|
|
expect(screen.getByText('select count(*) from edge_logs')).toBeInTheDocument()
|
|
expect(screen.getByText('Log query timed out')).toBeInTheDocument()
|
|
})
|
|
|
|
it('uses logs-specific copy for a rendered tool error', () => {
|
|
renderPart({
|
|
toolCallId: 'logs-1',
|
|
state: 'output-error',
|
|
input: { sql: 'select event_message from edge_logs' },
|
|
output: undefined,
|
|
errorText: 'Analytics request failed',
|
|
})
|
|
|
|
expect(screen.getByText('Failed to query logs')).toBeInTheDocument()
|
|
expect(screen.queryByText('Failed to execute SQL')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('shows an explicit failure when errored input cannot be parsed', () => {
|
|
renderPart({
|
|
toolCallId: 'logs-2',
|
|
state: 'output-error',
|
|
input: { invalid: true },
|
|
output: undefined,
|
|
errorText: 'Analytics request failed',
|
|
})
|
|
|
|
expect(screen.getByText('Failed to query logs.')).toBeInTheDocument()
|
|
})
|
|
})
|