mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
e0280cb650d29ded05c080e35a52d22bf9dd84b9
513
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e0280cb650 |
docs: restructure observability navigation and overview (#49505)
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Stack Draft stack extracted from `docs/monitoring`. Merge bottom-up. The troubleshooting *catalog* rewrite (`content/troubleshooting` and the Diagnosing UI) stays out of scope. 1. #49503 move inspect and advisors 2. #49501 split Studio logs from ClickHouse queries 3. #49500 treat reports as signal dashboards 4. #49502 add Observe the data hub 5. #49506 add agent setup components 6. #49504 add hire-an-agent templates 7. **#49505** restructure observability nav, overview, Detecting, and flatten Observe the data ← **this PR** ## 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? Docs update. Top layer in the observability stack. ## What is the current behavior? The section is still titled Monitoring and Debugging, with a Debugging / Monitoring split that does not match the new pages. The debugging guide is still the master layer-isolation + symptom table. Observe the data is split into “what data” vs “where to observe it,” which duplicates the source pages. ## What is the new behavior? - Section title is Observability - Overview groups Observe the data, Detect and resolve, Hire an agent, and Export - **Observe the data is flattened by source.** Logs, Metrics API, Database, Advisors, and Reports each list where to read that source. There is no separate MCP/API/CLI/Studio nav group. - **Observe vs Detecting:** Observe is the catalog (what exists, how to access it). Detecting is how to *use* those sources to pick up a Health / Security / Performance / Usage signal. Named errors skip to Diagnosing. - Studio Logs sits under Logs. Reports sits beside the other sources. - Troubleshooting stays in the global menu and also appears as Diagnosing under Detect and resolve ## Additional context This is the last PR in the stack. Together the seven PRs reconstruct the `docs/monitoring` observability IA and guide content, without shipping the troubleshooting catalog overhaul. <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-a3cb5ece-925b-4046-b58a-5d69e9a9d794?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-a3cb5ece-925b-4046-b58a-5d69e9a9d794&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Saxon Fletcher <SaxonF@users.noreply.github.com> Co-authored-by: Nik Richers <nik@validmind.ai> |
||
|
|
0bbd64743c |
docs: move inspect and advisors into observability (#49503)
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Stack Draft stack extracted from `docs/monitoring`. Merge bottom-up. Troubleshooting / debugging-guide rewrite is out of scope. 1. **#49503** move inspect and advisors ← **this PR** 2. #49501 split Studio logs from ClickHouse queries 3. #49500 treat reports as signal dashboards 4. #49502 add Observe the data hub 5. #49506 add agent setup components 6. #49504 add hire-an-agent templates 7. #49505 restructure observability nav and overview ## 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? Docs update. First layer in the observability stack. ## What is the current behavior? Inspect and advisors live under Database (`/guides/database/inspect`, `/guides/database/database-advisors`). Observability readers have to leave the monitoring section to find them. ## What is the new behavior? - Moves inspect into `/guides/monitoring-and-debugging/inspect` - Adds `/guides/monitoring-and-debugging/advisors` (replaces the Database Advisors page) - Adds redirects and updates Studio/docs links so old URLs keep working - Adds both pages to the existing Monitoring nav so they are discoverable before the later IA PR ## Additional context Inspect and advisors pages render as standard MDX. Redirects cover `/docs/guides/database/inspect`, `/docs/guides/database/database-advisors`, and `/docs/guides/database/database-linter`. Debugging-guide content is unchanged except the inspect URL. ## Self-review - No leftover `/guides/database/inspect` or `/guides/database/database-advisors` links in docs guides or Studio linter/AI surfaces (historical blog posts left as-is) - Smoke test path updated to `/docs/guides/monitoring-and-debugging/advisors` <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-a3cb5ece-925b-4046-b58a-5d69e9a9d794?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-a3cb5ece-925b-4046-b58a-5d69e9a9d794&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a centralized Advisors guide for security and performance checks. - Updated database inspection guidance with live Postgres statistics, cache hit-rate context, and query-analysis resources. - **Documentation** - Reorganized Advisors and database inspection content under Monitoring and Debugging. - Updated navigation, cross-references, in-product help links, and CLI documentation links. - Added permanent redirects from previous documentation URLs to preserve access. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Saxon Fletcher <SaxonF@users.noreply.github.com> Co-authored-by: Nik Richers <nik@validmind.ai> |
||
|
|
5db8a0e960 |
feat(studio): instrument sign-in attempts and failures (#49853)
The /sign-in page emitted only a pageview on entry and the success-side `sign_in` event on exit: failed or abandoned attempts were invisible, so "never interacted" and "tried and failed silently" could not be told apart in the sign-in funnel. I added an unsampled `sign_in_submitted` event at every initiation point and classified failure capture via `dashboard_error_created` with a new `signin` origin. **Changed:** - **Submit attempts observable**: `sign_in_submitted` (method: `email`, provider id, `sso`, or partner) fires from the DOM submit handler on the password and SSO forms (so submits that fail client-side validation still count), and from the OAuth, custom-provider, and partner initiation handlers. - **Failures classified**: each sign-in error path feeds the existing funnel-error pipe with origin `signin` and a controlled reason slug (`invalid_credentials`, `email_not_confirmed`, `captcha_failed`, `sso_provider_not_found`, ...). GoTrue auth errors now classify via their numeric `status`, guarded so transport failures (`status: 0`) stay `network_error`. - **Attempt events survive the OAuth redirect**: the telemetry event POST sends with `keepalive` (scoped to `sign_in_submitted`, since keepalive requests share a per-page in-flight body quota), so a dispatched request is no longer aborted by the provider navigation; send rejections are caught centrally instead of surfacing as unhandled rejections. The fetch still dispatches after an async token lookup, so preview testing verifies the GitHub-path event actually lands on the wire. - **Captcha rejection is no longer silent**: a rejected hCaptcha challenge resolves the stuck loading toast with an error message, emits `captcha_challenge_failed` (distinct from `captcha_failed`, which stays reserved for the auth server rejecting a submitted token), reports to error monitoring, and resets the captcha widget (previously: unhandled promise rejection and a spinner that never resolved). - **Partner method validated**: the partner sign-in page resolves the URL-hash value against the provider registry and forwards the canonical provider id into `method` on both `sign_in_submitted` and `sign_in`; anything unregistered records as `unregistered_partner`, so a crafted link can't poison the breakdown on either event. **Note:** failure events stay on the shared 10% `dashboard_error_created` sampling rate (a per-origin carve-out would break cross-source volume comparability); the unsampled attempt event carries the tried-vs-never-interacted signal at full volume. ## To test Tested on Vercel preview (studio-staging, wire-level network capture + staging ingestion check): - [x] On `/sign-in`, submit a bogus email + password: expect a `POST */platform/telemetry/event` request with `action: sign_in_submitted`, `method: email` in the network tab, plus an error toast. Observed: 201, auth returned 400 as expected. - [x] Submit with an empty password: expect `sign_in_submitted` to still fire (validation failures count as attempts). Observed: event fired with 201 and no auth call followed. - [x] Click "Continue with GitHub": expect `sign_in_submitted` with `method: github` on the wire before the provider redirect. Observed: the POST completed (201) before the browser landed on github.com, so the keepalive path holds. - [x] Negative case: fresh page load with no interaction fires no `sign_in_submitted`. - [x] Ingestion: all fired events (methods `email`, `github`, plus organic `sso` submits from a real login on the same preview) arrived in the staging project with the expected properties. - [x] Re-ran the email and GitHub paths on the scoped-keepalive build (`129bf8d`): both `sign_in_submitted` POSTs returned 201 (the GitHub one completed despite the provider redirect), and both events ingested into the staging project with the expected `method`/`category` properties. ## Linear - GROWTH-1165 (no `fixes` keyword on purpose: the evidence checks run on prod data post-deploy, and the issue closes manually after they pass) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved sign-in protection with more reliable invisible CAPTCHA handling. * Added sign-in submission tracking across password, SSO, partner, custom OAuth, and external-provider flows. * Added detailed classification for authentication, validation, CAPTCHA, provider, and network errors. * **Bug Fixes** * Sign-in now stops safely and resets CAPTCHA when verification fails. * Improved error reporting for failed sign-in attempts, including redirects and OAuth flows. * Ensured sign-in telemetry is delivered reliably during OAuth redirects. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9b17ce8f2c |
chore(studio): default assistant to GPT-5.6 Luna (#49749)
## 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 / chore: hide assistant model selection in the UI and default chats to GPT-5.6 Luna. ## What is the current behavior? The assistant composer exposes a model picker. Paid orgs default to `gpt-5.3-codex`; everyone else defaults to `gpt-5.4-nano`. ## What is the new behavior? - The model picker is hidden in the assistant composer and Explorer home. - Chats default to `gpt-5.6-luna` with `reasoningEffort: medium`. - Model selection plumbing is kept (registry, entitlements, `setModel`, generate-v4 request body) so a requested model can still be honored when provided. - Other completion endpoints still use `gpt-5.4-nano`. ## Additional context Model selector UI can be re-enabled by passing `selectedModel` / `onSelectModel` to `AssistantChatForm`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for the GPT-5.6 Luna model with medium reasoning capability. * Made GPT-5.6 Luna the default assistant model. * **Improvements** * Simplified assistant chat by removing model selection from the primary chat experience. * Updated model fallback behavior to use the standard assistant model. * Chat forms can now optionally display model selection when configured. * **Tests** * Updated model coverage and assistant chat tests for the new defaults and behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
8790e657e9 |
feat(ai): include org slug in Assistant Braintrust span metadata (#49692)
<!-- ccr-slack-attribution --> _Requested by **Matt Rossman** · [Slack thread](https://supabase.slack.com/archives/D0A79RYJKRB/p1787926891744399)_ # Problem Assistant spans in Braintrust record only the numeric `orgId`, whereas support tickets show org slug. This incurs an extra manual step to resolve the ID through admin studio before the trace can be found. # Fix Adds `orgSlug` to spans, sourced from the same verified org lookup that produces `orgId`. Renamed the request body's `orgSlug` to `rawOrgSlug` to distinguish the verified slug from getAIDetails, following the existing rawRequestedModel / requestedModel pattern. ## How to review See sample trace [94863b6d-aaa9-449a-a9c9-981ad40e614a](https://www.braintrust.dev/app/supabase.io/p/Assistant/trace?object_type=project_logs&object_id=5a8d02e5-b3b6-40cc-ba76-ecee286478f4&r=223112cd-33f4-45c4-a273-8d3781689448&s=223112cd-33f4-45c4-a273-8d3781689448) produced from sending a chat from the [Preview](https://studio-staging-git-mattrossman-ai-1149-include-698a5f-supabase.vercel.app/dashboard/org) on this PR. Note it now includes the org slug in span metadata: <img width="873" height="548" alt="CleanShot 2026-08-28 at 10 59 49@2x" src="https://github.com/user-attachments/assets/bcf47a94-6782-434a-9006-c7b9c95f1c37" /> If desired you can test yourself too by chatting with Assistant in the preview and looking up the corresponding Chat ID from Braintrust [logs](https://www.braintrust.dev/app/supabase.io/p/Assistant/logs). Closes AI-1149 --- _Generated by [Claude Code](https://claude.ai/code/session_01N2ziJech9dV19pJ9MisYdX)_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
5fd2023708 |
feat(studio): worker detail page (FE-4189, FE-4197) (#49195)
## What
The worker detail page at `/project/[ref]/workers/[name]`, reading `GET
/v2/projects/{ref}/workers/{name}`. Base: #49194.
## How to test
Only on the **Mockamaster** project in staging — it is the one project
in the alpha allow-list.
1. Staging dashboard → Mockamaster → **Workers** → click
`dashboard-test`
2. Overview: instances read 1 declared / 1 live / 1 ready / 0 stale, no
error alerts
3. Settings: Deno 2, `denoland/deno:latest`, 2 GB · 1 vCPU, private, US
West (locked)
4. **How to call** in the header → the snippets name the real worker URL
No write actions. Delete (FE-4190) is deliberately out.
Closes FE-4189
Closes FE-4197
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added worker detail pages with overview, requests, logs, builds, and
settings tabs.
* Added worker metadata, runtime details, invocation examples, and local
development commands.
* Added worker log streams with refresh, row selection, loading, empty,
and error states.
* Added worker-specific log formatting and clearer instance status
information.
* **Documentation**
* Updated migration tracking to mark the worker route as complete.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
4dee589735 |
fix(studio): stop assistant fabricating database_identifier for notebooks (#49558)
## Summary * Fixes [FE-4275](https://linear.app/supabase/issue/FE-4275/assistant-always-creates-notebooks-with-wrong-identifier-first-try): the assistant always created database notebook cells with a fabricated `database_identifier` (`"primary"`, later observed as `""` / `"_primary"` under different prompt wording) instead of omitting the key for the project's primary database, which tripped the tool's reject-and-retry validation on the very first attempt. * Prompt wording alone wasn't reliable — live eval runs against the real model kept substituting a new placeholder every time the prompt was tightened further. * Normalizes an empty-string `database_identifier` to absent at the schema level (`databaseIdentifierSchema` in `notebook-schema.ts`), which is inherited by every schema built from it — the AI SDK's `inputSchema` for `create_notebook`/`update_notebook`, and the write-boundary `writableNotebookSchema` used right before the PUT to the backend. * Adds an eval case (`evals/dataset.ts`) reproducing the original bug, plus unit tests covering schema-level and write-boundary normalization. ## Test plan - [X] `pnpm --filter studio exec tsc --noEmit` passes - [X] `pnpm exec prettier --check` passes on touched files - [X] Unit tests pass: `notebook-schema.test.ts`, `notebook-upsert-mutation.test.ts`, `notebook-tools.test.ts` (104 tests) - [X] Ran the new eval case against the real model 3x before the code fix (0% correctness, fabricated `""`/`"_primary"`) and 3x after (100% correctness) ## Summary by CodeRabbit * **Bug Fixes** * Improved notebook handling of empty database identifiers by treating them as absent. * Ensured notebook requests omit unused database identifier fields. * Added validation guidance for read-replica database identifiers. |
||
|
|
632e099487 |
feat(studio): track assistant notebook divergence (#49539)
## Summary - record server divergence when an assistant changes a notebook with local unsaved edits - clear the session-only marker after a successful save or notebook removal - cover update, delete, saved eviction, and lifecycle behavior ## Verification - pnpm --dir apps/studio exec vitest run state/notebooks/notebooks-state.test.ts lib/ai/notebook-cache-invalidation.test.ts - pnpm --dir apps/studio exec eslint state/notebooks/notebooks-state.ts state/notebooks/notebooks-state.test.ts lib/ai/notebook-cache-invalidation.ts lib/ai/notebook-cache-invalidation.test.ts - pnpm --dir apps/studio typecheck Stacked on the approval-warning PR for FE-4255. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved handling of server changes to notebooks with unsaved local edits. * Server updates and deletions are now tracked as divergences instead of being silently skipped. * Divergence indicators are cleared when changes are saved or notebooks are removed. * Unrelated notebook changes no longer create false conflicts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
509d80c9eb |
feat(studio): CLI deploy instructions for workers (FE-4191) (#49194)
## What The surface that shows you how to deploy a worker from the CLI, plus the product rename and the alpha framing. - **Compute → Workers.** `PRODUCT_NAME` and `CLI_NAME` now say `Workers` / `workers`, so the sidebar, page title, command menu, and every generated snippet match the CLI. One name, not two. - **`DeployWorkerDialog`** — scaffold / configure / push, with copyable `supabase workers` and `config.toml` snippets - **`WorkersEmptyState`** — an `EmptyStatePresentational` with a permission-gated deploy action - **`AlphaNotice`** on the list page, and a **New** badge on the sidebar entry (`Route.isNew`) - **`WorkerSnippetTabs`** — CLI, `config.toml`, and curl/JS/Python calls built from one worker shape. Reused by #49195. Snippet URLs resolve from the project's `app_config.endpoint` (`https://<project>/workers/v1/<name>`, the same shape as `/functions/v1/`), and fall back to `[YOUR WORKER URL]` before settings load rather than printing a wrong host. ## How to test Only on the **Mockamaster** project in staging — it is the one project in the alpha allow-list. 1. Staging dashboard → Mockamaster → **Workers** (the sidebar entry carries a **New** badge) 2. **Deploy a worker** → step through the tabs; every snippet should name the real worker URL, not a placeholder 3. Copy the cURL snippet and run it: expect `401`. Reaching a deployed worker needs a second allow-list (`WORKERS_ALLOWED_PROJECTS` in api-gateway `customer-router/wrangler.toml`), separate from the flag that unlocks the dashboard. 4. Open a project with no workers to see the empty state ## Tests `workerSnippets.test.ts` covers the generated output users copy: worker URL in all three call snippets, the `[YOUR WORKER URL]` fallback, anon vs service-role placeholder, empty-name fallback and trimming, runtime default, and every `config.toml` field. ## Unverified copy The dialog steps and the `supabase workers <sub>` subcommands come from the original POC spec, not from the shipped CLI. Same for "Dockerfile, Node.js and Deno supported" in the empty state — only Deno is confirmed end to end. Worth a check by someone who knows the CLI surface. Closes FE-4191 --------- Co-authored-by: Francesco Sansalvadore <f.sansalvadore@gmail.com> |
||
|
|
dcac820571 |
feat(studio): add assistant notebook run tool (#49361)
## 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? Assistant feature and data-handling plumbing. ## 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? The Assistant can read and edit notebooks, but it cannot execute all saved query cells as one approved operation. ## What is the new behavior? - Adds a `run_notebook` tool with one approval gate for the complete notebook. - Executes database and log cells sequentially in notebook order. - Rejects stale runs when the notebook changed after the Assistant read it. - Resolves primary and read-replica connections and forwards authorization to log and replica requests. - Shares rows with the model only when the organization's AI data-sharing level permits it. - Strictly validates and sanitizes persisted notebook-run output before replaying message history. - Registers the tool in prompts, filtering, mocks, and tool construction. ## How to test manually This is the tool/data layer; use the top-of-stack preview from #49364 for the complete UI while checking these behaviors. 1. In Explorer, create and save a notebook named **Assistant run smoke test** with: - a markdown cell - a working database query - a working Logs query - a database query that returns no rows, such as `select 1 where false` 2. Open the AI Assistant and ask: **Read the “Assistant run smoke test” notebook and analyze it using its current results.** 3. Confirm the Assistant reads the notebook and requests one `run_notebook` approval for all query cells, rather than requesting one approval per cell. 4. Approve the run. Confirm database and Logs queries execute in notebook order, the markdown cell is not executed, and the Assistant responds only after the complete run finishes. 5. Start another run but do not approve it yet. In another tab, edit and save the notebook. Return to the pending approval and approve it. 6. Confirm the stale run is rejected, the Assistant reads the latest notebook version, and a new approval is required. 7. Optional privacy check: set the organization AI data-sharing level to schema-only, run a query containing a recognizable value, and confirm the value remains visible in the notebook result UI but is not repeated in the Assistant's answer. ## Automated test `mise exec node@22 -- pnpm --dir apps/studio exec vitest --run lib/ai/tool-filter.test.ts lib/ai/tools/index.test.ts lib/ai/tools/mock-tools.test.ts lib/ai/tools/notebook-tools.test.ts lib/ai/tools/tool-sanitizer.test.ts` 80 tests pass at this stack boundary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added AI-assisted notebook execution for database and log cells, with approval, freshness checks, replica support, and per-cell error handling. - Added notebook deletion and database discovery and validation for notebook management. - Added configurable privacy controls for notebook results. - Added request header support for analytics SQL execution. - **Bug Fixes** - Improved replica lookup handling so other notebook cells can continue when one lookup fails. - Prevented invalid, unauthorized, or overly detailed notebook execution results from being exposed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Saxon Fletcher <SaxonF@users.noreply.github.com> |
||
|
|
40d9a2e929 |
fix(studio): invalidate notebook cache after assistant delete (#49496)
Stacked on supabase/supabase#49415. ## Summary - collect completed assistant delete_notebook tool calls as deleted cache effects - evict deleted notebooks from the React Query cache and notebook state - cover collector, cache eviction, and the open-tab Notebook not found state ## Verification - pnpm test:studio -- notebook-cache-invalidation ExplorerNotebookTab.assistant-cache-invalidation - pnpm --filter studio typecheck - touched-file ESLint and Prettier checks <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved notebook deletion handling so removed notebooks no longer remain visible after deletion. * Navigation and cached notebook data now update promptly when a notebook is deleted. * Attempting to access a deleted notebook now displays a clear “Notebook not found” message. * **Tests** * Added coverage for notebook deletion, cache invalidation, navigation updates, and the resulting not-found state. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
de3a8799d6 |
fix(studio): invalidate notebook caches after assistant create/update (#49415)
## Summary - The assistant's `create_notebook`/`update_notebook` tools run entirely server-side, so an open notebook tab's React Query cache and Valtio store never learn a write happened — the tab keeps showing stale content until a manual reload. - Adds `collectNotebookCacheEffects`/`applyNotebookCacheEffects` (`apps/studio/lib/ai/notebook-cache-invalidation.ts`), which scan finished assistant messages for completed `create_notebook`/`update_notebook` tool calls and evict the affected notebook via `evictNotebookFromCaches` (`apps/studio/data/content/notebooks/notebook-cache.ts`), plus invalidate the nav list. - Wired into `createChatInstance`'s `onFinish` in `state/ai-assistant-state.tsx`, with per-chat dedupe so replayed history isn't reprocessed. - Removes the cache entry outright rather than invalidating it, since a remounting `useNotebookQuery` would otherwise read the stale cached value synchronously before its refetch lands. - Explicitly skips eviction when the open tab has unsaved local edits, so an assistant write can't silently discard them. Related: [FE-4235](https://linear.app/supabase/issue/FE-4235) **Out of scope:** this only protects the client-side cache/store from being clobbered after the fact. Preventing the assistant's `update_notebook` tool call itself from overwriting a user's unsaved edits (a data-layer conflict, not a cache-freshness one) is tracked separately in [FE-4255](https://linear.app/supabase/issue/FE-4255). ## Test plan - [x] `pnpm test:studio -- notebook-cache notebook-cache-invalidation ai-assistant-state.notebook-cache-invalidation ExplorerNotebookTab.assistant-cache-invalidation ExplorerNotebookTabCoordinator` — all passing - [x] Reproduction-first component test (`ExplorerNotebookTab.assistant-cache-invalidation.test.tsx`) — verified it fails without the fix (stale content persists) and passes with it - [x] Regression test for the dirty-notebook guard (an edited, unsaved notebook is left untouched by an assistant write) - [x] `pnpm typecheck --filter=studio` / `pnpm lint --filter=studio` clean <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Notebook changes made through the AI assistant now appear correctly in open notebook tabs and after reopening them. * Saved notebook caches are refreshed after completed create or update actions, preventing stale content from being displayed. * Unsaved notebook changes are preserved during cache cleanup. * Closing a notebook tab now consistently removes its cached content. * **Tests** * Added coverage for assistant-driven updates, remounts, duplicate actions, project context changes, and cache behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
89b4f1aca4 |
feat(studio): add delete_notebook tool to AI assistant (#49413)
## Summary * Adds a `delete_notebook` AI assistant tool (`needsApproval: true`) that lets the assistant delete a notebook with explicit user approval, mirroring the existing `create_notebook`/`update_notebook` tools. * Wires up a destructive-styled approval card in the AI Assistant Panel (fetches the notebook to show its name, warns the deletion is permanent) using the same `Confirm`/tool-approval plumbing as the other notebook tools. * Updates `tool-filter.ts` opt-in gating, the assistant system prompt, the eval-harness mock tools, and the eval dataset with `delete_notebook` coverage. * Adds test coverage in `notebook-tools.test.ts`, `mock-tools.test.ts`, and `NotebookProposalRenderer.test.tsx`. Closes [FE-4242](https://linear.app/supabase/issue/FE-4242/assistant-delete-notebook-tool). ## Test plan - [X] `pnpm typecheck --filter=studio` passes - [X] `pnpm --filter studio exec vitest run` for the touched files (notebook-tools, mock-tools, NotebookProposalRenderer, [Message.Parts](<http://Message.Parts>), and existing consumers of `content-delete-mutation`) — all passing - [X] `eslint` and `prettier --check` clean on all touched files - [X] Manual verification of the approval UI in a running Studio instance (not done in this session) ## Summary by CodeRabbit * **New Features** * Added AI-assisted notebook deletion with explicit confirmation and irreversible-action warnings. * Added safeguards to distinguish deleting an entire notebook from removing individual panels. * Completed deletions now display the deleted notebook’s name without an option to reopen it. * **Bug Fixes** * Improved handling of missing notebooks and invalid deletion requests. * **Tests** * Added coverage for deletion approval, denial, errors, and successful completion. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added AI-assisted notebook deletion with explicit approval and irreversible-action warnings. * Added confirmation, loading, error, and completion states for notebook deletion. * Prevented accidental full-notebook deletion when only a panel or section should be removed. * Improved notebook update results by showing applied changes when available. * **Bug Fixes** * Notebook deletion now uses the required API version. * Improved handling and validation of missing notebooks during deletion. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
ee931e49a1 |
fix(studio): send new signups to org creation directly (#41041)
## What kind of change does this PR introduce? Bug fix. Resolves DEPR-318. ## What is the current behavior? New users who confirm their email land on `/sign-in`, then `/organizations`, then get bounced to `/new` via a `useEffect`. Cancelling org creation with zero orgs sends them back to `/organizations`, which immediately redirects into `/new` again. ## What is the new behavior? - Signup email verification redirects to `/new` directly - `/organizations` with zero orgs shows the existing empty state instead of force-redirecting ## To test ### One-time setup Assuming you don’t already have a staging account with **zero** orgs: 1. On **supabase.green**, sign up with a fresh email and confirm it 2. Stop at org creation. Do **not** create an org ### On this PR Using the [studio-staging preview](https://studio-staging-git-dnywh-fixremove-org-redirect-supabase.vercel.app/) from Vercel checks: 4. Sign in on the preview with that account 5. Open `/dashboard/organizations`. Expect the **Create an organization** empty state, with no redirect to `/new` 6. Open `/dashboard/new`, click **Cancel**. Expect to land on `/organizations` and stay there ### Compare on supabase.green Optional. Just to show what happens currently on `master`: 7. Repeat steps 3–5 on **supabase.green**. `/organizations` should bounce to `/new`, and **Cancel** should send you back into org creation <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved signup redirects by preserving valid destinations and relevant query parameters. * Added safer fallback behavior for missing, invalid, or unsupported destinations. * Improved handling of signup redirects provided in multiple formats. * Prevented automatic redirection from the organizations page when no organizations exist. * **Style** * Updated the organizations page title capitalization for consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8920439569 |
Expose previous notebook content in update_notebook (#49401)
## Summary - Plumb pre-update notebook snapshot through `update_notebook` tool response as `previous_content` - Add sanitizers in `tool-sanitizer.ts` to strip snapshot before model sees it - Add client-side stripping in `prepareMessagesForAPI` to avoid re-uploading snapshot on subsequent turns - This is PR 2 of 3 fixing Linear issue FE-4243 (notebook update proposal shows 'unapplyable' error for already-completed updates) - Ships no visible behavior change on its own; enables PR 3 to restore diff preview for completed updates ## Test plan - [x] Unit tests: 80/80 passing across notebook-tools.test.ts, tool-sanitizer.test.ts, generate-assistant-response.utils.test.ts, message-utils.test.ts, and mock-tools.test.ts - [x] Typecheck: clean for all changed files - [x] ESLint: zero errors, lint:ratchet passes (exit 0) - [x] Integration: previous_content is correctly populated with pre-update notebook, stripped before model context, and stripped on client-side re-upload <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Notebook updates now retain previous content for recovery and history. - AI responses expose only the notebook’s ID and name, keeping previous content out of model-visible data. - **Tests** - Added coverage for notebook update results, content sanitization, and message preparation, including cases where previous content is absent or preserved. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
dd534d229b |
docs(studio): instruct the notebook agent to use list_databases (#49334)
## Summary - Adds a bullet to `NOTEBOOKS_PROMPT` instructing the assistant to call `list_databases` before setting a `database_cell`'s `database_identifier`, mirroring the existing `list_tables` schema-validation instruction immediately above it. Part 5/6 of the stack for FE-4225 (expose valid database identifiers to the notebook AI agent). Stacked on #49333. This is the last piece that makes the assistant actually *use* the tool and schema field wired up earlier in the stack, rather than just having them available. ## Test plan - [x] `pnpm --filter studio exec tsc --noEmit` passes - [x] `prettier --check` passes <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved notebook database configuration by ensuring database identifiers are selected from available databases. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
ee59d28240 |
fix(studio): reject unknown database_identifier before writing a notebook (#49333)
## Summary - `create_notebook`/`update_notebook` now validate every `database_cell`'s `database_identifier` against the project's real database list (`getReadReplicas`) before writing, throwing an assistant-actionable `NotebookToolError` (same pattern as the existing `expected_updated_at` mismatch check) when it doesn't match. - Only fetches the database list when a cell actually sets `database_identifier` — no added cost for the common case. - `update_notebook` validates only the cells its own operations introduce (`insert_cell`/`replace_cell`), not the whole resulting notebook — otherwise an unrelated, untouched pre-existing cell whose replica was removed after the fact would block updates that never touch it. Part 4/6 of the stack for FE-4225 (expose valid database identifiers to the notebook AI agent). Stacked on #49332. This closes the gap that PR 3 reopened: a model can no longer invent an identifier that silently breaks a cell — it now gets a retryable error naming `list_databases` (added in #49328) as the way to find a real one. ## Test plan - [x] `create_notebook`/`update_notebook` reject an unknown `database_identifier` with `NotebookToolError` + `exposeToAssistant: true` - [x] Both succeed when the identifier matches a real database - [x] `create_notebook` never calls the databases endpoint when no cell sets `database_identifier` - [x] `update_notebook` succeeds without validating or fetching databases when no operation introduces a database_cell, even if an untouched existing cell carries a now-invalid identifier - [x] `pnpm --filter studio exec tsc --noEmit` passes <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a database-listing tool that provides database identifiers and metadata, including primary-database status. * Database results now return only the relevant fields. * **Bug Fixes** * Added validation to prevent notebooks from referencing unknown databases. * Create and update actions now provide clear errors for invalid database identifiers. * Updates validate newly added or replaced cells while preserving existing, untouched cells. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0f730de9e0 |
feat(studio): add list_databases tool for the AI assistant (#49328)
## Summary
- Adds a `list_databases` tool to the notebook AI tools
(`getNotebookTools`), returning `{ identifier, is_primary, region,
status }` for the project's primary and any read replicas, via
`getReadReplicas`.
- Registers `list_databases` in `tool-filter.ts` (opt-in validation
schema + SCHEMA category), and adds a mock fixture in `mock-tools.ts`
for evals.
Part 2/6 of the stack for FE-4225 (expose valid database identifiers to
the notebook AI agent). Stacked on #49327. A later PR in the stack
reinstates `database_identifier` on the agent-facing notebook schema and
requires the agent to call this tool first.
## Test plan
- [x] New test coverage in `notebook-tools.test.ts` for
`list_databases`, including `is_primary` computation
- [x] Existing exact-tool-set assertion updated
- [x] `pnpm --filter studio exec tsc --noEmit` passes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added an AI notebook tool for listing a project’s databases.
* Results include each database’s identifier, region, status, and
whether it is the primary database.
* Supports projects with read replicas.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
7a2e237892 |
Add update_notebook evals; fix prompt gaps they surfaced (#49324)
## Summary - Add `update_notebook` eval cases (insert/replace/delete/move, a combined delete+insert, and guard/safety cases) mirroring the existing `create_notebook` cases, targeting the notebooks already seeded in the mock tool harness. - Fix two behavior gaps in `NOTEBOOKS_PROMPT`/`LIMITATIONS_PROMPT` that these cases surfaced when run live: the assistant asking the user for a notebook id instead of resolving it via `list_notebooks`, and the destructive-operations warning rule not being connected to SQL written into notebook cells. - Soften the destructive-SQL case's `correctAnswer` to match `update_notebook`'s real approval-gated behavior — a warning accompanying the reported change is acceptable, not only one strictly preceding the tool call. ## Test plan - [x] `pnpm run typecheck` (apps/studio) — clean - [x] `pnpm exec prettier --check` on both changed files — clean - [x] `evals/scorer.test.ts`, `evals/transcript.test.ts`, `evals/trace-utils.test.ts` — 21/21 pass - [x] Ran the new eval cases live against OpenAI (bypassing the Braintrust proxy) via Braintrust MCP; confirmed via trace inspection that the prompt fix resolved the id-resolution gap (Tool Usage 0% → 100% across 3 trials) and that the assistant now includes an explicit irreversibility warning when destructive SQL is written into a notebook cell <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved notebook creation and editing support across SQL, query, chart, and time-range cells. - Added clearer handling for saved notebooks, recurring requests, and one-time SQL execution. - Enhanced validation for database cells and notebook configuration. - **Bug Fixes** - Improved safeguards and warnings for destructive queries, including saved notebook queries. - Better handling of missing tables and notebooks. - More precise notebook cell updates and tool usage validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
aa2897f712 |
feat(studio): teach assistant to query ClickHouse logs (#49292)
## 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 --> |
||
|
|
ebd616fa90 |
fix(studio): auto-retry notebook updates on stale/invalid conflicts (#49323)
## Summary
- **Removed dead client-side refresh UI** in
`NotebookProposalRenderer.tsx` and its test — the diff preview is always
computed from live data, so the check was redundant with the tool's
server-side re-validation
- **Added typed `NotebookToolError`** in `notebook-tools.ts` with
structured metadata (`{ exposeToAssistant: boolean }`) validated by a
zod schema with a literal discriminant tag (`tag:
'notebook_tool_error'`) — tracks the two retryable failures: staleness
conflict and invalid operations (unknown cell id)
- **Encoded errors in `generate-v4.ts` onError** — the one place in the
pipeline that holds the live `Error` before it becomes a string in the
persisted message
- **Extracted and fixed message history filter** into new
`generate-assistant-response.utils.ts` — any tool-error whose
`errorText` decodes against the `NotebookToolError` schema is let
through (with `errorText` rewritten to plain prose so the model sees the
message, not JSON), while other errors stay filtered as before
Net effect: the assistant detects the specific, actionable rejection
reason and retries on its own with no dead button or human intervention
needed.
## Test plan
- Existing unit tests in `NotebookProposalRenderer.test.tsx` pass (dead
button test removed)
- New unit tests in `notebook-tools.test.ts` cover encode/decode
round-trips and error discrimination
- New unit tests in `generate-assistant-response.utils.test.ts` cover
message history filtering with all error states
- `pnpm typecheck` is clean
- `pnpm --filter studio run lint:ratchet` passes (no new ESLint
warnings)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Notebook update errors now provide clearer, structured explanations to
the AI assistant.
* Assistant responses preserve relevant notebook error details while
filtering invalid or temporary tool states.
* **Bug Fixes**
* Improved handling of stale notebook revisions and invalid notebook
update operations.
* Notebook proposal rendering proceeds without an unnecessary refresh
step.
* **Tests**
* Expanded coverage for notebook errors, message filtering,
serialization, and error handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
e7c3cad8de |
feat(evals): add notebook eval cases and forbiddenTools scorer capability (#49104)
## Summary - Added ~11 new eval cases for Notebooks AI assistant evals, including: basic notebook cell creation, multi-cell composition (markdown+database+log), log cell time ranges, row_limit defaults, chart config, destructive SQL safety warnings, and hallucination guards for nonexistent tables - Extended `toolUsageScorer` with deterministic `forbiddenTools` field to score both required and forbidden tool usage, enabling eval cases to assert tool choice (e.g., `execute_sql` vs `create_notebook`) without LLM-as-judge - Extended SQL validators (`sqlSyntaxScorer`/`sqlIdentifierQuotingScorer`) to validate SQL inside `create_notebook` database cells (log cells deliberately excluded as they use ClickHouse dialect) - Fixed two real assistant issues in `NOTEBOOKS_PROMPT`: (a) reuse `CLICKHOUSE_LOGS_COMPLETION_INSTRUCTIONS` and schema section to prevent incorrect BigQuery-style SQL in logs queries, (b) require schema verification before writing `database_cell` to prevent queries against nonexistent tables Resolves FE-4087 ## Test plan - All 11 new eval cases run live against OpenAI via Braintrust; traces inspected and validated - Existing unit tests, lint, and typecheck pass <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for creating notebooks with database, Markdown, chart, and log cells. * Improved handling of reusable notebook requests versus one-off SQL queries. * Added guidance for modern ClickHouse SQL and absolute log time ranges. * **Bug Fixes** * Improved SQL validation, row-limit enforcement, and destructive-query safety. * Prevented invalid or nonexistent-table queries from being accepted. * Improved validation of notebook cell types and tool usage. * Improved handling of ClickHouse log queries and database-cell SQL. * Improved evaluation reliability by limiting concurrent test execution. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6c6ac567b1 |
feat(studio): workers list behind the workers flag (FE-4188) (#49193)
## What
The Workers list page at `/project/[ref]/workers`, behind
`useFlag('workers')`. Reads `GET /v2/projects/{ref}/workers`.
- Sidebar and command-menu entries, both hidden when the flag is off
- Name search, state and access filters, pagination
- Read-only
Gating, in order: flag off redirects to the project home; a 404 from the
API means the project is outside the alpha allow-list ("not enabled for
this project"); a 403 means the caller lacks the permission
(`NoPermission`); anything else is an `AlertError`.
`parseWorker` in `data/workers/workers.utils.ts` is the only place the
API shape becomes the view model. It validates with zod, so a drifted
response fails the query instead of half-rendering a row.
## How to test
Only on the **Mockamaster** project in staging — it is the one project
in the alpha allow-list, and standing a worker up anywhere else is
involved right now.
1. Staging dashboard → Mockamaster → **Compute** in the sidebar
2. Expect the `dashboard-test` worker: state `Active`, runtime Deno,
private, US West, 2 GB · 1 vCPU · 1 inst
3. Open any other project's `/workers` URL → "Compute is not enabled for
this project"
4. Turn the `workers` flag off → the sidebar entry disappears and the
URL redirects to the project home
Closes FE-4188
|
||
|
|
2893c783d5 |
Hook up APIs for Notebooks CRUD (#49254)
## Context API changes are ready so hooking up the endpoints for full CRUD UX E2E - Can create notebooks - Can load notebooks - Can delete notebooks - Can update notebooks |
||
|
|
8bdfe03fe7 |
refactor(studio): drop notebook type widening now that the API supports it (#49272)
## Summary - Regenerates `packages/api-types` for the content endpoints now that the Platform API's `notebook` content type has landed (list/get/upsert `type` enums, plus `UpsertContentBody`'s notebook cell shape with `_id`/`y_series`). Unrelated schema drift from the same regen (Warehouse, SSO, notification exceptions, etc.) is excluded — only the content-endpoint hunks are applied. - Removes every local widening cast added while the API support was pending (`content-query.ts`, `content-infinite-query.ts`, `notebook-query.ts`, `notebook-upsert-mutation.ts`, `sql-folders-query.ts`). - What remains is scoped and renamed to match: draft ids (`generateDraftId`/`isDraftId`), used only for cells created client-side in the editor before their first save, dropped before they'd ever reach the backend as a fake `_id`. ## Test plan - [x] `pnpm typecheck` — clean - [x] `pnpm --filter studio test` — full suite passes (518 files / 5471 tests) - [x] `pnpm --filter studio run lint:ratchet` — no new warnings - [x] `pnpm format` / prettier — clean <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved notebook cell tracking during editing, reordering, insertion, and deletion. * Preserved existing cell identifiers while removing temporary draft identifiers before saving. * Improved chart configuration for selecting and displaying multiple Y-axis series. * Strengthened notebook validation and content persistence behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
bd76d7fc34 |
feat(studio): wrap assistant Edge Function approval in a Confirm card (#49168)
<img width="1512" height="862" alt="image" src="https://github.com/user-attachments/assets/79a6d4dc-dcd2-489f-97d7-3ee7a0196b7d" /> ## 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 / UI refactor. ## What is the current behavior? Assistant Edge Function approval nests `ConfirmFooter` under the function block. `addToolApprovalResponse` is wired whenever state is `approval-requested`, including automatic approvals. ## What is the new behavior? Introduces a `Confirm` card that owns the frame, with the footer attached below the body. Edge Function approval uses that card. Interactive Approve/Deny only runs for manual `approval-requested` parts (`!approval.isAutomatic`), matching the [AI SDK tool-approvals `useChat` guidelines](https://ai-sdk.dev/docs/agents/tool-approvals). SQL still uses `DisplayBlockRenderer` until #49170. `ConfirmFooter` is inlined into `Confirm` so SQL can keep importing the named footer until that PR. ## Additional context Part of stack #49171. Base: `chore/ai-sdk-7` (#49167). Notebook proposal Confirm wrapping is **not** in this stack — that file lives on [#49159](https://github.com/supabase/supabase/pull/49159). Follow up after that stack merges. ## Test plan - [ ] Deploy-edge-function tool part shows Confirm with Skip / Deploy - [ ] Existing-function replace warning still requires the second confirm - [ ] After approve, footer morphs to loading and buttons disable - [ ] `Confirm.utils.test.ts` and `EdgeFunctionRenderer.test.tsx` pass <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added confirmation cards for AI-assisted actions, including approve and cancel controls. * Improved handling of manual approval requests for SQL execution, notebook changes, and Edge Function deployment. * Added support for customizing report and Edge Function block styling. * **Bug Fixes** * Automatic approvals no longer appear as pending manual confirmations. * Skipped SQL actions now provide clearer messaging. * **Tests** * Expanded coverage for approval states, confirmation controls, and automatic decisions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c80f8ad78d |
chore(studio): upgrade AI SDK to v7 (#49167)
## 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? Chore / dependency upgrade. ## What is the current behavior? Studio is on AI SDK 6 (`ai` ^6.0.174, `@ai-sdk/react` ^3). Tool approvals still use the v6 `needsApproval` flag on individual tools. ## What is the new behavior? Upgrades Studio to AI SDK 7 (`ai` 7.0.59) and the matching `@ai-sdk/*` packages. Aligns call sites with v7 names (`instructions`, `isStepCount`, `onEnd`, `ToolExecutionOptions`). This is the bottom of stack #49171. Later layers add a shared Confirm card and AssistantQueryCell. ## Additional context - Stack: #49167 → #49168 → #49169 → #49170 - `needsApproval` on tools is left as-is in this PR so the upgrade can land independently. A follow-up can move those gates to `streamText({ toolApproval })` and `experimental_toolApprovalSecret`. - Independent of the notebook preview stack ([#49112](https://github.com/supabase/supabase/pull/49112), [#49159](https://github.com/supabase/supabase/pull/49159)), which should merge first before we wrap notebook proposals in Confirm. ## Test plan - [ ] `pnpm --filter studio test` for `lib/ai/tools/*` and assistant generate path - [ ] Assistant chat still streams and tool-approval SQL / Edge Function still pause for confirm - [ ] Evals still run with mock tools (`needsApproval: false` overrides) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Updated AI-powered chat, onboarding, SQL, code completion, and recipe generation workflows for more reliable responses. * Streaming responses now better preserve reasoning and source information where available. * Improved tool privacy notices while preserving dynamically generated tool descriptions. * Refined AI response handling, including step limits and structured policy results. * **Bug Fixes** * Improved compatibility across AI-powered tool interactions and execution scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6073c7a7e7 |
[FE-4193] fix(studio): show proper names for custom identity providers (#49182)
Unregistered `custom:*` identity providers (e.g. white-label deployments' own OAuth providers) rendered their raw id — the account preferences "Sign-in methods" list showed something like `Custom:Acme` instead of `Acme`. `getProviderDisplay()` now derives a proper title-cased name from any `custom:*` id, so this works generically for every custom provider. **Changed:** - `getProviderDisplay()` derives a title-cased display name for unregistered `custom:*` providers (`custom:acme` → "Acme", `custom:my_provider` → "My Provider"), case-insensitively. Registered ones (e.g. `custom:openai` → ChatGPT) are unaffected. - `SignInWithCustom` reuses `getProviderDisplay()` instead of its own `formatProviderName`, which only stripped a lowercase `custom:` prefix — the display name also now flows into its error toast. - Added unit tests for the new fallback branch. ## To test - On a deployment with a custom provider (or by temporarily hardcoding an identity with `provider: 'custom:acme'` in `AccountIdentities`), check `/account/me` → Sign-in methods shows "Acme", not "Custom:Acme" - Unlink dialog/toast for that identity should also say "Acme" - Sign-in page with a custom provider configured should show "Continue with Acme" - `pnpm vitest run lib/external-identity-providers.test.ts` in `apps/studio` passes Addresses [FE-4193](https://linear.app/supabase/issue/FE-4193) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for unregistered custom identity providers. * Custom provider names are now displayed in a clearer, title-cased format with underscores converted to spaces. * Matching providers use the SAML icon while preserving their configured display names. * **Bug Fixes** * Improved sign-in error messages and button labels for custom providers. * Provider identifiers are now handled case-insensitively. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> |
||
|
|
bfab3090f5 |
QueryTab: Scope role impersonation to each tab instead of global (#49139)
## Context Previous PR [here](https://github.com/supabase/supabase/pull/49101) introduced role impersonation to the Explorer -> Query Tab, but the setting was global (e.g selected role would be the same despite switching query tabs) Changes here shifts the scope of the role impersonation into the query draft so that the value is tied to each individual query tab instead <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Query drafts now remember selected impersonated roles when switching between drafts or returning later. * Added support for clearing saved impersonated roles. * Impersonation state remains isolated across query tabs. * **Bug Fixes** * Prevented impersonation settings from carrying over between unrelated drafts. * Invalid saved role data is safely ignored during restoration. * Logs drafts no longer persist or update impersonated roles. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9be60cab63 |
refactor(studio): add optimistic locking to update_notebook (#49111)
## 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? Refactor / hardening ## What is the current behavior? The `update_notebook` AI tool re-fetches the notebook right before applying operations, but concurrent edits are last-write-wins: the model has no way to detect that the notebook changed since it planned the edit, so a stale diff can silently overwrite someone else's changes. ## What is the new behavior? - `get_notebook` now returns the notebook's `updated_at` timestamp. - `update_notebook` requires a new `expected_updated_at` input field (the `updated_at` the model got from `get_notebook`). - At execute time, after the existing re-fetch and before applying operations, `update_notebook` compares the fetched `updated_at` against `expected_updated_at` and throws a descriptive error if they don't match, telling the model to re-read the notebook and reissue the update. - The notebook system prompt and mock tools (used by the eval harness) are updated to match. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Notebook retrieval now includes the latest update timestamp. * Notebook edits require confirmation that the content is current before saving. * **Bug Fixes** * Prevented stale edits from overwriting newer notebook changes. * Conflicting updates are rejected, allowing the latest content to be fetched before retrying. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
17dde3d324 |
feat(account): let OAuth-only users add a password to their account (#49057)
Allows a user to add a password which automatically creates and email identity to enable email + password authentication for OAuth-only accounts. Gated behind a feature flag: `enableAccountPassword` When a user does not have an email identity, allow them to set a password: <img width="762" height="284" alt="Screenshot 2026-08-13 at 14 52 53" src="https://github.com/user-attachments/assets/70b4883a-ed38-488a-a1b7-908caa112a0b" /> Password modal: <img width="519" height="423" alt="Screenshot 2026-08-13 at 14 56 57" src="https://github.com/user-attachments/assets/56ac370d-9e6c-4b05-986f-3aa9a51826c2" /> Email identity has been created, allow unlinking and/or updating email address or password: <img width="764" height="285" alt="Screenshot 2026-08-13 at 14 55 04" src="https://github.com/user-attachments/assets/5d9d7692-f4e3-4638-958d-15fefad01333" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * OAuth-only accounts can set a password from Sign-in methods. * Added password visibility controls, validation guidance, and success or error feedback. * Sign-in methods display the account email when available. * **Updates** * Renamed “Account identities” to “Sign-in methods” throughout account preferences. * Standardized password requirements across password setup and reset forms. * Setting a password refreshes the current session and signs out other sessions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2f89014f74 |
Add logs cells (#49064)
## Context Related to Explorer/Notebooks - adds the source selector for query cell within a notebook <img width="1108" height="648" alt="image" src="https://github.com/user-attachments/assets/d1434197-3738-41b0-a8ef-1919c91181d9" /> <img width="1103" height="633" alt="image" src="https://github.com/user-attachments/assets/97f8c6a3-629d-4a41-aab4-3fdc5e8b2c7e" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for displaying log cells in the query editor. * Added switching between database and log query sources. * Log and database cells can display results as tables or charts. * Log queries support optional row limits. * Improved reliability when changing query settings. * Notebook query views now default to table display when unspecified. * **Bug Fixes** * Log cells no longer appear blank or get omitted from notebook views. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
794e45378c |
test(studio): add get_notebook eval cases (FE-4088) (#49067)
## 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 (test coverage) — second PR of the notebooks-evals plan, covering FE-4088 (Evals: Assistant can read notebook). Follows #49010 (FE-4086, list_notebooks). ## What is the current behavior? `dataset.ts` has no coverage for `get_notebook`. Separately, `NOTEBOOKS_PROMPT` only covers *choosing* between `create_notebook`, `update_notebook`, and `execute_sql` — it says nothing about reading or describing an existing notebook. ## What is the new behavior? **Eval cases** (`evals/dataset.ts`), three of them: - Resolve a notebook by name via `list_notebooks`, then `get_notebook`, and report the queries it actually contains. - Summarize a smaller, single-log-cell notebook as a baseline. - Report a nonexistent notebook id as not found instead of hallucinating contents. The mock's `execute` throws, which the AI SDK surfaces to the model as a `tool-error` part rather than failing the eval task. No new scorers or tool changes — `toolUsageScorer` and `correctnessScorer` already cover these, and `get_notebook` has unit coverage in `notebook-tools.test.ts`. **Prompt change** (`lib/ai/prompts.ts`) — please review this one separately, it's the only production behavior change here: Running the first case surfaced a real gap. The assistant transcribed each cell's SQL correctly but was inconsistent about the configuration that changes what a cell returns — dropping the log cell's time range in some runs, miscounting markdown cells as queries in others. Adds one bullet to `NOTEBOOKS_PROMPT` telling it to report a query cell's configuration and not count markdown cells as queries. Gated behind the Explorer flag, same as the rest of that prompt. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added notebook evaluation scenarios for database and log queries, including concise summaries and nonexistent notebook handling. * Improved notebook descriptions by reporting query configurations that affect returned results. * Markdown cells are now excluded from query counts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b5477a89a3 |
chore: Update API types (#48981)
Update the API types by running `api:codegen`. Some of the changes are fixed in code, some of the type changes had to be reverted (JIT Access, SSO features). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Billing** * Updated subscription messaging to reflect AWS Marketplace billing. * Removed outdated partner-billing downgrade notices. * **Bug Fixes** * Improved request handling for API keys, custom domains, SQL snippets, branches, and storage operations. * Improved legacy signing-key compatibility. * Refined temporary database access availability messaging. * **Updates** * Removed Fly as an available cloud provider for region selection. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d434c63bad |
joshen/fe 4150 explorer query cells result display settings (#49003)
## Context Related to Explorer / Notebooks - this adds chart functionality for the Query cells <img width="250" alt="image" src="https://github.com/user-attachments/assets/4ea37c14-87dc-4c43-ba7f-cb9436085c81" /> Query results can be rendered as either bar or line chart - using the chart packages from `ui-patterns` [NOTE]: For design team reviewers - am patching the chart packages to be agnostic to the `timestamp` property within the provided data set. Would love to use this component from a consistency POV instead of the old `BarChart` component we have. Have intentionally omitted log scale functionality from this PR - will have that separately 🙏 <img width="999" height="483" alt="image" src="https://github.com/user-attachments/assets/14356ee4-c658-4fd1-90e0-17c38dac4822" /> <img width="988" height="478" alt="image" src="https://github.com/user-attachments/assets/cd0ca088-9a03-4aa3-9884-17bc36d3cabf" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added chart views for notebook query results, including bar and line charts. - Added display settings for selecting X/Y columns, chart type, scale, cumulative values, and label visibility. - Added configurable X-axis support for charts. - Display preferences are saved with each notebook cell. - **Improvements** - New database cells default to table view. - Chart results better handle varied data types. - Empty results and incomplete chart settings now display clear placeholders. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8baaa517d0 |
test(studio): add list_notebooks eval cases (FE-4086) (#49010)
## 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 (test coverage) — first PR of the notebooks-evals plan, covering FE-4086 (Evals: Assistant can list notebooks). ## What is the current behavior? `dataset.ts` has zero notebook eval cases. Separately, two small gaps block writing them: `assistant.eval.ts` never sets `isExplorerEnabled`, so `NOTEBOOKS_PROMPT` never loads into the eval task's system prompt; and `list_notebooks`' `inputSchema` has no sort parameter, even though `getContent` already supports one, so "most recent" isn't answerable. ## What is the new behavior? - `assistant.eval.ts` passes `isExplorerEnabled: true` so `NOTEBOOKS_PROMPT` loads during evals. - `list_notebooks` gains a `sort_by: 'name' | 'inserted_at'` param, forwarded to `getContent`'s `sort`. Only creation order is exposed, since the underlying API has no `updated_at` sort key. - 3 new dataset cases: basic notebook enumeration, sorting by creation time (`sort_by`/`limit` args), and a nonexistent-notebook case guarding against hallucinated results. - A unit test covering `sort_by` forwarding to the content API's query param. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added notebook sorting options when listing notebooks, including by name or insertion date. * Added evaluation coverage for listing notebooks, finding the newest notebook, and avoiding fabricated results for nonexistent notebooks. * **Bug Fixes** * Ensured selected notebook sorting preferences are correctly applied when retrieving content. * Improved assistant evaluation coverage with Explorer mode enabled. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b9835e419c |
test(studio): mock notebook tools (#48952)
## Summary - Adds deterministic `list_notebooks`/`get_notebook` fixtures (two seeded notebooks, each with markdown/database/log cells) and stateful in-memory `create_notebook`/`update_notebook` mocks to `apps/studio/lib/ai/tools/mock-tools.ts`, so Braintrust evals can exercise notebook tool calls without a real project. - Both write-tool mocks force `needsApproval: false`, matching the existing `execute_sql`/`deploy_edge_function` mock pattern — the eval harness filters out tool-parts in `'approval-requested'` state and can never answer an approval gate. - All four notebook tools are wrapped from the real `getNotebookTools()` definitions (only `execute`/`needsApproval` overridden), so evals validate the model's arguments against the exact production schemas. - Dedupes `describeOperationError` (previously duplicated between this new mock and `notebook-tools.ts`) into a single exported `describeNotebookOperationError` in `notebook-operations.ts`. **Stacked on #48949** (`feature/notebooks-update-tool`) — this PR's base branch is that PR, not `master`, because it reuses `update_notebook` and the shared error helper that only exist there. Merge #48949 first, then retarget/merge this one. ## Test plan - [x] \`pnpm --filter studio typecheck\` passes - [x] \`pnpm --filter studio test\` — all notebook-related suites pass (\`mock-tools.test.ts\`, \`notebook-tools.test.ts\`, \`data/content/notebooks/*\`) - [x] \`eslint\` / \`prettier --check\` clean on all touched files |
||
|
|
4da8bfe469 |
feat(studio): wire update_notebook tool (#48949)
## Summary - Adds `update_notebook`, an AI tool (`needsApproval: true`) that re-fetches a notebook, applies an ordered list of cell operations (insert/replace/delete/move, from `notebook-operations.ts`) via `applyNotebookOperations`, and PUTs the resolved content. Concurrent edits are last-write-wins, since re-fetching at execute time is the only mitigation per the RFC. - Registers `update_notebook` in `toolSetValidationSchema` / `TOOL_CATEGORY_MAP`, and documents it in the notebooks system prompt. - The untrusted→safe SQL promotion (`acceptUntrustedSql`/`acceptUntrustedLogsSql`) is inlined directly inside each `needsApproval: true` tool's own `execute` (both `create_notebook` and `update_notebook`), rather than behind a shared helper — kept auditable right next to the approval gate that authorizes it, and not reusable by an unrelated caller unaware it needs re-promotion. Resolves FE-4083 ## Test plan - [x] `notebook-tools.test.ts`: re-fetch → apply operations → PUT with promoted SQL; descriptive error (no PUT) when an operation targets an unknown cell id; `needsApproval` asserted for both create and update - [x] `pnpm vitest run` on `notebook-tools.test.ts`, `tools/index.test.ts`, `tool-filter.test.ts` — all pass - [x] `tsc --noEmit`, `eslint`, `prettier --check` — clean on all touched files <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * AI-assisted notebook editing now supports updating existing notebooks. * Notebook changes are refreshed before being applied to help preserve the latest content. * Updates report operation errors and return a summary of the modified notebook. * Notebook edits require user approval before being saved. * **Bug Fixes** * Invalid or unknown cell references are reported without applying a partial update. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
47595f8ac7 |
feat(self-hosted): implement queryLogs for the MCP debugging tools (#48900)
> [!IMPORTANT] > > Only merge this when (https://github.com/supabase/platform/pull/36804) is merged, as the AI assistant will not have access to the `query_logs` tool for the remote MCP server ## 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 (self-hosted / CLI Studio MCP server). ## What is the current behavior? Self-hosted `getDebuggingOperations` (`apps/studio/lib/api/self-hosted/mcp.ts`) implements only `getLogs`, so the MCP `debugging` group exposes `get_logs` — a fixed per-service log dump built by `getLogQuery`. Logs are served by Logflare, which speaks BigQuery SQL. ## What is the new behavior? Bumps `@supabase/mcp-server-supabase` to `^0.10.0` (adds `query_logs` + `logsDialect`, and hides `get_logs` wherever a platform declares `queryLogs`) and moves logs over to it. - **Self-hosted `query_logs`:** declares `logsDialect: 'bigquery'` and implements `queryLogs`, passing the model's SQL straight through to the same Logflare `logs.all` endpoint (arbitrary `sql` param) — no new endpoint, no dialect translation. - **Drops `get_logs` from self-hosted:** `getLogs` throws (the server hides it once `queryLogs` exists) and the per-service `getLogQuery` builder is deleted; the model now writes its own BigQuery SQL, guided by the dialect schema hint. - **Honors no-logs mode:** `query_logs` throws when `logs:all` is disabled — the self-hosted default, enabled via the `docker-compose.logs.yml` override. - **Assistant:** switches the dashboard assistant from `get_logs` to `query_logs` (allowlist, drift guard, prompt, mocks, evals). Refs AI-1046 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * AI debugging can query recent project logs using read-only SQL. * Log queries support optional time-range filters, filtering, aggregation, and joins. * Self-hosted debugging checks whether logging is enabled before running queries. * **Bug Fixes** * Updated debugging workflows and validation to consistently use the new log-query capability. * Removed reliance on legacy service-specific log filtering and query behavior. * **Documentation** * Updated MCP debugging tool guidance to describe SQL-based log queries. * **Tests** * Expanded coverage for enabled, disabled, and unsupported logging scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ddb3e2c442 |
feat(studio): create_notebook AI tool (#48938)
## Summary - Adds a `create_notebook` AI assistant tool (`needsApproval: true`) that lets the assistant create a new notebook after explicit user approval. - Cell SQL is promoted from untrusted to safe via `acceptUntrustedSql`/`acceptUntrustedLogsSql` inside `execute`, using the approval gate as the confirming user gesture (same pattern as `execute_sql`). - Input is validated against the existing agent-writable notebook schema, which rejects any agent-supplied cell `id` at the schema level. - Threads an optional auth-headers param through `upsertContent`/`createNotebook`/`updateNotebook` so the tool can pass its own bearer token server-side. - Registers the tool in the tool-filter (`SCHEMA` category, alongside `list_notebooks`/`get_notebook`) and adds a `## Notebooks` prompt section guiding the assistant on when to use `create_notebook` vs. one-off `execute_sql`. Resolves FE-4082 ## Test plan - [x] `notebook-tools.test.ts` covers: tool registration, `needsApproval`, cell-id rejection, valid input, PUT body shape, and the returned id — all passing - [x] Typecheck clean - [x] Lint clean (no new warnings) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added AI-assisted notebook creation for saving multi-step investigations. * Added support for database and log SQL cells in newly created notebooks. * Notebook creation requires approval before saving and returns the notebook’s name and identifier. * Added support for custom request headers during notebook and content operations. * Added guidance for choosing between one-time SQL execution and reusable notebooks when Explorer is enabled. * **Improvements** * Improved validation and normalization of notebook content before saving. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
7798e42435 |
feat(studio): notebook read tools (#48908)
## Summary - Adds `list_notebooks` (cursor-paginated) and `get_notebook` AI tools in `lib/ai/tools/notebook-tools.ts`, modeled directly on `report-tools.ts`: server-side `getContent`/`getNotebook` with the `authorization` header forwarded, zod-validated input. - `get_notebook` resolves every cell and exposes `unchecked_sql` as a plain `sql` field for the agent to read — display only, per the `safe-sql-execution` skill; nothing here executes SQL. - Registers both tools in `lib/ai/tools/index.ts` (same platform branch as reports) and in `lib/ai/tool-filter.ts`'s `toolSetValidationSchema` + `TOOL_CATEGORY_MAP` (`SCHEMA` tier). - Adds an optional `headers` param to `content-infinite-query.ts`'s `getContent`, mirroring the sibling `content-query.ts`, so the cursor-paginated fetch can carry the `Authorization` header from a server context. - New tools are behind the Explorer feature flag. Stacked on #48907 (1.4 — notebook query and mutation hooks), per the Notebooks implementation plan (stack 2.1). Resolves FE-4081 Resolves FE-4080 ## Test plan - [x] `pnpm exec tsc --noEmit` — no new errors - [x] `pnpm exec vitest run lib/ai/tools/notebook-tools.test.ts lib/ai/tools/index.test.ts lib/ai/tools/report-tools.test.ts data/content/notebooks` — 36/36 passing - [x] `pnpm --filter studio run lint` — no new warnings - [x] `pnpm exec prettier --check` on changed files — clean <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added AI tools to list project notebooks with pagination. * Added AI support for retrieving notebook markdown and resolved SQL cell content. * Notebook tools now respect project and authorization context. * Notebook features are available only when Explorer access is enabled. * Content requests can forward custom request headers. * **Tests** * Added coverage for notebook tools, Explorer access, feature flags, authorization, pagination, and error handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
b04d14856a |
Resolve AI opt-in and tracing settings server-side (#48855)
The AI endpoints resolved organization and project settings independently and applied them together without confirming they belonged to the same pairing. Consolidates both into a single `getAIDetails` that reconciles them and falls back to the most restrictive posture when unconfirmed, and applies the HIPAA sensitivity gate to the opt-in level, which previously only existed on the client. Fixes FE-4110 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Consolidated AI access details across organization and project settings. - AI functionality now validates project ownership and disables access for mismatched or HIPAA-sensitive projects. - AI responses include plan, region, opt-in status, sensitivity, authorization, and advanced model access information. - **Bug Fixes** - Improved fail-closed behavior when project or organization data is missing or inconsistent. - Updated AI generation, feedback, rate, and policy flows to consistently apply consolidated access settings. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
0b97e37ccf |
feat: notebook content schema (#48813)
Related to FE-4109. ## Summary - **API codegen workaround**: Platform API's `notebook` content type hasn't shipped to the OpenAPI spec yet, so `pnpm api:codegen` can't be run. Locally widened `ContentBase.type` to include `'notebook'` (marked with TODO for removal once spec publishes). - **Notebook schema & type system**: Introduced Zod schemas mirroring RFC-defined notebook shape (`schema_version: 1, cells: Cell[]`). Maintains wire/domain boundary (cell `sql` → `unchecked_sql` branded for security). Agent-writable schema for `create_notebook` tool omits cell IDs (backend-generated); future update operations will require them. All TypeScript types are `z.infer`'d from schemas (no hand-written parallel interfaces). - **IsoDateTimeString moved**: Extracted ISO datetime validator from `querySource.ts` to `lib/iso-datetime.ts` (data layer shouldn't import from components layer). Needed by notebook `time_range` fields. ## Test plan - [x] Unit tests: `notebook-schema.test.ts` (9 tests), `iso-datetime.test.ts` (3 tests), `querySource.test.ts` updated and passing (26 tests) - [x] Typecheck: no new errors - [x] Prettier: formatting clean <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added support for validating and processing notebook content, including markdown, database, log cells, time ranges, and chart configurations. - Added compatibility for notebook content types in content handling. - Added reliable ISO date-time validation for notebook data and related features. - **Tests** - Expanded coverage for valid and invalid notebook structures, cell requirements, time ranges, chart settings, and date-time values. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> |
||
|
|
cddb430310 |
feat(studio): scoped pat root branch (#48384)
## Description This is the Scoped PAT stacked PRs root branch ## How to test ### With the `scopedPAT` enabled (default on staging) Go to https://studio-staging-git-scopedpat-merge-token-lists-supabase.vercel.app/dashboard/account/tokens. - You shouldn't see two tabs anymore - If you had classic tokens, they should have the _Legacy_ badge - You can create scoped tokens - You have a way to copy newly created tokens before closing the form side panel ### With the `scopedPAT` disabled (use the devtool to override) - You shouldn't see two tabs anymore - If you had classic tokens, they should **not** have the _Legacy_ badge - You can create classic tokens - You have a way to copy newly created tokens above the list upon form submission <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Show classic and scoped access tokens together in one list, with classic tokens labeled “Legacy” when the scoped experience is enabled. * Add scoped access token creation with a two-step configure → review → success flow (when enabled). * Add a dismissible migration notice about scoped tokens with a link to API docs. * Show “View permissions” only for scoped tokens. * **Bug Fixes** * Token deletion now supports both classic and scoped tokens with the correct confirmation and success handling. * The scoped tokens page now redirects to the unified access tokens page. * **Accessibility** * Improved accessibility by adding a label to the token “more options” action. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ali Waseem <waseema393@gmail.com> Co-authored-by: kemal.earth <606977+kemaldotearth@users.noreply.github.com> |
||
|
|
21511042a3 |
feat(studio): assistant logs context and reports guard (#48514)
## 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 — final PR (9/9) of the SQL editor logs-source stack. **Base branch:** `charislam/sql-editor-inline-ai-clickhouse-dialect` (PR 8). Nothing here is user-visible: entry points stay behind `sqlEditorLogsSource` + `otelLegacyLogs`, and flag rollout happens after the whole stack merges. ## What is the current behavior? - The Assistant has no idea a SQL editor snippet targets the logs backend. Ask it about a logs snippet and it answers in Postgres, because the attached query is fenced as ` ```sql ` and nothing tells the model otherwise. - Because the `sql` fence is what `MessageMarkdown` treats as runnable Postgres, an attached ClickHouse query is rendered with a Run-against-Postgres affordance and branded with `untrustedSql`. - "Debug with Assistant" on a failed logs query produces a dialect-less prompt, so both the in-app assistant and the copyable version get debugged as Postgres. - A report referencing a `log_sql` snippet runs its ClickHouse SQL against the user's Postgres database and surfaces the resulting error. ## What is the new behavior? **Assistant panel.** The "Current Query" chip records which backend the attached query targets. That reaches the model two ways: each attachment is fenced with its own dialect (` ```clickhouse ` vs ` ```sql `), and a `containsLogsSnippets` flag rides on the user message as AI SDK `metadata`. The server reads the flag off the conversation and prepends the ClickHouse dialect rules plus the logs schema reference as a non-cached context message. Two design points worth calling out in review: - The flag lives on the **message**, not the request body, so Retry and the tool-approval continuation reproduce the context a message was originally asked in — neither of those passes a per-call body. - It's derived from **what's actually attached**, so detaching the chip drops the claim rather than leaving the two able to disagree. The `clickhouse` fence also keeps a logs query out of `MessageMarkdown`'s `sql` branch, so it's no longer offered as runnable Postgres or branded with `untrustedSql` — a boundary this stack's distinct brands exist to prevent crossing. **Debug flow.** `buildDebugChatArgs` attaches its query with a source for the same reason, and names the dialect in the prompt text so the copyable version stands on its own outside the app. **Reports.** A report only stores a snippet id, so whether it queries the logs backend is only knowable once the content loads. `ReportBlock` guards on the fetched type and renders a `LogsSnippetReportBlock` placeholder instead of executing. Double-guarded: no `sql` for a logs snippet (so it's out of the query key and `queryFn` short-circuits even on an explicit `refetch`) and `enabled` excludes it. **Incidental cleanups.** `buildAssistantContextMessages` extracted out of `generate-assistant-response`; a schema-access sentinel that was duplicated as a string literal across two files (and compared against) replaced with one exported constant; `SqlSnippet` deduplicated to a single declaration; `resolveSnippetSource` / `isLogsSource` shared instead of re-implemented per surface. **Tests.** 4 new/extended suites. Notable cases pinned: a message with no metadata must validate (`safeValidateUIMessages` applies `metadataSchema` to *every* message, so a required schema would 400 every existing conversation); only *user* messages count, so a model reply can't talk the server into a different dialect; a mixed-attachment message is flagged without overclaiming a single source; and `ReportBlock` registers no pg-meta mock for the logs cases, so an unhandled request failing the test *is* the assertion that logs SQL never reaches Postgres. Verified: `pnpm typecheck`, `lint:ratchet` (no regression), Prettier, and the full Studio suite (459 files / 4969 tests). ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added support for recognizing log snippets in reports, with clear guidance to open them in the SQL editor or remove them. - AI Assistant now understands log snippets and provides ClickHouse-specific context, formatting, and troubleshooting guidance. - Snippets retain their source information when shared with the AI Assistant. - **Bug Fixes** - Prevented unsupported log snippets from being executed as regular database queries. - Improved source detection when opening snippets directly from links. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
8b38e0d1ed |
feat(studio): ClickHouse dialect for logs snippet AI + rewrite to ClickHouse (#48501)
## 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, plus a refactor of the shared logs-rewrite flow. PR 8 of the SQL editor query-source series. Stacked on #48457 — review that one first, and merge this after it. ## What is the current behavior? A `log_sql` snippet runs against the ClickHouse-backed analytics endpoint, but the SQL editor's AI still writes Postgres: inline edits get Postgres system prompts, and the result is run through `sql-formatter`, which mangles ClickHouse backticks and `log_attributes` map lookups. Legacy Logs Explorer saved queries open in the editor as `log_sql` snippets. Those are BigQuery dialect and error against the ClickHouse endpoint the editor runs them on, with no in-editor way out — only the Logs Explorer offered a rewrite. The completion route was also asymmetric. It assembled a schema/code/instruction message for Postgres but forwarded `prompt` verbatim for ClickHouse, so a client wanting ClickHouse had to hand-build the equivalent string. ## What is the new behavior? **Inline AI speaks ClickHouse for logs snippets.** `sqlSourceToDialect` maps a snippet's source to `postgres`/`clickhouse` and `buildCompletionRequestBody` threads it through. For ClickHouse, `useSqlEditorAi` strips code fences from the response and skips `formatSql`. Execution and dialect both follow the snippet type, so a snippet's valid dialect never flips. **Rewrite to ClickHouse in the editor.** A banner offers the rewrite for a logs snippet whose text trips `looksLikeLegacyLogsQuery`, and proposes the result through the editor's existing AI diff view rather than replacing the snippet, so it's accepted or discarded like any other AI edit. Gated on `otelLegacyLogs`: on a non-migrated org the BigQuery text is still correct, so rewriting it would break a working query. The offer is a state machine (`offered` / `rewriting` / `failed` / `noRewriteNeeded` / `dismissed`) with a declarative table of valid transitions, so the states are mutually exclusive by construction and dismissal is terminal. A failure keeps its message and offers a retry; a response identical to the input is reported rather than opening an empty diff. **One place assembles completion prompts.** The route now uses a single template for both dialects, branching only the schema section and — for `intent: 'rewrite'` — the instruction. `lib/ai/clickhouse-logs.ts` is the single home for ClickHouse-logs prompt content, replacing two independently maintained descriptions of the same table. Clients carry no prompt text. **The rewrite flow is shared with the Logs Explorer.** Both surfaces previously hand-rolled the same sequence and had drifted: only one detected a no-op rewrite, they sourced `log_attributes` keys differently, and the Explorer formatted errors with an `as Error` cast. Both now use `useLegacyLogsRewrite` and the same state-driven banner, so the Explorer picks up no-op detection and typed error extraction. **Attribute keys are fetched on submit, not while typing.** The detected source would otherwise feed a reactive query key, making every edit that changed it cost another network call. `useLogsAttributeKeys` is imperative and goes through `queryClient.fetchQuery`, so a source already cached — including by the Explorer header and query panel, which subscribe reactively — is reused. This also closes a gap where inline edits never received keys at all, unlike full rewrites. `getErrorMessage` gains an optional typed fallback and no longer stringifies a bare object into `'[object Object]'`; every existing caller already hand-rolled a fallback, except `QueueSettings`, which interpolated the raw result and now passes one. Nothing here is user-visible until the `sqlEditorLogsSource` flag is enabled. Tests: dialect selection and request-body shape, the ClickHouse prompt content (including that the schema section does not restate the dialect rules), the reducer's valid and invalid transitions, `shouldOfferLegacyLogsRewrite`, on-submit key discovery with cache reuse, and `getErrorMessage`. ## Additional context <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an Assistant banner to help rewrite legacy BigQuery-style logs queries into ClickHouse SQL. * SQL assistance now adapts to the selected query type, including relevant log attribute context. * Rewrite suggestions can be reviewed as editor diffs before being applied. * **Bug Fixes** * Improved rewrite failure handling, retry options, dismissal behavior, and “no rewrite needed” messaging. * Error notifications now provide a clearer fallback message when details are unavailable. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
a0cec24f49 |
Remove references to fly (#48648)
## Context As per PR title - should not have any visual nor functional change <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Changes** - Standardized infrastructure, region, and database configuration around AWS-based environments. - Removed Fly.io-specific region and provider options from project creation, instance sizing, and infrastructure settings. - Enabled disk validation, spend-cap eligibility, backup restoration, and extension setup consistently across supported projects. - Updated billing and region displays to use the applicable AWS configuration. - **Bug Fixes** - Corrected project-specific restrictions that could incorrectly hide configuration and billing controls. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
73c9dbfa52 |
fix(studio): standardise custom icon weight (#48478)
## What kind of change does this PR introduce? Bug fix and internal tooling update. Resolves FE-3472. ## What is the current behavior? Custom Studio icons use inconsistent source stroke widths, and some child-level styling prevents component props from overriding them. Mixed custom and Lucide icon sets can therefore appear uneven. ## What is the new behavior? Custom stroke icons use a root-level `stroke-width="1.5"`; fill-only logos use `stroke="none"`. The build validates that contract and regenerated components preserve existing exports and props. Studio applies the same `1.5` weight across Reports categories and uses one shared destination icon mapping in the replication selector, destination rows and diagram. | Before | After | | --- | --- | | <img width="418" height="516" alt="56398" src="https://github.com/user-attachments/assets/6afa7042-e6be-40e7-9911-af2f61238c9d" /> | <img width="390" height="550" alt="CleanShot 2026-07-30 at 17 12 37@2x" src="https://github.com/user-attachments/assets/870f49cf-c8fa-40db-8be8-2eb5f264ff4a" /> | | <img width="510" height="734" alt="CleanShot 2026-07-30 at 17 19 28@2x" src="https://github.com/user-attachments/assets/a5b2c088-dcd2-4907-976b-5820794d06e3" /> | <img width="554" height="742" alt="CleanShot 2026-07-30 at 17 16 06@2x" src="https://github.com/user-attachments/assets/ed3a77c4-5d94-4ca7-b9e4-1403b725a981" /> | ## Testing At 100% zoom, compare custom and Lucide icon weight in: - Reports: **Add your first chart** and **Add block** - Database > Replication: the destination selector, destination rows and replication diagram - Command menu (`⌘K`): **Search Database Tables**, **Search RLS Policies**, **Search Edge Functions** and **Search Storage** - Authentication > Users: right-click a user row and compare the context-menu icons - Database > Schema Visualizer: open a table node overflow menu - A paused project: **Export your data > Download backups** <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added consistent destination icons across replication panels, rows, and diagrams. * Updated instance health and metric icons for clearer identification. * Standardized icon stroke weight and reduced default icon stroke thickness. * **Documentation** * Clarified custom icon requirements, default properties, and validation guidance. * **Bug Fixes** * Improved consistency of icon rendering across replication destinations and reports. * **Tests** * Added coverage for icon SVG validation and replication destination icon rendering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
2c53ca4a79 |
Support listing and reading custom reports from Assistant (#48530)
## Context This is pre-requisite work for adding support to managing custom reports from the Assistant. Planning to break this into a number of PRs, briefly - Adding read support for custom reports - Adding write support for custom reports - Adding run support for custom reports - Should be able to infer data from the results then This PR starts with adding support for listing and reading custom reports from the Assistant ## Other changes involved - Updates setting up of the home page report to have better title and description - Swaps the variant of the ToggleGroup in the SQL block for custom reports as the default variant blends into the background color of the PopoverContent ## To test - [ ] Assistant should be able to list custom reports + read its contents <img width="428" height="755" alt="image" src="https://github.com/user-attachments/assets/6a15b660-c0ee-4a06-984c-87eff3943eec" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added AI-assisted tools to list reports and retrieve report details, including chart counts, layouts, configurations, and SQL-backed chart information. - Added clearer empty-state messaging when no snippets are available. - **Improvements** - New homepage reports now use the name “Homepage Report” and include a descriptive project-home summary. - Updated query controls with refreshed visual styling. - Improved content requests to support additional request context. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e88a3723e1 |
feat(studio): add PostHog session replay with masked-by-default policy (#48515)
## 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? Telemetry feature. ## What is the current behavior? - Session replay is off, and nothing in the code keeps it off. - `packages/common/posthog-client.ts` sets no recording config at all. - So PostHog's project setting alone decides, for every app sharing that project. - Studio, www and docs share one project. - Studio shows customer data almost everywhere: SQL editor, table rows, connection strings, API keys. - posthog-js masks inputs by default. It does not mask rendered text. - [GROWTH-1055](https://linear.app/supabase/issue/GROWTH-1055) ## What is the new behavior? - `posthogClient.init()` takes a masking config, and disables recording when it gets none. - Studio passes one behind `NEXT_PUBLIC_POSTHOG_SESSION_REPLAY`. - Every other app passes nothing, so it never loads the recorder. - Studio masks all text and all inputs. - `data-ph-capture="true"` opts one element's text back in. Unused so far. - Canvas is blocked, because it records as images that text masking cannot reach. - Query strings and fragments are stripped from recorded URLs, where auth callbacks carry tokens. - Request and response bodies are never recorded. - Console logs are never recorded, since masking only reaches DOM text. - Masking is set in code, so PostHog's settings cannot loosen it. - Consent gating is unchanged. Nothing records before a user accepts. ## Additional context - Recording needs three things: this env var, the PostHog project toggle, and user consent. - All three are off or unset, so merging this changes nothing at runtime. - `NEXT_PUBLIC_POSTHOG_SESSION_REPLAY` goes into Vercel on Preview scope first, to test on a preview build. - Production scope comes later, once we are ready to record there. - `NEXT_PUBLIC_*` is inlined at build time, so each scope needs a rebuild afterwards. - Text inside HTML attributes (`title`, `alt`, `href`) is still recorded as-is. - posthog-js exposes no hook for masking attributes, so covering it needs `ph-no-capture` per component. - Staging has no server-side masking config, so that is where this gets verified. - Plan: enable recording on staging, verify masked text on a preview, then decide on production. - Network timing stays on for the dashboard performance work. Payloads stay off. - Tests cover both masking functions and the config values. ## Screenshots https://github.com/user-attachments/assets/aa064a04-f977-4453-a3da-2fe0cdcead08 <img width="889" height="651" alt="CleanShot 2026-07-31 at 10 13 43" src="https://github.com/user-attachments/assets/f1d07946-fd68-42b2-89f1-d201bc605638" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Added privacy-focused session replay for Studio. * Text and form inputs are masked by default, with explicit opt-in capture. * Network recordings remove query strings and fragments. * Headers, request bodies, canvas data, and console logs are excluded. * **Bug Fixes** * Improved whitespace and capture-attribute handling during masking. * Session replay remains disabled without a masking policy or explicit enablement. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |