mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 18:11:51 +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? Feature and bug fix. ## What is the current behavior? The assistant can call `query_logs`, but it is not given the ClickHouse schema and query-writing guidance it needs. It also lacks a current UTC reference for producing the absolute timestamps required by the tool, which can lead to valid queries being run against the wrong time range and reported as returning zero rows. ## What is the new behavior? - Adds a dedicated `logs` knowledge topic backed by the shared ClickHouse schema and query guidance. - Requires the assistant to load that knowledge before using `query_logs`. - Includes the current UTC time in project context so relative requests can be converted to correct absolute tool parameters. - Covers the new knowledge flow and context with focused tests and updates the assistant eval expectation. ## How to test 1. Check out this PR and run Studio against a project that has recent logs. Generate some project activity first, such as an API request, if needed. 2. Open the AI Assistant and ask: `Show log counts by minute for the last 15 minutes and summarize any spikes.` 3. Expand the assistant's tool activity and verify it loads the `logs` knowledge topic before calling `query_logs`. 4. Inspect the `query_logs` input and verify: - `iso_timestamp_start` and `iso_timestamp_end` are absolute UTC timestamps ending in `Z`. - The timestamps cover approximately the requested 15-minute window. - The SQL uses ClickHouse syntax, includes a `LIMIT`, and does not put the time range in the SQL `WHERE` clause. 5. Verify the assistant's summary reflects the rows returned by `query_logs` instead of reporting zero rows when results are present. ## Additional context This is the bottom PR in stack #49294. The front-end visualization is added separately in #49293. Verified with 59 focused tests across assistant context, Studio/MCP tools, query display, and logs result parsing. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added AI-assisted project log querying through the `query_logs` tool. - Added logs knowledge guidance for time ranges, schema discovery, query limits, and concise result summaries. - Project context now includes the current UTC timestamp to improve relative time-range interpretation. - Improved notebook assistance with safer table verification and appropriate handling of log queries. - **Bug Fixes** - Prevented incorrect SQL timestamp filtering and enabled cross-service searches without requiring a source filter. - Added validation for supported knowledge topics. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
83 lines
3.9 KiB
TypeScript
83 lines
3.9 KiB
TypeScript
import {
|
|
buildClickhouseLogsSchemaSection,
|
|
CLICKHOUSE_LOGS_COMPLETION_INSTRUCTIONS,
|
|
} from '@/lib/ai/clickhouse-logs'
|
|
|
|
/**
|
|
* Stands in for the schema list when the org hasn't opted into sharing schemas.
|
|
* Doubles as a sentinel — "no project context worth sending" is decided by
|
|
* comparing against this exact sentence — so the producer and the comparison have
|
|
* to agree on it, hence one exported constant instead of copies per call site.
|
|
*/
|
|
export const NO_SCHEMA_ACCESS_MESSAGE = "You don't have access to any schemas."
|
|
|
|
/**
|
|
* A request-scoped context message, sent as an assistant turn ahead of the
|
|
* conversation. Deliberately NOT part of the system prompt: the system prompt is
|
|
* static so Bedrock can cache it, and anything derived from the current project,
|
|
* chat, or open editor tab would break that cache.
|
|
*/
|
|
export type AssistantContextMessage = { role: 'assistant'; content: string }
|
|
|
|
/**
|
|
* Tells the model that the snippet in the SQL editor targets the logs backend, so
|
|
* SQL it writes for that snippet comes back as ClickHouse for the `logs` table
|
|
* rather than Postgres. Carries the same dialect rules and table reference the
|
|
* inline editor completions use, so there's one description of the logs schema.
|
|
*/
|
|
function buildLogsSnippetContext(): string {
|
|
return [
|
|
"Some SQL snippets are marked with the dialect 'clickhouse', which means they query the Supabase logs backend, not the Postgres database. Any SQL you write, edit, or debug for that snippet must be ClickHouse SQL against the logs table described below — the database schema and the Postgres tools don't apply to it. To run a logs query, load `logs` knowledge then call `query_logs`; do not use `execute_sql`. Postgres SQL is still the right answer for anything else the user asks about their database, or for non-ClickHouse marked queries.",
|
|
CLICKHOUSE_LOGS_COMPLETION_INSTRUCTIONS.trim(),
|
|
buildClickhouseLogsSchemaSection().trim(),
|
|
].join('\n\n')
|
|
}
|
|
|
|
/**
|
|
* Assemble the context messages that precede the conversation: what project and
|
|
* chat this is, whether it's a support chat, and which backend the open SQL editor
|
|
* snippet targets. Pure and per-request — see {@link AssistantContextMessage} for
|
|
* why none of this belongs in the system prompt.
|
|
*/
|
|
export function buildAssistantContextMessages({
|
|
projectRef,
|
|
chatName,
|
|
schemasString,
|
|
supportMode,
|
|
includesLogsSnippets,
|
|
now = new Date(),
|
|
}: {
|
|
projectRef?: string
|
|
chatName?: string
|
|
schemasString: string
|
|
supportMode?: boolean
|
|
/** Whether any user message in the conversation attached a logs (ClickHouse) query. */
|
|
includesLogsSnippets?: boolean
|
|
/** Injected so tests can pin the clock. Lives here, not the system prompt, so Bedrock can cache the system prompt. */
|
|
now?: Date
|
|
}): AssistantContextMessage[] {
|
|
const messages: AssistantContextMessage[] = []
|
|
|
|
const hasProjectContext = !!projectRef || !!chatName || schemasString !== NO_SCHEMA_ACCESS_MESSAGE
|
|
if (hasProjectContext) {
|
|
messages.push({
|
|
role: 'assistant',
|
|
content: `The user's current project is ${projectRef || 'unknown'}. Their available schemas are: ${schemasString}. The current chat name is: ${chatName || 'unnamed'}. The current time is ${now.toISOString()} (UTC). Use this clock when converting relative ranges such as "last hour" into iso_timestamp_start and iso_timestamp_end.`,
|
|
})
|
|
}
|
|
|
|
if (supportMode) {
|
|
messages.push({
|
|
role: 'assistant',
|
|
content:
|
|
'This is an active support chat. Help the user while they wait for a human agent. Keep guidance practical and concise. If the user asks for a human, or if the issue cannot be safely resolved, call escalate_to_human with a short reason. Only call resolve_support_conversation after the user explicitly confirms the issue is resolved; otherwise keep helping.',
|
|
})
|
|
}
|
|
|
|
if (includesLogsSnippets) {
|
|
messages.push({ role: 'assistant', content: buildLogsSnippetContext() })
|
|
}
|
|
|
|
return messages
|
|
}
|