Skip to content

Commit afe0289

Browse files
committed
fix(blocks): move type coercions from tools.config.tool to tools.config.params
Number() coercions in tools.config.tool ran at serialization time before variable resolution, destroying dynamic references like <block.result.count> by converting them to NaN/null. Moved all coercions to tools.config.params which runs at execution time after variables are resolved. Fixed in 15 blocks: exa, arxiv, sentry, incidentio, wikipedia, ahrefs, posthog, elasticsearch, dropbox, hunter, lemlist, spotify, youtube, grafana, parallel. Also added mode: 'advanced' to optional exa fields. Closes #3258
1 parent 3c470ab commit afe0289

File tree

17 files changed

+165
-181
lines changed

17 files changed

+165
-181
lines changed

.claude/commands/add-block.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ Enables AI-assisted field generation.
454454

455455
## Tools Configuration
456456

457+
**Important:** `tools.config.tool` runs during serialization before variable resolution. Put `Number()` and other type coercions in `tools.config.params` instead, which runs at execution time after variables are resolved.
458+
457459
**Preferred:** Use tool names directly as dropdown option IDs to avoid switch cases:
458460
```typescript
459461
// Dropdown options use tool IDs directly

CLAUDE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,16 @@ export const ServiceBlock: BlockConfig = {
238238
bgColor: '#hexcolor',
239239
icon: ServiceIcon,
240240
subBlocks: [ /* see SubBlock Properties */ ],
241-
tools: { access: ['service_action'], config: { tool: (p) => `service_${p.operation}` } },
241+
tools: { access: ['service_action'], config: { tool: (p) => `service_${p.operation}`, params: (p) => ({ /* type coercions here */ }) } },
242242
inputs: { /* ... */ },
243243
outputs: { /* ... */ },
244244
}
245245
```
246246

247247
Register in `blocks/registry.ts` (alphabetically).
248248

249+
**IMPORTANT:** `tools.config.tool` runs during serialization (before variable resolution). Never do `Number()` or other type coercions there — dynamic references like `<Block.output>` will be destroyed. Use `tools.config.params` for type coercions (it runs during execution, after variables are resolved).
250+
249251
**SubBlock Properties:**
250252
```typescript
251253
{

apps/sim/blocks/blocks/ahrefs.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -485,14 +485,6 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
485485
],
486486
config: {
487487
tool: (params) => {
488-
// Convert numeric string inputs to numbers
489-
if (params.limit) {
490-
params.limit = Number(params.limit)
491-
}
492-
if (params.offset) {
493-
params.offset = Number(params.offset)
494-
}
495-
496488
switch (params.operation) {
497489
case 'ahrefs_domain_rating':
498490
return 'ahrefs_domain_rating'
@@ -514,6 +506,12 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
514506
return 'ahrefs_domain_rating'
515507
}
516508
},
509+
params: (params) => {
510+
const result: Record<string, unknown> = {}
511+
if (params.limit) result.limit = Number(params.limit)
512+
if (params.offset) result.offset = Number(params.offset)
513+
return result
514+
},
517515
},
518516
},
519517
inputs: {

apps/sim/blocks/blocks/arxiv.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,6 @@ export const ArxivBlock: BlockConfig<ArxivResponse> = {
110110
access: ['arxiv_search', 'arxiv_get_paper', 'arxiv_get_author_papers'],
111111
config: {
112112
tool: (params) => {
113-
// Convert maxResults to a number for operations that use it
114-
if (params.maxResults) {
115-
params.maxResults = Number(params.maxResults)
116-
}
117-
118113
switch (params.operation) {
119114
case 'arxiv_search':
120115
return 'arxiv_search'
@@ -126,6 +121,11 @@ export const ArxivBlock: BlockConfig<ArxivResponse> = {
126121
return 'arxiv_search'
127122
}
128123
},
124+
params: (params) => {
125+
const result: Record<string, unknown> = {}
126+
if (params.maxResults) result.maxResults = Number(params.maxResults)
127+
return result
128+
},
129129
},
130130
},
131131
inputs: {

apps/sim/blocks/blocks/dropbox.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,14 +309,6 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
309309
],
310310
config: {
311311
tool: (params) => {
312-
// Convert numeric params
313-
if (params.limit) {
314-
params.limit = Number(params.limit)
315-
}
316-
if (params.maxResults) {
317-
params.maxResults = Number(params.maxResults)
318-
}
319-
320312
// Normalize file input for upload operation - use canonical 'file' param
321313
const normalizedFile = normalizeFileInput(params.file, { single: true })
322314
if (normalizedFile) {
@@ -348,6 +340,12 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
348340
return 'dropbox_upload'
349341
}
350342
},
343+
params: (params) => {
344+
const result: Record<string, unknown> = {}
345+
if (params.limit) result.limit = Number(params.limit)
346+
if (params.maxResults) result.maxResults = Number(params.maxResults)
347+
return result
348+
},
351349
},
352350
},
353351
inputs: {

apps/sim/blocks/blocks/elasticsearch.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -457,24 +457,20 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`,
457457
],
458458
config: {
459459
tool: (params) => {
460-
// Convert numeric strings to numbers
461-
if (params.size) {
462-
params.size = Number(params.size)
463-
}
464-
if (params.from) {
465-
params.from = Number(params.from)
466-
}
467-
if (params.retryOnConflict) {
468-
params.retryOnConflict = Number(params.retryOnConflict)
469-
}
470-
// Append 's' to timeout for Elasticsearch time format
471-
if (params.timeout && !params.timeout.endsWith('s')) {
472-
params.timeout = `${params.timeout}s`
473-
}
474-
475460
// Return the operation as the tool ID
476461
return params.operation || 'elasticsearch_search'
477462
},
463+
params: (params) => {
464+
const result: Record<string, unknown> = {}
465+
if (params.size) result.size = Number(params.size)
466+
if (params.from) result.from = Number(params.from)
467+
if (params.retryOnConflict) result.retryOnConflict = Number(params.retryOnConflict)
468+
// Append 's' to timeout for Elasticsearch time format
469+
if (params.timeout && typeof params.timeout === 'string' && !params.timeout.endsWith('s')) {
470+
result.timeout = `${params.timeout}s`
471+
}
472+
return result
473+
},
478474
},
479475
},
480476

apps/sim/blocks/blocks/exa.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
4949
title: 'Use Autoprompt',
5050
type: 'switch',
5151
condition: { field: 'operation', value: 'exa_search' },
52+
mode: 'advanced',
5253
},
5354
{
5455
id: 'type',
@@ -62,20 +63,23 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
6263
],
6364
value: () => 'auto',
6465
condition: { field: 'operation', value: 'exa_search' },
66+
mode: 'advanced',
6567
},
6668
{
6769
id: 'includeDomains',
6870
title: 'Include Domains',
6971
type: 'long-input',
7072
placeholder: 'example.com, another.com (comma-separated)',
7173
condition: { field: 'operation', value: 'exa_search' },
74+
mode: 'advanced',
7275
},
7376
{
7477
id: 'excludeDomains',
7578
title: 'Exclude Domains',
7679
type: 'long-input',
7780
placeholder: 'exclude.com, another.com (comma-separated)',
7881
condition: { field: 'operation', value: 'exa_search' },
82+
mode: 'advanced',
7983
},
8084
{
8185
id: 'category',
@@ -95,6 +99,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
9599
],
96100
value: () => '',
97101
condition: { field: 'operation', value: 'exa_search' },
102+
mode: 'advanced',
98103
},
99104
{
100105
id: 'text',
@@ -107,12 +112,14 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
107112
title: 'Include Highlights',
108113
type: 'switch',
109114
condition: { field: 'operation', value: 'exa_search' },
115+
mode: 'advanced',
110116
},
111117
{
112118
id: 'summary',
113119
title: 'Include Summary',
114120
type: 'switch',
115121
condition: { field: 'operation', value: 'exa_search' },
122+
mode: 'advanced',
116123
},
117124
{
118125
id: 'livecrawl',
@@ -125,6 +132,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
125132
],
126133
value: () => 'never',
127134
condition: { field: 'operation', value: 'exa_search' },
135+
mode: 'advanced',
128136
},
129137
// Get Contents operation inputs
130138
{
@@ -147,26 +155,30 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
147155
type: 'long-input',
148156
placeholder: 'Enter a query to guide the summary generation...',
149157
condition: { field: 'operation', value: 'exa_get_contents' },
158+
mode: 'advanced',
150159
},
151160
{
152161
id: 'subpages',
153162
title: 'Number of Subpages',
154163
type: 'short-input',
155164
placeholder: '5',
156165
condition: { field: 'operation', value: 'exa_get_contents' },
166+
mode: 'advanced',
157167
},
158168
{
159169
id: 'subpageTarget',
160170
title: 'Subpage Target Keywords',
161171
type: 'long-input',
162172
placeholder: 'docs, tutorial, about (comma-separated)',
163173
condition: { field: 'operation', value: 'exa_get_contents' },
174+
mode: 'advanced',
164175
},
165176
{
166177
id: 'highlights',
167178
title: 'Include Highlights',
168179
type: 'switch',
169180
condition: { field: 'operation', value: 'exa_get_contents' },
181+
mode: 'advanced',
170182
},
171183
// Find Similar Links operation inputs
172184
{
@@ -196,19 +208,22 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
196208
type: 'long-input',
197209
placeholder: 'example.com, another.com (comma-separated)',
198210
condition: { field: 'operation', value: 'exa_find_similar_links' },
211+
mode: 'advanced',
199212
},
200213
{
201214
id: 'excludeDomains',
202215
title: 'Exclude Domains',
203216
type: 'long-input',
204217
placeholder: 'exclude.com, another.com (comma-separated)',
205218
condition: { field: 'operation', value: 'exa_find_similar_links' },
219+
mode: 'advanced',
206220
},
207221
{
208222
id: 'excludeSourceDomain',
209223
title: 'Exclude Source Domain',
210224
type: 'switch',
211225
condition: { field: 'operation', value: 'exa_find_similar_links' },
226+
mode: 'advanced',
212227
},
213228
{
214229
id: 'category',
@@ -228,18 +243,21 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
228243
],
229244
value: () => '',
230245
condition: { field: 'operation', value: 'exa_find_similar_links' },
246+
mode: 'advanced',
231247
},
232248
{
233249
id: 'highlights',
234250
title: 'Include Highlights',
235251
type: 'switch',
236252
condition: { field: 'operation', value: 'exa_find_similar_links' },
253+
mode: 'advanced',
237254
},
238255
{
239256
id: 'summary',
240257
title: 'Include Summary',
241258
type: 'switch',
242259
condition: { field: 'operation', value: 'exa_find_similar_links' },
260+
mode: 'advanced',
243261
},
244262
{
245263
id: 'livecrawl',
@@ -252,6 +270,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
252270
],
253271
value: () => 'never',
254272
condition: { field: 'operation', value: 'exa_find_similar_links' },
273+
mode: 'advanced',
255274
},
256275
// Answer operation inputs
257276
{
@@ -267,6 +286,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
267286
title: 'Include Text',
268287
type: 'switch',
269288
condition: { field: 'operation', value: 'exa_answer' },
289+
mode: 'advanced',
270290
},
271291
// Research operation inputs
272292
{
@@ -309,16 +329,6 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
309329
],
310330
config: {
311331
tool: (params) => {
312-
// Convert numResults to a number for operations that use it
313-
if (params.numResults) {
314-
params.numResults = Number(params.numResults)
315-
}
316-
317-
// Convert subpages to a number if provided
318-
if (params.subpages) {
319-
params.subpages = Number(params.subpages)
320-
}
321-
322332
switch (params.operation) {
323333
case 'exa_search':
324334
return 'exa_search'
@@ -334,6 +344,16 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
334344
return 'exa_search'
335345
}
336346
},
347+
params: (params) => {
348+
const result: Record<string, unknown> = {}
349+
if (params.numResults) {
350+
result.numResults = Number(params.numResults)
351+
}
352+
if (params.subpages) {
353+
result.subpages = Number(params.subpages)
354+
}
355+
return result
356+
},
337357
},
338358
},
339359
inputs: {

apps/sim/blocks/blocks/grafana.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -606,26 +606,6 @@ Return ONLY the folder title - no explanations, no quotes, no extra text.`,
606606
],
607607
config: {
608608
tool: (params) => {
609-
// Convert numeric string fields to numbers
610-
if (params.panelId) {
611-
params.panelId = Number(params.panelId)
612-
}
613-
if (params.annotationId) {
614-
params.annotationId = Number(params.annotationId)
615-
}
616-
if (params.time) {
617-
params.time = Number(params.time)
618-
}
619-
if (params.timeEnd) {
620-
params.timeEnd = Number(params.timeEnd)
621-
}
622-
if (params.from) {
623-
params.from = Number(params.from)
624-
}
625-
if (params.to) {
626-
params.to = Number(params.to)
627-
}
628-
629609
// Map subblock fields to tool parameter names
630610
if (params.alertTitle) {
631611
params.title = params.alertTitle
@@ -645,6 +625,16 @@ Return ONLY the folder title - no explanations, no quotes, no extra text.`,
645625

646626
return params.operation
647627
},
628+
params: (params) => {
629+
const result: Record<string, unknown> = {}
630+
if (params.panelId) result.panelId = Number(params.panelId)
631+
if (params.annotationId) result.annotationId = Number(params.annotationId)
632+
if (params.time) result.time = Number(params.time)
633+
if (params.timeEnd) result.timeEnd = Number(params.timeEnd)
634+
if (params.from) result.from = Number(params.from)
635+
if (params.to) result.to = Number(params.to)
636+
return result
637+
},
648638
},
649639
},
650640
inputs: {

apps/sim/blocks/blocks/hunter.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,6 @@ Return ONLY the search query text - no explanations.`,
204204
],
205205
config: {
206206
tool: (params) => {
207-
// Convert numeric parameters
208-
if (params.limit) {
209-
params.limit = Number(params.limit)
210-
}
211-
212207
switch (params.operation) {
213208
case 'hunter_discover':
214209
return 'hunter_discover'
@@ -226,6 +221,11 @@ Return ONLY the search query text - no explanations.`,
226221
return 'hunter_domain_search'
227222
}
228223
},
224+
params: (params) => {
225+
const result: Record<string, unknown> = {}
226+
if (params.limit) result.limit = Number(params.limit)
227+
return result
228+
},
229229
},
230230
},
231231
inputs: {

0 commit comments

Comments
 (0)