Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions apps/sim/blocks/blocks/airweave.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
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<AirweaveSearchResponse> = {
type: 'airweave',
name: 'Airweave',
description: 'Search connected data sources',
authMode: AuthMode.ApiKey,
longDescription:
'Search across all your connected data sources using Airweave. Supports 50+ integrations including Stripe, GitHub, Notion, Slack, HubSpot, Zendesk, and more. Get raw search results or AI-generated summaries.',
category: 'tools',
docsLink: 'https://docs.sim.ai/tools/airweave',
bgColor: '#8B5CF6',
icon: AirweaveIcon,
subBlocks: [
{
id: 'collectionId',
title: 'Collection ID',
type: 'short-input',
layout: 'full',
placeholder: 'my-collection-id',
required: true,
description: 'The readable ID of your Airweave collection',
},
{
id: 'query',
title: 'Search Query',
type: 'long-input',
layout: 'full',
placeholder: 'What information are you looking for?',
required: true,
description: 'Natural language search query to find relevant information',
},
{
id: 'responseType',
title: 'Response Type',
type: 'dropdown',
layout: 'full',
options: [
{ label: 'Raw Results', id: 'raw' },
{ label: 'AI Summary', id: 'completion' },
],
value: () => 'raw',
description: 'Get raw search results or an AI-generated answer',
},
{
id: 'limit',
title: 'Max Results',
type: 'short-input',
layout: 'half',
placeholder: '10',
description: 'Maximum number of results to return (1-100)',
},
{
id: 'recencyBias',
title: 'Recency Bias',
type: 'slider',
layout: 'half',
min: 0,
max: 1,
step: 0.1,
defaultValue: 0,
description: 'Prioritize recent results (0=relevance only, 1=recency only)',
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
layout: 'full',
placeholder: 'Enter your Airweave API key',
password: true,
required: true,
description: 'Get your API key from https://app.airweave.ai',
},
],
tools: {
access: ['airweave_search'],
},
inputs: {
collectionId: { type: 'string', description: 'Airweave collection ID' },
query: { type: 'string', description: 'Search query' },
limit: { type: 'number', description: 'Maximum number of results' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: offset input is declared but missing from subBlocks - users can't configure pagination offset in the UI

Suggested change
limit: { type: 'number', description: 'Maximum number of results' },
offset: { type: 'number', description: 'Pagination offset (default: 0)' },
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/blocks/blocks/airweave.ts
Line: 84:84

Comment:
**logic:** `offset` input is declared but missing from `subBlocks` - users can't configure pagination offset in the UI

```suggestion
    offset: { type: 'number', description: 'Pagination offset (default: 0)' },
```

How can I resolve this? If you propose a fix, please make it concise.

offset: { type: 'number', description: 'Pagination offset' },
responseType: { type: 'string', description: 'Response format (raw or completion)' },
recencyBias: { type: 'number', description: 'Recency weighting (0.0-1.0)' },
apiKey: { type: 'string', description: 'Airweave API key' },
},
outputs: {
status: { type: 'string', description: 'Search operation status' },
results: { type: 'json', description: 'Array of search results with metadata' },
completion: { type: 'string', description: 'AI-generated answer (when using completion mode)' },
},
}

2 changes: 2 additions & 0 deletions apps/sim/blocks/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { AgentBlock } from '@/blocks/blocks/agent'
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 { ArxivBlock } from '@/blocks/blocks/arxiv'
Expand Down Expand Up @@ -94,6 +95,7 @@ import type { BlockConfig } from '@/blocks/types'
export const registry: Record<string, BlockConfig> = {
agent: AgentBlock,
airtable: AirtableBlock,
airweave: AirweaveBlock,
api: ApiBlock,
arxiv: ArxivBlock,
browser_use: BrowserUseBlock,
Expand Down
35 changes: 35 additions & 0 deletions apps/sim/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,41 @@ export function AirplaneIcon(props: SVGProps<SVGSVGElement>) {
)
}

export function AirweaveIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
width='24'
height='24'
viewBox='0 0 24 24'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M12 2L2 7L12 12L22 7L12 2Z'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
/>
<path
d='M2 17L12 22L22 17'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
/>
<path
d='M2 12L12 17L22 12'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
/>
</svg>
)
}

export function WorkIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
Expand Down
6 changes: 5 additions & 1 deletion apps/sim/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"@opentelemetry/exporter-trace-otlp-http": "^0.200.0",
"@opentelemetry/resources": "^2.0.0",
"@opentelemetry/sdk-node": "^0.200.0",
"@opentelemetry/sdk-trace-base": "2.1.0",
"@opentelemetry/sdk-trace-node": "2.1.0",
Comment on lines +42 to +43
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Check if OpenTelemetry dependencies are needed for this PR - they appear unrelated to Airweave integration

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/package.json
Line: 42:43

Comment:
**style:** Check if OpenTelemetry dependencies are needed for this PR - they appear unrelated to Airweave integration

How can I resolve this? If you propose a fix, please make it concise.

"@opentelemetry/semantic-conventions": "^1.32.0",
"@radix-ui/react-alert-dialog": "^1.1.5",
"@radix-ui/react-avatar": "1.1.10",
Expand All @@ -65,6 +67,7 @@
"@types/three": "0.177.0",
"better-auth": "1.3.12",
"browser-image-compression": "^2.0.2",
"chalk": "5.6.2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Check if chalk is needed for this PR - not used in Airweave integration files

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/package.json
Line: 70:70

Comment:
**style:** Check if `chalk` is needed for this PR - not used in Airweave integration files

How can I resolve this? If you propose a fix, please make it concise.

"cheerio": "1.1.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand Down Expand Up @@ -116,7 +119,8 @@
"three": "0.177.0",
"uuid": "^11.1.0",
"xlsx": "0.18.5",
"zod": "^3.24.2"
"zod": "^3.24.2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Check if zustand is needed for this PR - not used in Airweave integration files

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/package.json
Line: 122:122

Comment:
**style:** Check if `zustand` is needed for this PR - not used in Airweave integration files

How can I resolve this? If you propose a fix, please make it concise.

"zustand": "5.0.8"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.6.3",
Expand Down
4 changes: 4 additions & 0 deletions apps/sim/tools/airweave/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { searchTool } from '@/tools/airweave/search'

export const airweaveSearchTool = searchTool

130 changes: 130 additions & 0 deletions apps/sim/tools/airweave/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import type { AirweaveSearchParams, AirweaveSearchResponse } from '@/tools/airweave/types'
import type { ToolConfig } from '@/tools/types'

export const searchTool: ToolConfig<AirweaveSearchParams, AirweaveSearchResponse> = {
id: 'airweave_search',
name: 'Airweave Search',
description:
'Search across all connected data sources in your Airweave collection. Supports 50+ integrations including Stripe, GitHub, Notion, Slack, HubSpot, Zendesk, and more. Returns relevant search results with metadata or AI-generated summaries.',
version: '1.0.0',

params: {
collectionId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The readable ID of the Airweave collection to search',
},
query: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The search query to find relevant information from connected data sources',
},
limit: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Maximum number of results to return (1-100, default: 10)',
},
offset: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Number of results to skip for pagination (default: 0)',
},
responseType: {
type: 'string',
required: false,
visibility: 'user-only',
description: "Response format: 'raw' for search results or 'completion' for AI-generated answer (default: 'raw')",
},
recencyBias: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Weight for recent results (0.0=no bias, 1.0=only recency, default: 0.0)',
},
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Airweave API Key (get from https://app.airweave.ai)',
},
},

request: {
url: (params) => `https://api.airweave.ai/v1/collections/${params.collectionId}/search`,
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, any> = {
query: params.query,
limit: params.limit || 10,
offset: params.offset || 0,
}

if (params.responseType) {
body.response_type = params.responseType
}

if (params.recencyBias !== undefined) {
body.recency_bias = params.recencyBias
}

return body
},
},

transformResponse: async (response: Response) => {
const data = await response.json()

return {
success: true,
output: {
status: data.status || 'success',
results: data.results || [],
completion: data.completion,
},
}
},

outputs: {
status: {
type: 'string',
description: 'Status of the search operation (success, no_results, no_relevant_results)',
},
results: {
type: 'array',
description: 'Search results with content and metadata from connected data sources',
items: {
type: 'object',
properties: {
payload: {
type: 'object',
properties: {
md_content: { type: 'string', description: 'Markdown content of the result' },
source_name: { type: 'string', description: 'Name of the data source' },
entity_id: { type: 'string', description: 'Unique identifier of the entity' },
created_at: { type: 'string', description: 'Creation timestamp' },
url: { type: 'string', description: 'URL of the source' },
},
},
score: {
type: 'number',
description: 'Relevance score for the search result',
},
},
},
},
completion: {
type: 'string',
optional: true,
description: 'AI-generated answer (when response_type is completion)',
},
},
}

39 changes: 39 additions & 0 deletions apps/sim/tools/airweave/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Common types for Airweave tools
import type { ToolResponse } from '@/tools/types'

// Base parameters for Airweave tools
export interface AirweaveBaseParams {
apiKey: string
collectionId: string
}

// Search tool types
export interface AirweaveSearchParams extends AirweaveBaseParams {
query: string
limit?: number
offset?: number
responseType?: 'raw' | 'completion'
recencyBias?: number
}

export interface AirweaveSearchResult {
payload: {
md_content?: string
source_name?: string
entity_id?: string
created_at?: string
updated_at?: string
url?: string
[key: string]: any
}
score: number
}

export interface AirweaveSearchResponse extends ToolResponse {
output: {
status: string
results?: AirweaveSearchResult[]
completion?: string
}
}

2 changes: 2 additions & 0 deletions apps/sim/tools/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
airtableListRecordsTool,
airtableUpdateRecordTool,
} from '@/tools/airtable'
import { airweaveSearchTool } from '@/tools/airweave'
import { arxivGetAuthorPapersTool, arxivGetPaperTool, arxivSearchTool } from '@/tools/arxiv'
import { browserUseRunTaskTool } from '@/tools/browser_use'
import { clayPopulateTool } from '@/tools/clay'
Expand Down Expand Up @@ -226,6 +227,7 @@ import {

// Registry of all available tools
export const tools: Record<string, ToolConfig> = {
airweave_search: airweaveSearchTool,
arxiv_search: arxivSearchTool,
arxiv_get_paper: arxivGetPaperTool,
arxiv_get_author_papers: arxivGetAuthorPapersTool,
Expand Down
Loading