improvement(supabase): add Edge Functions tool; correct storage output shapes + harden tools#5112
Conversation
…t shapes + harden tools
- Add supabase_invoke_function tool (POST/GET/PUT/PATCH/DELETE /functions/v1/{name})
- upsert: support on_conflict; storage upload: support cache-control
- Fix storage copy/move/upload/delete-bucket output properties to match live API
- get_public_url: build URL via directExecution (no spurious network call)
- text_search: validate column identifier
- Strip non-TSDoc section-label comments
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Supabase follow-ups: upsert gains optional Tavily: most optional subBlocks move to advanced mode; search results map Reviewed by Cursor Bugbot for commit 8947057. Configure here. |
Greptile SummaryThis PR adds a
Confidence Score: 5/5Safe to merge — the changes are additive, well-tested, and fix real output-shape bugs without touching any breaking API surface. The new Edge Function tool is cleanly isolated, its identifier validation prevents path injection, and the block-level params builder correctly scopes new fields so they cannot leak into unrelated operations. The Tavily content fix corrects a consistently empty output field. Storage output-shape corrections and the directExecution conversion for public URL are accurate against the Supabase API. The two observations flagged are HTTP-semantics nits that are unlikely to produce observable failures with Supabase's infrastructure today. No files require special attention; the invoke_function.ts Content-Type and fallback-body observations are minor and do not affect correctness on current Supabase infrastructure. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Block params] --> B{operation?}
B -->|invoke_function| C[destructure method / functionBody / functionHeaders]
B -->|other ops| D[fields excluded from result - no leakage]
C --> E[parse functionBody as JSON to result.body]
C --> F[validate and parse functionHeaders to result.headers]
C --> G[pass method to result.method]
E & F & G --> H[supabase_invoke_function tool]
H --> I[validateFunctionName]
I -->|invalid| J[throw Error]
I -->|valid| K[resolveMethod - default POST]
K -->|GET| L[body = undefined]
K -->|non-GET| M[body = params.body]
L & M --> N[fetch /functions/v1/name with auth headers]
N --> O{response content-type}
O -->|application/json| P[response.json to results]
O -->|other| Q[response.text to results]
P & Q --> R[return success output]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[Block params] --> B{operation?}
B -->|invoke_function| C[destructure method / functionBody / functionHeaders]
B -->|other ops| D[fields excluded from result - no leakage]
C --> E[parse functionBody as JSON to result.body]
C --> F[validate and parse functionHeaders to result.headers]
C --> G[pass method to result.method]
E & F & G --> H[supabase_invoke_function tool]
H --> I[validateFunctionName]
I -->|invalid| J[throw Error]
I -->|valid| K[resolveMethod - default POST]
K -->|GET| L[body = undefined]
K -->|non-GET| M[body = params.body]
L & M --> N[fetch /functions/v1/name with auth headers]
N --> O{response content-type}
O -->|application/json| P[response.json to results]
O -->|other| Q[response.text to results]
P & Q --> R[return success output]
Reviews (5): Last reviewed commit: "fix(supabase): include last_accessed_at ..." | Re-trigger Greptile |
…blic_url apiKey
- rpc: validate + encode functionName (SSRF/injection parity with vector_search)
- text_search: validate language config interpolated into the PostgREST operator
- get_public_url: remove unused apiKey param + dead auth headers (public endpoint needs no auth)
- create_bucket: tighten output description to match the {name}-only response
… output - Mark 29 optional search/extract/crawl/map subBlocks as mode: advanced (keep query/urls/url/apiKey basic) - Fix search transformResponse: populate content from result.content (was result.snippet, always empty) - Guard data.results with ?? []; correct country placeholder to a lowercase name - Rewrite stale TavilySearch/Extract response interfaces; drop dead duplicate interfaces
…ionName description - storage upload: expand a bare numeric cache-control to `max-age=<n>` (a raw number is not a valid Cache-Control header) - block: functionName input description now covers RPC, vector search, and Edge Function invoke
|
Thanks @cursor — addressing the two flagged points:
Pushed fixes for greptile's P1 (valid |
|
@greptile |
|
@cursor review |
- invoke_function: drop unreachable !response.ok branch (executor throws on non-OK before transformResponse runs and surfaces the error body); document the success-only contract - invoke_function: ignore non-object (array) headers so JSON arrays can't produce numeric-index header names - block: reject array/non-object Edge Function headers with a clear error in config.params
|
@greptile |
|
@cursor review |
…tion Prevents a stale `method` value (e.g. from the Edge Function field) from leaking into other operations' params. The tool executor lets `params.method` override a tool's static verb (tools/utils.ts), so an unscoped value could turn a read into DELETE/POST against PostgREST. Now method/body/headers are only passed for the invoke_function operation. Adds a block-level regression test.
|
@greptile |
|
@cursor review |
Stale or invalid functionBody/functionHeaders left in the block (common when switching operations) were parsed and validated for every operation, so they could throw before unrelated tools ran even while hidden. Moved parsing and validation inside the invoke_function guard; added a regression test.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 7687d28. Configure here.
|
@greptile |
The Storage list API accepts last_accessed_at for sortBy; add it to the tool description and the block dropdown so the surfaced options match the API.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8947057. Configure here.
Summary
Supabase
supabase_invoke_functiontool to invoke Supabase Edge Functions over HTTP (/functions/v1/{name}), with configurable method, JSON body, and custom headers — wired through the block (new operation, subBlocks, params mapping, inputs, skill)upsertnow supportson_conflict; storageuploadnow supportscache-controlpropertiesto match what the API actually returns:copy({Id,Key}),move({message,Id,Key}),upload({Id,Key,path,bucket,publicUrl}),delete_bucket({message})get_public_urlbuilds the URL viadirectExecution(no spurious network round-trip); dropped its now-unusedapiKeyparamrpcvalidates/encodesfunctionName(parity withvector_search);text_searchvalidatescolumnandlanguageTavily (follow-up validation pass)
mode: advanced(keptquery/urls/url/apiKeybasic)transformResponse: populatecontentfromresult.content(wasresult.snippet, so the output was always empty)data.results; correctedcountryplaceholder; rewrote stale response interfaces and removed dead duplicatesType of Change
contentoutput)Testing
Validated every endpoint against the live Supabase storage-api source, PostgREST, Tavily, and Edge Functions docs, with independent parallel re-validation.
bun run lint,tsc,check:api-validation, and the Supabase unit tests all pass. Backward compatible — no tool IDs, param names, operation values, or existing I/O keys renamed/removed.Checklist