Skip to content

Commit d5bd97d

Browse files
authored
feat(tinybird): added tinybird block (#2781)
1 parent bd7009e commit d5bd97d

File tree

12 files changed

+644
-0
lines changed

12 files changed

+644
-0
lines changed

apps/docs/components/icons.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,19 @@ export function TelegramIcon(props: SVGProps<SVGSVGElement>) {
18971897
)
18981898
}
18991899

1900+
export function TinybirdIcon(props: SVGProps<SVGSVGElement>) {
1901+
return (
1902+
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'>
1903+
<rect x='0' y='0' width='24' height='24' fill='#2EF598' rx='6' />
1904+
<g transform='translate(2, 2) scale(0.833)'>
1905+
<path d='M25 2.64 17.195.5 14.45 6.635z' fill='#1E7F63' />
1906+
<path d='M17.535 17.77 10.39 15.215 6.195 25.5z' fill='#1E7F63' />
1907+
<path d='M0 11.495 17.535 17.77 20.41 4.36z' fill='#1F2437' />
1908+
</g>
1909+
</svg>
1910+
)
1911+
}
1912+
19001913
export function ClayIcon(props: SVGProps<SVGSVGElement>) {
19011914
return (
19021915
<svg {...props} xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 400 400'>

apps/docs/components/ui/icon-mapping.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ import {
107107
SupabaseIcon,
108108
TavilyIcon,
109109
TelegramIcon,
110+
TinybirdIcon,
110111
TranslateIcon,
111112
TrelloIcon,
112113
TTSIcon,
@@ -230,6 +231,8 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
230231
supabase: SupabaseIcon,
231232
tavily: TavilyIcon,
232233
telegram: TelegramIcon,
234+
thinking: BrainIcon,
235+
tinybird: TinybirdIcon,
233236
translate: TranslateIcon,
234237
trello: TrelloIcon,
235238
tts: TTSIcon,

apps/docs/content/docs/en/tools/meta.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@
103103
"supabase",
104104
"tavily",
105105
"telegram",
106+
"thinking",
107+
"tinybird",
106108
"translate",
107109
"trello",
108110
"tts",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
title: Tinybird
3+
description: Send events and query data with Tinybird
4+
---
5+
6+
import { BlockInfoCard } from "@/components/ui/block-info-card"
7+
8+
<BlockInfoCard
9+
type="tinybird"
10+
color="#2EF598"
11+
/>
12+
13+
## Usage Instructions
14+
15+
Interact with Tinybird using the Events API to stream JSON or NDJSON events, or use the Query API to execute SQL queries against Pipes and Data Sources.
16+
17+
18+
19+
## Tools
20+
21+
### `tinybird_events`
22+
23+
Send events to a Tinybird Data Source using the Events API. Supports JSON and NDJSON formats with optional gzip compression.
24+
25+
#### Input
26+
27+
| Parameter | Type | Required | Description |
28+
| --------- | ---- | -------- | ----------- |
29+
| `base_url` | string | Yes | Tinybird API base URL \(e.g., https://api.tinybird.co or https://api.us-east.tinybird.co\) |
30+
| `datasource` | string | Yes | Name of the Tinybird Data Source to send events to |
31+
| `data` | string | Yes | Data to send as NDJSON \(newline-delimited JSON\) or JSON string. Each event should be a valid JSON object. |
32+
| `wait` | boolean | No | Wait for database acknowledgment before responding. Enables safer retries but introduces latency. Defaults to false. |
33+
| `format` | string | No | Format of the events data: "ndjson" \(default\) or "json" |
34+
| `compression` | string | No | Compression format: "none" \(default\) or "gzip" |
35+
| `token` | string | Yes | Tinybird API Token with DATASOURCE:APPEND or DATASOURCE:CREATE scope |
36+
37+
#### Output
38+
39+
| Parameter | Type | Description |
40+
| --------- | ---- | ----------- |
41+
| `successful_rows` | number | Number of rows successfully ingested |
42+
| `quarantined_rows` | number | Number of rows quarantined \(failed validation\) |
43+
44+
### `tinybird_query`
45+
46+
Execute SQL queries against Tinybird Pipes and Data Sources using the Query API.
47+
48+
#### Input
49+
50+
| Parameter | Type | Required | Description |
51+
| --------- | ---- | -------- | ----------- |
52+
| `base_url` | string | Yes | Tinybird API base URL \(e.g., https://api.tinybird.co\) |
53+
| `query` | string | Yes | SQL query to execute. Specify your desired output format \(e.g., FORMAT JSON, FORMAT CSV, FORMAT TSV\). JSON format provides structured data, while other formats return raw text. |
54+
| `pipeline` | string | No | Optional pipe name. When provided, enables SELECT * FROM _ syntax |
55+
| `token` | string | Yes | Tinybird API Token with PIPE:READ scope |
56+
57+
#### Output
58+
59+
| Parameter | Type | Description |
60+
| --------- | ---- | ----------- |
61+
| `data` | json | Query result data. For FORMAT JSON: array of objects. For other formats \(CSV, TSV, etc.\): raw text string. |
62+
| `rows` | number | Number of rows returned \(only available with FORMAT JSON\) |
63+
| `statistics` | json | Query execution statistics - elapsed time, rows read, bytes read \(only available with FORMAT JSON\) |
64+
65+
66+
67+
## Notes
68+
69+
- Category: `tools`
70+
- Type: `tinybird`

apps/sim/blocks/blocks/tinybird.ts

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import { TinybirdIcon } from '@/components/icons'
2+
import type { BlockConfig } from '@/blocks/types'
3+
import { AuthMode } from '@/blocks/types'
4+
import type { TinybirdResponse } from '@/tools/tinybird/types'
5+
6+
export const TinybirdBlock: BlockConfig<TinybirdResponse> = {
7+
type: 'tinybird',
8+
name: 'Tinybird',
9+
description: 'Send events and query data with Tinybird',
10+
authMode: AuthMode.ApiKey,
11+
longDescription:
12+
'Interact with Tinybird using the Events API to stream JSON or NDJSON events, or use the Query API to execute SQL queries against Pipes and Data Sources.',
13+
docsLink: 'https://www.tinybird.co/docs/api-reference',
14+
category: 'tools',
15+
bgColor: '#2EF598',
16+
icon: TinybirdIcon,
17+
subBlocks: [
18+
{
19+
id: 'operation',
20+
title: 'Operation',
21+
type: 'dropdown',
22+
options: [
23+
{ label: 'Send Events', id: 'tinybird_events' },
24+
{ label: 'Query', id: 'tinybird_query' },
25+
],
26+
value: () => 'tinybird_events',
27+
},
28+
{
29+
id: 'base_url',
30+
title: 'Base URL',
31+
type: 'short-input',
32+
placeholder: 'https://api.tinybird.co',
33+
required: true,
34+
},
35+
{
36+
id: 'token',
37+
title: 'API Token',
38+
type: 'short-input',
39+
placeholder: 'Enter your Tinybird API token',
40+
password: true,
41+
required: true,
42+
},
43+
// Send Events operation inputs
44+
{
45+
id: 'datasource',
46+
title: 'Data Source',
47+
type: 'short-input',
48+
placeholder: 'my_events_datasource',
49+
condition: { field: 'operation', value: 'tinybird_events' },
50+
required: true,
51+
},
52+
{
53+
id: 'data',
54+
title: 'Data',
55+
type: 'code',
56+
placeholder:
57+
'{"event": "click", "timestamp": "2024-01-01T12:00:00Z"}\n{"event": "view", "timestamp": "2024-01-01T12:00:01Z"}',
58+
condition: { field: 'operation', value: 'tinybird_events' },
59+
required: true,
60+
},
61+
{
62+
id: 'format',
63+
title: 'Format',
64+
type: 'dropdown',
65+
options: [
66+
{ label: 'NDJSON (Newline-delimited JSON)', id: 'ndjson' },
67+
{ label: 'JSON', id: 'json' },
68+
],
69+
value: () => 'ndjson',
70+
condition: { field: 'operation', value: 'tinybird_events' },
71+
},
72+
{
73+
id: 'compression',
74+
title: 'Compression',
75+
type: 'dropdown',
76+
options: [
77+
{ label: 'None', id: 'none' },
78+
{ label: 'Gzip', id: 'gzip' },
79+
],
80+
value: () => 'none',
81+
mode: 'advanced',
82+
condition: { field: 'operation', value: 'tinybird_events' },
83+
},
84+
{
85+
id: 'wait',
86+
title: 'Wait for Acknowledgment',
87+
type: 'switch',
88+
value: () => 'false',
89+
mode: 'advanced',
90+
condition: { field: 'operation', value: 'tinybird_events' },
91+
},
92+
// Query operation inputs
93+
{
94+
id: 'query',
95+
title: 'SQL Query',
96+
type: 'code',
97+
placeholder: 'SELECT * FROM my_pipe FORMAT JSON\nOR\nSELECT * FROM my_pipe FORMAT CSV',
98+
condition: { field: 'operation', value: 'tinybird_query' },
99+
required: true,
100+
},
101+
{
102+
id: 'pipeline',
103+
title: 'Pipeline Name',
104+
type: 'short-input',
105+
placeholder: 'my_pipe (optional)',
106+
condition: { field: 'operation', value: 'tinybird_query' },
107+
},
108+
],
109+
tools: {
110+
access: ['tinybird_events', 'tinybird_query'],
111+
config: {
112+
tool: (params) => params.operation || 'tinybird_events',
113+
params: (params) => {
114+
const operation = params.operation || 'tinybird_events'
115+
const result: Record<string, any> = {
116+
base_url: params.base_url,
117+
token: params.token,
118+
}
119+
120+
if (operation === 'tinybird_events') {
121+
// Send Events operation
122+
if (!params.datasource) {
123+
throw new Error('Data Source is required for Send Events operation')
124+
}
125+
if (!params.data) {
126+
throw new Error('Data is required for Send Events operation')
127+
}
128+
129+
result.datasource = params.datasource
130+
result.data = params.data
131+
result.format = params.format || 'ndjson'
132+
result.compression = params.compression || 'none'
133+
134+
// Convert wait from string to boolean
135+
// Convert wait from string to boolean
136+
if (params.wait !== undefined) {
137+
const waitValue =
138+
typeof params.wait === 'string' ? params.wait.toLowerCase() : params.wait
139+
result.wait = waitValue === 'true' || waitValue === true
140+
}
141+
} else if (operation === 'tinybird_query') {
142+
// Query operation
143+
if (!params.query) {
144+
throw new Error('SQL Query is required for Query operation')
145+
}
146+
147+
result.query = params.query
148+
if (params.pipeline) {
149+
result.pipeline = params.pipeline
150+
}
151+
}
152+
153+
return result
154+
},
155+
},
156+
},
157+
inputs: {
158+
operation: { type: 'string', description: 'Operation to perform' },
159+
base_url: { type: 'string', description: 'Tinybird API base URL' },
160+
// Send Events inputs
161+
datasource: {
162+
type: 'string',
163+
description: 'Name of the Tinybird Data Source',
164+
},
165+
data: {
166+
type: 'string',
167+
description: 'Data to send as JSON or NDJSON string',
168+
},
169+
wait: { type: 'boolean', description: 'Wait for database acknowledgment' },
170+
format: {
171+
type: 'string',
172+
description: 'Format of the events (ndjson or json)',
173+
},
174+
compression: {
175+
type: 'string',
176+
description: 'Compression format (none or gzip)',
177+
},
178+
// Query inputs
179+
query: { type: 'string', description: 'SQL query to execute' },
180+
pipeline: { type: 'string', description: 'Optional pipeline name' },
181+
// Common
182+
token: { type: 'string', description: 'Tinybird API Token' },
183+
},
184+
outputs: {
185+
// Send Events outputs
186+
successful_rows: {
187+
type: 'number',
188+
description: 'Number of rows successfully ingested',
189+
},
190+
quarantined_rows: {
191+
type: 'number',
192+
description: 'Number of rows quarantined (failed validation)',
193+
},
194+
// Query outputs
195+
data: {
196+
type: 'json',
197+
description:
198+
'Query result data. FORMAT JSON: array of objects. Other formats (CSV, TSV, etc.): raw text string.',
199+
},
200+
rows: { type: 'number', description: 'Number of rows returned (only with FORMAT JSON)' },
201+
statistics: {
202+
type: 'json',
203+
description:
204+
'Query execution statistics - elapsed time, rows read, bytes read (only with FORMAT JSON)',
205+
},
206+
},
207+
}

apps/sim/blocks/registry.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ import { SupabaseBlock } from '@/blocks/blocks/supabase'
121121
import { TavilyBlock } from '@/blocks/blocks/tavily'
122122
import { TelegramBlock } from '@/blocks/blocks/telegram'
123123
import { ThinkingBlock } from '@/blocks/blocks/thinking'
124+
import { TinybirdBlock } from '@/blocks/blocks/tinybird'
124125
import { TranslateBlock } from '@/blocks/blocks/translate'
125126
import { TrelloBlock } from '@/blocks/blocks/trello'
126127
import { TtsBlock } from '@/blocks/blocks/tts'
@@ -281,6 +282,7 @@ export const registry: Record<string, BlockConfig> = {
281282
tavily: TavilyBlock,
282283
telegram: TelegramBlock,
283284
thinking: ThinkingBlock,
285+
tinybird: TinybirdBlock,
284286
translate: TranslateBlock,
285287
trello: TrelloBlock,
286288
twilio_sms: TwilioSMSBlock,

apps/sim/components/icons.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,19 @@ export function TelegramIcon(props: SVGProps<SVGSVGElement>) {
18971897
)
18981898
}
18991899

1900+
export function TinybirdIcon(props: SVGProps<SVGSVGElement>) {
1901+
return (
1902+
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'>
1903+
<rect x='0' y='0' width='24' height='24' fill='#2EF598' rx='6' />
1904+
<g transform='translate(2, 2) scale(0.833)'>
1905+
<path d='M25 2.64 17.195.5 14.45 6.635z' fill='#1E7F63' />
1906+
<path d='M17.535 17.77 10.39 15.215 6.195 25.5z' fill='#1E7F63' />
1907+
<path d='M0 11.495 17.535 17.77 20.41 4.36z' fill='#1F2437' />
1908+
</g>
1909+
</svg>
1910+
)
1911+
}
1912+
19001913
export function ClayIcon(props: SVGProps<SVGSVGElement>) {
19011914
return (
19021915
<svg {...props} xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 400 400'>

apps/sim/tools/registry.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,7 @@ import {
13811381
telegramSendVideoTool,
13821382
} from '@/tools/telegram'
13831383
import { thinkingTool } from '@/tools/thinking'
1384+
import { tinybirdEventsTool, tinybirdQueryTool } from '@/tools/tinybird'
13841385
import {
13851386
trelloAddCommentTool,
13861387
trelloCreateCardTool,
@@ -2237,6 +2238,8 @@ export const tools: Record<string, ToolConfig> = {
22372238
apollo_email_accounts: apolloEmailAccountsTool,
22382239
mistral_parser: mistralParserTool,
22392240
thinking_tool: thinkingTool,
2241+
tinybird_events: tinybirdEventsTool,
2242+
tinybird_query: tinybirdQueryTool,
22402243
stagehand_extract: stagehandExtractTool,
22412244
stagehand_agent: stagehandAgentTool,
22422245
mem0_add_memories: mem0AddMemoriesTool,

0 commit comments

Comments
 (0)