feat(supabase): added vector search tool and updated docs (#1707)

* feat(supabase): added vector search tool and updated docs

* exclude generic webhook from docs gen

* change items to pages in meta.json for tools directory in the docs
This commit is contained in:
Waleed
2025-10-21 18:48:18 -07:00
committed by GitHub
parent ca1156a6c2
commit 4d7ebd8bcb
18 changed files with 283 additions and 9 deletions

View File

@@ -75,6 +75,7 @@ Send a message to a Discord channel
| `channelId` | string | Yes | The Discord channel ID to send the message to |
| `content` | string | No | The text content of the message |
| `serverId` | string | Yes | The Discord server ID \(guild ID\) |
| `files` | file[] | No | Files to attach to the message |
#### Output

View File

@@ -230,4 +230,4 @@ curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
- Category: `triggers`
- Type: `generic_webhook`
- **File Support**: Available via input format configuration
- **Max File Size**: 20MB per file
- **Max File Size**: 20MB per file

View File

@@ -88,8 +88,9 @@ Upload a file to Google Drive
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `fileName` | string | Yes | The name of the file to upload |
| `content` | string | Yes | The content of the file to upload |
| `mimeType` | string | No | The MIME type of the file to upload |
| `file` | file | No | Binary file to upload \(UserFile object\) |
| `content` | string | No | Text content to upload \(use this OR file, not both\) |
| `mimeType` | string | No | The MIME type of the file to upload \(auto-detected from file if not provided\) |
| `folderSelector` | string | No | Select the folder to upload the file to |
| `folderId` | string | No | The ID of the folder to upload the file to \(internal use\) |

View File

@@ -138,6 +138,7 @@ Write or update content in a Microsoft Teams chat
| --------- | ---- | -------- | ----------- |
| `chatId` | string | Yes | The ID of the chat to write to |
| `content` | string | Yes | The content to write to the message |
| `files` | file[] | No | Files to attach to the message |
#### Output
@@ -187,6 +188,7 @@ Write or send a message to a Microsoft Teams channel
| `teamId` | string | Yes | The ID of the team to write to |
| `channelId` | string | Yes | The ID of the channel to write to |
| `content` | string | Yes | The content to write to the channel |
| `files` | file[] | No | Files to attach to the message |
#### Output

View File

@@ -66,7 +66,8 @@ Upload a file to OneDrive
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `fileName` | string | Yes | The name of the file to upload |
| `content` | string | Yes | The content of the file to upload |
| `file` | file | No | The file to upload \(binary\) |
| `content` | string | No | The text content to upload \(if no file is provided\) |
| `folderSelector` | string | No | Select the folder to upload the file to |
| `manualFolderId` | string | No | Manually entered folder ID \(advanced mode\) |

View File

@@ -161,6 +161,7 @@ Send emails using Outlook
| `conversationId` | string | No | Conversation ID for threading |
| `cc` | string | No | CC recipients \(comma-separated\) |
| `bcc` | string | No | BCC recipients \(comma-separated\) |
| `attachments` | file[] | No | Files to attach to the email |
#### Output
@@ -184,6 +185,7 @@ Draft emails using Outlook
| `body` | string | Yes | Email body content |
| `cc` | string | No | CC recipients \(comma-separated\) |
| `bcc` | string | No | BCC recipients \(comma-separated\) |
| `attachments` | file[] | No | Files to attach to the email draft |
#### Output

View File

@@ -202,6 +202,26 @@ Add a new item to a SharePoint list
| --------- | ---- | ----------- |
| `item` | object | Created SharePoint list item |
### `sharepoint_upload_file`
Upload files to a SharePoint document library
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | No | The ID of the SharePoint site |
| `driveId` | string | No | The ID of the document library \(drive\). If not provided, uses default drive. |
| `folderPath` | string | No | Optional folder path within the document library \(e.g., /Documents/Subfolder\) |
| `fileName` | string | No | Optional: override the uploaded file name |
| `files` | file[] | No | Files to upload to SharePoint |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `uploadedFiles` | array | Array of uploaded file objects |
## Notes

View File

@@ -82,6 +82,7 @@ Send messages to Slack channels or users through the Slack API. Supports Slack m
| `botToken` | string | No | Bot token for Custom Bot |
| `channel` | string | Yes | Target Slack channel \(e.g., #general\) |
| `text` | string | Yes | Message text to send \(supports Slack mrkdwn formatting\) |
| `files` | file[] | No | Files to attach to the message |
#### Output

View File

@@ -205,6 +205,28 @@ Insert or update data in a Supabase table (upsert operation)
| `message` | string | Operation status message |
| `results` | array | Array of upserted records |
### `supabase_vector_search`
Perform similarity search using pgvector in a Supabase table
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `projectId` | string | Yes | Your Supabase project ID \(e.g., jdrkgepadsdopsntdlom\) |
| `functionName` | string | Yes | The name of the PostgreSQL function that performs vector search \(e.g., match_documents\) |
| `queryEmbedding` | array | Yes | The query vector/embedding to search for similar items |
| `matchThreshold` | number | No | Minimum similarity threshold \(0-1\), typically 0.7-0.9 |
| `matchCount` | number | No | Maximum number of results to return \(default: 10\) |
| `apiKey` | string | Yes | Your Supabase service role secret key |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Operation status message |
| `results` | array | Array of records with similarity scores from the vector search. Each record includes a similarity field \(0-1\) indicating how similar it is to the query vector. |
## Notes

View File

@@ -191,6 +191,26 @@ Send animations (GIFs) to Telegram channels or users through the Telegram Bot AP
| `message` | string | Success or error message |
| `data` | object | Telegram message data including optional media |
### `telegram_send_document`
Send documents (PDF, ZIP, DOC, etc.) to Telegram channels or users through the Telegram Bot API.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `botToken` | string | Yes | Your Telegram Bot API Token |
| `chatId` | string | Yes | Target Telegram chat ID |
| `files` | file[] | No | Document file to send \(PDF, ZIP, DOC, etc.\). Max size: 50MB |
| `caption` | string | No | Document caption \(optional\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Success or error message |
| `data` | object | Telegram message data including document |
## Notes

View File

@@ -62,7 +62,8 @@ Process and analyze images using advanced vision models. Capable of understandin
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | API key for the selected model provider |
| `imageUrl` | string | Yes | Publicly accessible image URL |
| `imageUrl` | string | No | Publicly accessible image URL |
| `imageFile` | file | No | Image file to analyze |
| `model` | string | No | Vision model to use \(gpt-4o, claude-3-opus-20240229, etc\) |
| `prompt` | string | No | Custom prompt for image analysis |

View File

@@ -29,6 +29,7 @@ export const SupabaseBlock: BlockConfig<SupabaseResponse> = {
{ label: 'Update a Row', id: 'update' },
{ label: 'Delete a Row', id: 'delete' },
{ label: 'Upsert a Row', id: 'upsert' },
{ label: 'Vector Search', id: 'vector_search' },
],
value: () => 'query',
},
@@ -381,6 +382,41 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
placeholder: '100',
condition: { field: 'operation', value: 'query' },
},
// Vector search operation fields
{
id: 'functionName',
title: 'Function Name',
type: 'short-input',
layout: 'full',
placeholder: 'match_documents',
condition: { field: 'operation', value: 'vector_search' },
required: true,
},
{
id: 'queryEmbedding',
title: 'Query Embedding',
type: 'code',
layout: 'full',
placeholder: '[0.1, 0.2, 0.3, ...]',
condition: { field: 'operation', value: 'vector_search' },
required: true,
},
{
id: 'matchThreshold',
title: 'Match Threshold (optional)',
type: 'short-input',
layout: 'full',
placeholder: '0.78',
condition: { field: 'operation', value: 'vector_search' },
},
{
id: 'matchCount',
title: 'Match Count (optional)',
type: 'short-input',
layout: 'full',
placeholder: '10',
condition: { field: 'operation', value: 'vector_search' },
},
],
tools: {
access: [
@@ -390,6 +426,7 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
'supabase_update',
'supabase_delete',
'supabase_upsert',
'supabase_vector_search',
],
config: {
tool: (params) => {
@@ -406,12 +443,14 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
return 'supabase_delete'
case 'upsert':
return 'supabase_upsert'
case 'vector_search':
return 'supabase_vector_search'
default:
throw new Error(`Invalid Supabase operation: ${params.operation}`)
}
},
params: (params) => {
const { operation, data, filter, ...rest } = params
const { operation, data, filter, queryEmbedding, ...rest } = params
// Parse JSON data if it's a string
let parsedData
@@ -435,6 +474,21 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
parsedFilter = filter.trim()
}
// Handle query embedding for vector search
let parsedQueryEmbedding
if (queryEmbedding && typeof queryEmbedding === 'string' && queryEmbedding.trim()) {
try {
parsedQueryEmbedding = JSON.parse(queryEmbedding)
} catch (parseError) {
const errorMsg = parseError instanceof Error ? parseError.message : 'Unknown JSON error'
throw new Error(
`Invalid query embedding format: ${errorMsg}. Please provide a valid array of numbers like [0.1, 0.2, 0.3].`
)
}
} else if (queryEmbedding && Array.isArray(queryEmbedding)) {
parsedQueryEmbedding = queryEmbedding
}
// Build params object, only including defined values
const result = { ...rest }
@@ -446,6 +500,10 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
result.filter = parsedFilter
}
if (parsedQueryEmbedding !== undefined) {
result.queryEmbedding = parsedQueryEmbedding
}
return result
},
},
@@ -462,6 +520,11 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
// Query operation inputs
orderBy: { type: 'string', description: 'Sort column' },
limit: { type: 'number', description: 'Result limit' },
// Vector search operation inputs
functionName: { type: 'string', description: 'PostgreSQL function name for vector search' },
queryEmbedding: { type: 'array', description: 'Query vector/embedding for similarity search' },
matchThreshold: { type: 'number', description: 'Minimum similarity threshold (0-1)' },
matchCount: { type: 'number', description: 'Maximum number of similar results to return' },
},
outputs: {
message: {

View File

@@ -2,7 +2,7 @@ import type { JSX, SVGProps } from 'react'
import type { ToolResponse } from '@/tools/types'
export type BlockIcon = (props: SVGProps<SVGSVGElement>) => JSX.Element
export type ParamType = 'string' | 'number' | 'boolean' | 'json'
export type ParamType = 'string' | 'number' | 'boolean' | 'json' | 'array'
export type PrimitiveValueType =
| 'string'
| 'number'

View File

@@ -180,6 +180,7 @@ import {
supabaseQueryTool,
supabaseUpdateTool,
supabaseUpsertTool,
supabaseVectorSearchTool,
} from '@/tools/supabase'
import { tavilyExtractTool, tavilySearchTool } from '@/tools/tavily'
import {
@@ -271,6 +272,7 @@ export const tools: Record<string, ToolConfig> = {
supabase_update: supabaseUpdateTool,
supabase_delete: supabaseDeleteTool,
supabase_upsert: supabaseUpsertTool,
supabase_vector_search: supabaseVectorSearchTool,
typeform_responses: typeformResponsesTool,
typeform_files: typeformFilesTool,
typeform_insights: typeformInsightsTool,

View File

@@ -4,6 +4,7 @@ import { insertTool } from '@/tools/supabase/insert'
import { queryTool } from '@/tools/supabase/query'
import { updateTool } from '@/tools/supabase/update'
import { upsertTool } from '@/tools/supabase/upsert'
import { vectorSearchTool } from '@/tools/supabase/vector_search'
export const supabaseQueryTool = queryTool
export const supabaseInsertTool = insertTool
@@ -11,3 +12,4 @@ export const supabaseGetRowTool = getRowTool
export const supabaseUpdateTool = updateTool
export const supabaseDeleteTool = deleteTool
export const supabaseUpsertTool = upsertTool
export const supabaseVectorSearchTool = vectorSearchTool

View File

@@ -45,6 +45,15 @@ export interface SupabaseUpsertParams {
data: any
}
export interface SupabaseVectorSearchParams {
apiKey: string
projectId: string
functionName: string
queryEmbedding: number[]
matchThreshold?: number
matchCount?: number
}
export interface SupabaseBaseResponse extends ToolResponse {
output: {
message: string
@@ -65,4 +74,6 @@ export interface SupabaseDeleteResponse extends SupabaseBaseResponse {}
export interface SupabaseUpsertResponse extends SupabaseBaseResponse {}
export interface SupabaseVectorSearchResponse extends SupabaseBaseResponse {}
export interface SupabaseResponse extends SupabaseBaseResponse {}

View File

@@ -0,0 +1,125 @@
import type {
SupabaseVectorSearchParams,
SupabaseVectorSearchResponse,
} from '@/tools/supabase/types'
import type { ToolConfig } from '@/tools/types'
export const vectorSearchTool: ToolConfig<
SupabaseVectorSearchParams,
SupabaseVectorSearchResponse
> = {
id: 'supabase_vector_search',
name: 'Supabase Vector Search',
description: 'Perform similarity search using pgvector in a Supabase table',
version: '1.0',
params: {
projectId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Supabase project ID (e.g., jdrkgepadsdopsntdlom)',
},
functionName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'The name of the PostgreSQL function that performs vector search (e.g., match_documents)',
},
queryEmbedding: {
type: 'array',
required: true,
visibility: 'user-or-llm',
description: 'The query vector/embedding to search for similar items',
},
matchThreshold: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum similarity threshold (0-1), typically 0.7-0.9',
},
matchCount: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of results to return (default: 10)',
},
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Supabase service role secret key',
},
},
request: {
url: (params) => {
// Use RPC endpoint for calling PostgreSQL functions
return `https://${params.projectId}.supabase.co/rest/v1/rpc/${params.functionName}`
},
method: 'POST',
headers: (params) => ({
apikey: params.apiKey,
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
// Build the RPC call parameters
const rpcParams: Record<string, any> = {
query_embedding: params.queryEmbedding,
}
// Add optional parameters if provided
if (params.matchThreshold !== undefined) {
rpcParams.match_threshold = params.matchThreshold
}
if (params.matchCount !== undefined) {
rpcParams.match_count = params.matchCount
}
return rpcParams
},
},
transformResponse: async (response: Response) => {
let data
try {
data = await response.json()
} catch (parseError) {
throw new Error(`Failed to parse Supabase vector search response: ${parseError}`)
}
const resultCount = Array.isArray(data) ? data.length : 0
if (resultCount === 0) {
return {
success: true,
output: {
message: 'No similar vectors found matching the search criteria',
results: data,
},
error: undefined,
}
}
return {
success: true,
output: {
message: `Successfully found ${resultCount} similar vector${resultCount === 1 ? '' : 's'}`,
results: data,
},
error: undefined,
}
},
outputs: {
message: { type: 'string', description: 'Operation status message' },
results: {
type: 'array',
description:
'Array of records with similarity scores from the vector search. Each record includes a similarity field (0-1) indicating how similar it is to the query vector.',
},
},
}

View File

@@ -838,7 +838,7 @@ async function generateBlockDoc(blockPath: string, icons: Record<string, string>
return
}
if (blockConfig.type.includes('_trigger')) {
if (blockConfig.type.includes('_trigger') || blockConfig.type.includes('_webhook')) {
console.log(`Skipping ${blockConfig.type} - contains '_trigger'`)
return
}
@@ -1111,7 +1111,7 @@ function updateMetaJson() {
]
const metaJson = {
items,
pages: items,
}
fs.writeFileSync(metaJsonPath, JSON.stringify(metaJson, null, 2))