From 22942814b08ffa3c2b43e05b304c16ce80d82506 Mon Sep 17 00:00:00 2001 From: EwanTauran Date: Fri, 30 Jan 2026 13:25:59 +0100 Subject: [PATCH 1/3] feat(icons): add Airweave icon and update registry with Airweave block and tool --- apps/sim/blocks/blocks/airweave.ts | 99 ++++++++++++++++++++++ apps/sim/blocks/registry.ts | 2 + apps/sim/components/icons.tsx | 26 ++++++ apps/sim/tools/airweave/index.ts | 1 + apps/sim/tools/airweave/search.ts | 130 +++++++++++++++++++++++++++++ apps/sim/tools/airweave/types.ts | 84 +++++++++++++++++++ apps/sim/tools/registry.ts | 2 + bun.lock | 1 - 8 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 apps/sim/blocks/blocks/airweave.ts create mode 100644 apps/sim/tools/airweave/index.ts create mode 100644 apps/sim/tools/airweave/search.ts create mode 100644 apps/sim/tools/airweave/types.ts diff --git a/apps/sim/blocks/blocks/airweave.ts b/apps/sim/blocks/blocks/airweave.ts new file mode 100644 index 0000000000..e0a679383c --- /dev/null +++ b/apps/sim/blocks/blocks/airweave.ts @@ -0,0 +1,99 @@ +import { AirweaveIcon } from '@/components/icons' +import type { BlockConfig } from '@/blocks/types' +import { AuthMode } from '@/blocks/types' +import type { AirweaveSearchResponse } from '@/tools/airweave/types' + +export const AirweaveBlock: BlockConfig = { + type: 'airweave', + name: 'Airweave', + description: 'Search your synced data collections', + authMode: AuthMode.ApiKey, + longDescription: + 'Search across your synced data sources using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results.', + docsLink: 'https://docs.airweave.ai', + category: 'tools', + bgColor: '#6366F1', + icon: AirweaveIcon, + subBlocks: [ + { + id: 'collectionId', + title: 'Collection ID', + type: 'short-input', + placeholder: 'Enter your collection readable ID...', + required: true, + }, + { + id: 'query', + title: 'Search Query', + type: 'long-input', + placeholder: 'Enter your search query...', + required: true, + }, + { + id: 'limit', + title: 'Max Results', + type: 'dropdown', + options: [ + { label: '10', id: '10' }, + { label: '25', id: '25' }, + { label: '50', id: '50' }, + { label: '100', id: '100' }, + ], + value: () => '25', + }, + { + id: 'retrievalStrategy', + title: 'Retrieval Strategy', + type: 'dropdown', + options: [ + { label: 'Hybrid (Default)', id: 'hybrid' }, + { label: 'Neural', id: 'neural' }, + { label: 'Keyword', id: 'keyword' }, + ], + value: () => 'hybrid', + }, + { + id: 'expandQuery', + title: 'Expand Query', + type: 'switch', + description: 'Generate query variations to improve recall', + }, + { + id: 'rerank', + title: 'Rerank Results', + type: 'switch', + description: 'Reorder results for improved relevance using LLM', + }, + { + id: 'generateAnswer', + title: 'Generate Answer', + type: 'switch', + description: 'Generate a natural-language answer from results', + }, + { + id: 'apiKey', + title: 'API Key', + type: 'short-input', + placeholder: 'Enter your Airweave API key', + password: true, + required: true, + }, + ], + tools: { + access: ['airweave_search'], + }, + inputs: { + collectionId: { type: 'string', description: 'Airweave collection readable ID' }, + query: { type: 'string', description: 'Search query text' }, + apiKey: { type: 'string', description: 'Airweave API key' }, + limit: { type: 'number', description: 'Maximum number of results' }, + retrievalStrategy: { type: 'string', description: 'Retrieval strategy (hybrid/neural/keyword)' }, + expandQuery: { type: 'boolean', description: 'Generate query variations' }, + rerank: { type: 'boolean', description: 'Rerank results with LLM' }, + generateAnswer: { type: 'boolean', description: 'Generate AI answer' }, + }, + outputs: { + results: { type: 'json', description: 'Search results with content and metadata' }, + completion: { type: 'string', description: 'AI-generated answer (when enabled)' }, + }, +} diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index b04e3ee16f..7a488cff57 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -2,6 +2,7 @@ import { A2ABlock } from '@/blocks/blocks/a2a' import { AgentBlock } from '@/blocks/blocks/agent' import { AhrefsBlock } from '@/blocks/blocks/ahrefs' import { AirtableBlock } from '@/blocks/blocks/airtable' +import { AirweaveBlock } from '@/blocks/blocks/airweave' import { ApiBlock } from '@/blocks/blocks/api' import { ApiTriggerBlock } from '@/blocks/blocks/api_trigger' import { ApifyBlock } from '@/blocks/blocks/apify' @@ -160,6 +161,7 @@ export const registry: Record = { agent: AgentBlock, ahrefs: AhrefsBlock, airtable: AirtableBlock, + airweave: AirweaveBlock, api: ApiBlock, api_trigger: ApiTriggerBlock, apify: ApifyBlock, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 5645f1f9e1..bf796a32ea 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -1131,6 +1131,32 @@ export function AirtableIcon(props: SVGProps) { ) } +export function AirweaveIcon(props: SVGProps) { + return ( + + + + + + ) +} + export function GoogleDocsIcon(props: SVGProps) { return ( = { + id: 'airweave_search', + name: 'Airweave Search', + description: + 'Search your synced data collections using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Airweave API Key for authentication', + }, + collectionId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The readable ID of the collection to search', + }, + query: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The search query text', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-only', + description: 'Maximum number of results to return (default: 100)', + }, + retrievalStrategy: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Retrieval strategy: hybrid (default), neural, or keyword', + }, + expandQuery: { + type: 'boolean', + required: false, + visibility: 'user-only', + description: 'Generate query variations to improve recall', + }, + rerank: { + type: 'boolean', + required: false, + visibility: 'user-only', + description: 'Reorder results for improved relevance using LLM', + }, + generateAnswer: { + type: 'boolean', + required: false, + visibility: 'user-only', + description: 'Generate a natural-language answer to the query', + }, + }, + + request: { + url: (params) => `https://api.airweave.ai/collections/${params.collectionId}/search`, + method: 'POST', + headers: (params) => ({ + Authorization: `Bearer ${params.apiKey}`, + 'Content-Type': 'application/json', + }), + body: (params) => { + const body: Record = { + query: params.query, + } + + // Only include optional parameters if explicitly set + if (params.limit !== undefined) body.limit = Number(params.limit) + if (params.retrievalStrategy) body.retrieval_strategy = params.retrievalStrategy + if (params.expandQuery !== undefined) body.expand_query = params.expandQuery + if (params.rerank !== undefined) body.rerank = params.rerank + if (params.generateAnswer !== undefined) body.generate_answer = params.generateAnswer + + return body + }, + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + + // Handle error responses + if (!response.ok) { + return { + success: false, + output: { results: [] }, + error: data.detail ?? data.message ?? 'Search request failed', + } + } + + return { + success: true, + output: { + results: (data.results ?? []).map((result: any) => ({ + entity_id: result.entity_id ?? result.id ?? '', + source_name: result.source_name ?? '', + md_content: result.md_content ?? null, + score: result.score ?? 0, + metadata: result.metadata ?? null, + breadcrumbs: result.breadcrumbs ?? null, + url: result.url ?? null, + })), + ...(data.completion && { completion: data.completion }), + }, + } + }, + + outputs: { + results: { + type: 'array', + description: 'Search results with content, scores, and metadata from your synced data', + items: { + type: 'object', + properties: AIRWEAVE_SEARCH_RESULT_OUTPUT_PROPERTIES, + }, + }, + completion: { + type: 'string', + description: 'AI-generated answer to the query (when generateAnswer is enabled)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/airweave/types.ts b/apps/sim/tools/airweave/types.ts new file mode 100644 index 0000000000..123ceca7f1 --- /dev/null +++ b/apps/sim/tools/airweave/types.ts @@ -0,0 +1,84 @@ +import type { OutputProperty, ToolResponse } from '@/tools/types' + +/** + * Output definition for Airweave search result items. + * Based on Airweave Search API response format. + */ +export const AIRWEAVE_SEARCH_RESULT_OUTPUT_PROPERTIES = { + entity_id: { type: 'string', description: 'Unique identifier for the search result entity' }, + source_name: { type: 'string', description: 'Name of the data source (e.g., "GitHub", "Slack")' }, + md_content: { + type: 'string', + description: 'Markdown-formatted content of the result', + optional: true, + }, + score: { type: 'number', description: 'Relevance score from the search' }, + metadata: { + type: 'object', + description: 'Additional metadata associated with the result', + optional: true, + }, + breadcrumbs: { + type: 'array', + description: 'Navigation path to the result within its source', + optional: true, + items: { type: 'string', description: 'Breadcrumb segment' }, + }, + url: { type: 'string', description: 'URL to the original content', optional: true }, +} as const satisfies Record + +/** + * Complete search result output definition. + */ +export const AIRWEAVE_SEARCH_RESULT_OUTPUT: OutputProperty = { + type: 'object', + description: 'Search result item with content and metadata', + properties: AIRWEAVE_SEARCH_RESULT_OUTPUT_PROPERTIES, +} + +/** + * Parameters for Airweave search requests. + */ +export interface AirweaveSearchParams { + /** Airweave API Key for authentication */ + apiKey: string + /** The readable ID of the collection to search */ + collectionId: string + /** The search query text */ + query: string + /** Maximum number of results to return */ + limit?: number + /** Retrieval strategy: hybrid, neural, or keyword */ + retrievalStrategy?: 'hybrid' | 'neural' | 'keyword' + /** Generate query variations to improve recall */ + expandQuery?: boolean + /** Reorder results for improved relevance using LLM */ + rerank?: boolean + /** Generate a natural-language answer to the query */ + generateAnswer?: boolean +} + +/** + * Individual search result from Airweave. + */ +export interface AirweaveSearchResult { + entity_id: string + source_name: string + md_content?: string + score: number + metadata?: Record + breadcrumbs?: string[] + url?: string +} + +/** + * Response from Airweave search API. + */ +export interface AirweaveSearchResponse extends ToolResponse { + output: { + /** Array of search results */ + results: AirweaveSearchResult[] + /** AI-generated answer to the query (when generateAnswer is true) */ + completion?: string + } +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 2b251e0d2f..60ff1c61d6 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -24,6 +24,7 @@ import { airtableListRecordsTool, airtableUpdateRecordTool, } from '@/tools/airtable' +import { airweaveSearchTool } from '@/tools/airweave' import { apifyRunActorAsyncTool, apifyRunActorSyncTool } from '@/tools/apify' import { apolloAccountBulkCreateTool, @@ -1743,6 +1744,7 @@ export const tools: Record = { a2a_resubscribe: a2aResubscribeTool, a2a_send_message: a2aSendMessageTool, a2a_set_push_notification: a2aSetPushNotificationTool, + airweave_search: airweaveSearchTool, arxiv_search: arxivSearchTool, arxiv_get_paper: arxivGetPaperTool, arxiv_get_author_papers: arxivGetAuthorPapersTool, diff --git a/bun.lock b/bun.lock index 670d3c893f..9a032da3f7 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 1, "workspaces": { "": { "name": "simstudio", From 6e2219adf155885a2d30e8f73b6a81a66c0c6200 Mon Sep 17 00:00:00 2001 From: EwanTauran Date: Fri, 30 Jan 2026 13:52:02 +0100 Subject: [PATCH 2/3] feat(icons): add Airweave icon and update icon mapping and metadata --- apps/docs/components/icons.tsx | 26 ++++++++++ apps/docs/components/ui/icon-mapping.ts | 14 +++--- apps/docs/content/docs/en/tools/airweave.mdx | 52 ++++++++++++++++++++ apps/docs/content/docs/en/tools/meta.json | 3 +- 4 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 apps/docs/content/docs/en/tools/airweave.mdx diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index 5645f1f9e1..bf796a32ea 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -1131,6 +1131,32 @@ export function AirtableIcon(props: SVGProps) { ) } +export function AirweaveIcon(props: SVGProps) { + return ( + + + + + + ) +} + export function GoogleDocsIcon(props: SVGProps) { return ( > @@ -138,6 +139,7 @@ export const blockTypeToIconMap: Record = { a2a: A2AIcon, ahrefs: AhrefsIcon, airtable: AirtableIcon, + airweave: AirweaveIcon, apify: ApifyIcon, apollo: ApolloIcon, arxiv: ArxivIcon, diff --git a/apps/docs/content/docs/en/tools/airweave.mdx b/apps/docs/content/docs/en/tools/airweave.mdx new file mode 100644 index 0000000000..f5ce4994f2 --- /dev/null +++ b/apps/docs/content/docs/en/tools/airweave.mdx @@ -0,0 +1,52 @@ +--- +title: Airweave +description: Search your synced data collections +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +## Usage Instructions + +Search across your synced data sources using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results. + + + +## Tools + +### `airweave_search` + +Search your synced data collections using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Airweave API Key for authentication | +| `collectionId` | string | Yes | The readable ID of the collection to search | +| `query` | string | Yes | The search query text | +| `limit` | number | No | Maximum number of results to return \(default: 100\) | +| `retrievalStrategy` | string | No | Retrieval strategy: hybrid \(default\), neural, or keyword | +| `expandQuery` | boolean | No | Generate query variations to improve recall | +| `rerank` | boolean | No | Reorder results for improved relevance using LLM | +| `generateAnswer` | boolean | No | Generate a natural-language answer to the query | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `results` | array | Search results with content, scores, and metadata from your synced data | +| ↳ `entity_id` | string | Unique identifier for the search result entity | +| ↳ `source_name` | string | Name of the data source \(e.g., "GitHub", "Slack"\) | +| ↳ `md_content` | string | Markdown-formatted content of the result | +| ↳ `score` | number | Relevance score from the search | +| ↳ `metadata` | object | Additional metadata associated with the result | +| ↳ `breadcrumbs` | array | Navigation path to the result within its source | +| ↳ `url` | string | URL to the original content | +| `completion` | string | AI-generated answer to the query \(when generateAnswer is enabled\) | + + diff --git a/apps/docs/content/docs/en/tools/meta.json b/apps/docs/content/docs/en/tools/meta.json index 78ccaf2d0e..dcd9b29dbc 100644 --- a/apps/docs/content/docs/en/tools/meta.json +++ b/apps/docs/content/docs/en/tools/meta.json @@ -4,6 +4,7 @@ "a2a", "ahrefs", "airtable", + "airweave", "apify", "apollo", "arxiv", @@ -129,4 +130,4 @@ "zep", "zoom" ] -} +} \ No newline at end of file From 309a95650d61c240bb15454e5bc5c9c163071f3f Mon Sep 17 00:00:00 2001 From: EwanTauran Date: Mon, 2 Feb 2026 13:43:21 +0100 Subject: [PATCH 3/3] fix(search): update API key header from Authorization to X-API-Key for Airweave search tool --- apps/sim/tools/airweave/search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sim/tools/airweave/search.ts b/apps/sim/tools/airweave/search.ts index 7736247903..5e39780f4f 100644 --- a/apps/sim/tools/airweave/search.ts +++ b/apps/sim/tools/airweave/search.ts @@ -64,7 +64,7 @@ export const airweaveSearchTool: ToolConfig `https://api.airweave.ai/collections/${params.collectionId}/search`, method: 'POST', headers: (params) => ({ - Authorization: `Bearer ${params.apiKey}`, + 'X-API-Key': params.apiKey, 'Content-Type': 'application/json', }), body: (params) => {