fix(blocks): move type coercions from tools.config.tool to tools.config.params (#3264)

* 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

* fix(blocks): address PR review — move remaining param mutations from tool() to params()

- Moved field mappings from tool() to params() in grafana, posthog,
  lemlist, spotify, dropbox (same dynamic reference bug)
- Fixed parallel.ts excerpts/full_content boolean logic
- Fixed parallel.ts search_queries empty case (must set undefined)
- Fixed elasticsearch.ts timeout not included when already ends with 's'
- Restored dropbox.ts tool() switch for proper default fallback

* fix(blocks): restore field renames to tool() for serialization-time validation

Field renames (e.g. personalApiKey→apiKey) must be in tool() because
validateRequiredFieldsBeforeExecution calls selectToolId()→tool() then
checks renamed field names on params. Only type coercions (Number(),
boolean) stay in params() to avoid destroying dynamic variable references.
This commit is contained in:
Waleed
2026-02-19 21:54:16 -08:00
committed by GitHub
parent 9ca5254c2b
commit 9920882dc5
17 changed files with 174 additions and 238 deletions

View File

@@ -454,6 +454,8 @@ Enables AI-assisted field generation.
## Tools Configuration
**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.
**Preferred:** Use tool names directly as dropdown option IDs to avoid switch cases:
```typescript
// Dropdown options use tool IDs directly

View File

@@ -238,7 +238,7 @@ export const ServiceBlock: BlockConfig = {
bgColor: '#hexcolor',
icon: ServiceIcon,
subBlocks: [ /* see SubBlock Properties */ ],
tools: { access: ['service_action'], config: { tool: (p) => `service_${p.operation}` } },
tools: { access: ['service_action'], config: { tool: (p) => `service_${p.operation}`, params: (p) => ({ /* type coercions here */ }) } },
inputs: { /* ... */ },
outputs: { /* ... */ },
}
@@ -246,6 +246,8 @@ export const ServiceBlock: BlockConfig = {
Register in `blocks/registry.ts` (alphabetically).
**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).
**SubBlock Properties:**
```typescript
{

View File

@@ -485,14 +485,6 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
],
config: {
tool: (params) => {
// Convert numeric string inputs to numbers
if (params.limit) {
params.limit = Number(params.limit)
}
if (params.offset) {
params.offset = Number(params.offset)
}
switch (params.operation) {
case 'ahrefs_domain_rating':
return 'ahrefs_domain_rating'
@@ -514,6 +506,12 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
return 'ahrefs_domain_rating'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.limit) result.limit = Number(params.limit)
if (params.offset) result.offset = Number(params.offset)
return result
},
},
},
inputs: {

View File

@@ -110,11 +110,6 @@ export const ArxivBlock: BlockConfig<ArxivResponse> = {
access: ['arxiv_search', 'arxiv_get_paper', 'arxiv_get_author_papers'],
config: {
tool: (params) => {
// Convert maxResults to a number for operations that use it
if (params.maxResults) {
params.maxResults = Number(params.maxResults)
}
switch (params.operation) {
case 'arxiv_search':
return 'arxiv_search'
@@ -126,6 +121,11 @@ export const ArxivBlock: BlockConfig<ArxivResponse> = {
return 'arxiv_search'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.maxResults) result.maxResults = Number(params.maxResults)
return result
},
},
},
inputs: {

View File

@@ -309,20 +309,6 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
],
config: {
tool: (params) => {
// Convert numeric params
if (params.limit) {
params.limit = Number(params.limit)
}
if (params.maxResults) {
params.maxResults = Number(params.maxResults)
}
// Normalize file input for upload operation - use canonical 'file' param
const normalizedFile = normalizeFileInput(params.file, { single: true })
if (normalizedFile) {
params.file = normalizedFile
}
switch (params.operation) {
case 'dropbox_upload':
return 'dropbox_upload'
@@ -348,6 +334,16 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
return 'dropbox_upload'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.limit) result.limit = Number(params.limit)
if (params.maxResults) result.maxResults = Number(params.maxResults)
const normalizedFile = normalizeFileInput(params.file, { single: true })
if (normalizedFile) {
result.file = normalizedFile
}
return result
},
},
},
inputs: {

View File

@@ -457,24 +457,19 @@ Return ONLY valid JSON - no explanations, no markdown code blocks.`,
],
config: {
tool: (params) => {
// Convert numeric strings to numbers
if (params.size) {
params.size = Number(params.size)
}
if (params.from) {
params.from = Number(params.from)
}
if (params.retryOnConflict) {
params.retryOnConflict = Number(params.retryOnConflict)
}
// Append 's' to timeout for Elasticsearch time format
if (params.timeout && !params.timeout.endsWith('s')) {
params.timeout = `${params.timeout}s`
}
// Return the operation as the tool ID
return params.operation || 'elasticsearch_search'
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.size) result.size = Number(params.size)
if (params.from) result.from = Number(params.from)
if (params.retryOnConflict) result.retryOnConflict = Number(params.retryOnConflict)
if (params.timeout && typeof params.timeout === 'string') {
result.timeout = params.timeout.endsWith('s') ? params.timeout : `${params.timeout}s`
}
return result
},
},
},

View File

@@ -49,6 +49,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
title: 'Use Autoprompt',
type: 'switch',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
{
id: 'type',
@@ -62,6 +63,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
],
value: () => 'auto',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
{
id: 'includeDomains',
@@ -69,6 +71,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
type: 'long-input',
placeholder: 'example.com, another.com (comma-separated)',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
{
id: 'excludeDomains',
@@ -76,6 +79,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
type: 'long-input',
placeholder: 'exclude.com, another.com (comma-separated)',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
{
id: 'category',
@@ -95,6 +99,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
],
value: () => '',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
{
id: 'text',
@@ -107,12 +112,14 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
title: 'Include Highlights',
type: 'switch',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
{
id: 'summary',
title: 'Include Summary',
type: 'switch',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
{
id: 'livecrawl',
@@ -125,6 +132,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
],
value: () => 'never',
condition: { field: 'operation', value: 'exa_search' },
mode: 'advanced',
},
// Get Contents operation inputs
{
@@ -147,6 +155,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
type: 'long-input',
placeholder: 'Enter a query to guide the summary generation...',
condition: { field: 'operation', value: 'exa_get_contents' },
mode: 'advanced',
},
{
id: 'subpages',
@@ -154,6 +163,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
type: 'short-input',
placeholder: '5',
condition: { field: 'operation', value: 'exa_get_contents' },
mode: 'advanced',
},
{
id: 'subpageTarget',
@@ -161,12 +171,14 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
type: 'long-input',
placeholder: 'docs, tutorial, about (comma-separated)',
condition: { field: 'operation', value: 'exa_get_contents' },
mode: 'advanced',
},
{
id: 'highlights',
title: 'Include Highlights',
type: 'switch',
condition: { field: 'operation', value: 'exa_get_contents' },
mode: 'advanced',
},
// Find Similar Links operation inputs
{
@@ -196,6 +208,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
type: 'long-input',
placeholder: 'example.com, another.com (comma-separated)',
condition: { field: 'operation', value: 'exa_find_similar_links' },
mode: 'advanced',
},
{
id: 'excludeDomains',
@@ -203,12 +216,14 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
type: 'long-input',
placeholder: 'exclude.com, another.com (comma-separated)',
condition: { field: 'operation', value: 'exa_find_similar_links' },
mode: 'advanced',
},
{
id: 'excludeSourceDomain',
title: 'Exclude Source Domain',
type: 'switch',
condition: { field: 'operation', value: 'exa_find_similar_links' },
mode: 'advanced',
},
{
id: 'category',
@@ -228,18 +243,21 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
],
value: () => '',
condition: { field: 'operation', value: 'exa_find_similar_links' },
mode: 'advanced',
},
{
id: 'highlights',
title: 'Include Highlights',
type: 'switch',
condition: { field: 'operation', value: 'exa_find_similar_links' },
mode: 'advanced',
},
{
id: 'summary',
title: 'Include Summary',
type: 'switch',
condition: { field: 'operation', value: 'exa_find_similar_links' },
mode: 'advanced',
},
{
id: 'livecrawl',
@@ -252,6 +270,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
],
value: () => 'never',
condition: { field: 'operation', value: 'exa_find_similar_links' },
mode: 'advanced',
},
// Answer operation inputs
{
@@ -267,6 +286,7 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
title: 'Include Text',
type: 'switch',
condition: { field: 'operation', value: 'exa_answer' },
mode: 'advanced',
},
// Research operation inputs
{
@@ -309,16 +329,6 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
],
config: {
tool: (params) => {
// Convert numResults to a number for operations that use it
if (params.numResults) {
params.numResults = Number(params.numResults)
}
// Convert subpages to a number if provided
if (params.subpages) {
params.subpages = Number(params.subpages)
}
switch (params.operation) {
case 'exa_search':
return 'exa_search'
@@ -334,6 +344,16 @@ export const ExaBlock: BlockConfig<ExaResponse> = {
return 'exa_search'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.numResults) {
result.numResults = Number(params.numResults)
}
if (params.subpages) {
result.subpages = Number(params.subpages)
}
return result
},
},
},
inputs: {

View File

@@ -606,45 +606,23 @@ Return ONLY the folder title - no explanations, no quotes, no extra text.`,
],
config: {
tool: (params) => {
// Convert numeric string fields to numbers
if (params.panelId) {
params.panelId = Number(params.panelId)
}
if (params.annotationId) {
params.annotationId = Number(params.annotationId)
}
if (params.time) {
params.time = Number(params.time)
}
if (params.timeEnd) {
params.timeEnd = Number(params.timeEnd)
}
if (params.from) {
params.from = Number(params.from)
}
if (params.to) {
params.to = Number(params.to)
}
// Map subblock fields to tool parameter names
if (params.alertTitle) {
params.title = params.alertTitle
}
if (params.folderTitle) {
params.title = params.folderTitle
}
if (params.folderUidNew) {
params.uid = params.folderUidNew
}
if (params.annotationTags) {
params.tags = params.annotationTags
}
if (params.annotationDashboardUid) {
params.dashboardUid = params.annotationDashboardUid
}
if (params.alertTitle) params.title = params.alertTitle
if (params.folderTitle) params.title = params.folderTitle
if (params.folderUidNew) params.uid = params.folderUidNew
if (params.annotationTags) params.tags = params.annotationTags
if (params.annotationDashboardUid) params.dashboardUid = params.annotationDashboardUid
return params.operation
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.panelId) result.panelId = Number(params.panelId)
if (params.annotationId) result.annotationId = Number(params.annotationId)
if (params.time) result.time = Number(params.time)
if (params.timeEnd) result.timeEnd = Number(params.timeEnd)
if (params.from) result.from = Number(params.from)
if (params.to) result.to = Number(params.to)
return result
},
},
},
inputs: {

View File

@@ -204,11 +204,6 @@ Return ONLY the search query text - no explanations.`,
],
config: {
tool: (params) => {
// Convert numeric parameters
if (params.limit) {
params.limit = Number(params.limit)
}
switch (params.operation) {
case 'hunter_discover':
return 'hunter_discover'
@@ -226,6 +221,11 @@ Return ONLY the search query text - no explanations.`,
return 'hunter_domain_search'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.limit) result.limit = Number(params.limit)
return result
},
},
},
inputs: {

View File

@@ -826,16 +826,6 @@ Return ONLY the JSON array - no explanations or markdown formatting.`,
],
config: {
tool: (params) => {
// Convert page_size to a number if provided
if (params.page_size) {
params.page_size = Number(params.page_size)
}
// Convert notify_incident_channel from string to boolean
if (params.notify_incident_channel !== undefined) {
params.notify_incident_channel = params.notify_incident_channel === 'true'
}
switch (params.operation) {
case 'incidentio_incidents_list':
return 'incidentio_incidents_list'
@@ -929,6 +919,14 @@ Return ONLY the JSON array - no explanations or markdown formatting.`,
return 'incidentio_incidents_list'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.page_size) result.page_size = Number(params.page_size)
if (params.notify_incident_channel !== undefined) {
result.notify_incident_channel = params.notify_incident_channel === 'true'
}
return result
},
},
},
inputs: {

View File

@@ -169,17 +169,7 @@ export const LemlistBlock: BlockConfig<LemlistResponse> = {
access: ['lemlist_get_activities', 'lemlist_get_lead', 'lemlist_send_email'],
config: {
tool: (params) => {
if (params.limit) {
params.limit = Number(params.limit)
}
if (params.offset) {
params.offset = Number(params.offset)
}
// Map filterLeadId to leadId for get_activities tool
if (params.filterLeadId) {
params.leadId = params.filterLeadId
}
if (params.filterLeadId) params.leadId = params.filterLeadId
switch (params.operation) {
case 'get_activities':
return 'lemlist_get_activities'
@@ -191,6 +181,12 @@ export const LemlistBlock: BlockConfig<LemlistResponse> = {
return 'lemlist_get_activities'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.limit) result.limit = Number(params.limit)
if (params.offset) result.offset = Number(params.offset)
return result
},
},
},
inputs: {

View File

@@ -149,66 +149,48 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
access: ['parallel_search', 'parallel_extract', 'parallel_deep_research'],
config: {
tool: (params) => {
if (params.extract_objective) params.objective = params.extract_objective
if (params.research_input) params.input = params.research_input
switch (params.operation) {
case 'search':
// Convert search_queries from comma-separated string to array (if provided)
if (params.search_queries && typeof params.search_queries === 'string') {
const queries = params.search_queries
.split(',')
.map((query: string) => query.trim())
.filter((query: string) => query.length > 0)
// Only set if we have actual queries
if (queries.length > 0) {
params.search_queries = queries
} else {
params.search_queries = undefined
}
}
// Convert numeric parameters
if (params.max_results) {
params.max_results = Number(params.max_results)
}
if (params.max_chars_per_result) {
params.max_chars_per_result = Number(params.max_chars_per_result)
}
return 'parallel_search'
case 'extract':
// Map extract_objective to objective for the tool
params.objective = params.extract_objective
// Convert boolean strings to actual booleans with defaults
if (params.excerpts === 'true' || params.excerpts === true) {
params.excerpts = true
} else if (params.excerpts === 'false' || params.excerpts === false) {
params.excerpts = false
} else {
// Default to true if not provided
params.excerpts = true
}
if (params.full_content === 'true' || params.full_content === true) {
params.full_content = true
} else if (params.full_content === 'false' || params.full_content === false) {
params.full_content = false
} else {
// Default to false if not provided
params.full_content = false
}
return 'parallel_extract'
case 'deep_research':
// Map research_input to input for the tool
params.input = params.research_input
return 'parallel_deep_research'
default:
return 'parallel_search'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
const operation = params.operation
if (operation === 'search') {
if (params.search_queries && typeof params.search_queries === 'string') {
const queries = params.search_queries
.split(',')
.map((query: string) => query.trim())
.filter((query: string) => query.length > 0)
if (queries.length > 0) {
result.search_queries = queries
} else {
result.search_queries = undefined
}
}
if (params.max_results) result.max_results = Number(params.max_results)
if (params.max_chars_per_result) {
result.max_chars_per_result = Number(params.max_chars_per_result)
}
}
if (operation === 'extract') {
result.excerpts = !(params.excerpts === 'false' || params.excerpts === false)
result.full_content = params.full_content === 'true' || params.full_content === true
}
return result
},
},
},
inputs: {

View File

@@ -1185,22 +1185,15 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
],
config: {
tool: (params) => {
// Convert numeric parameters
if (params.limit) params.limit = Number(params.limit)
if (params.offset) params.offset = Number(params.offset)
if (params.rolloutPercentage) params.rolloutPercentage = Number(params.rolloutPercentage)
// Map projectIdParam to projectId for get_project operation
// Field renames in tool() are safe (they copy values, not coerce types)
// and are needed for serialization-time validation of required fields
if (params.operation === 'posthog_get_project' && params.projectIdParam) {
params.projectId = params.projectIdParam
}
// Map personalApiKey to apiKey for all private endpoint tools
if (params.personalApiKey) {
params.apiKey = params.personalApiKey
}
// Map featureFlagId to flagId for feature flag operations
const flagOps = [
'posthog_get_feature_flag',
'posthog_update_feature_flag',
@@ -1210,7 +1203,6 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
params.flagId = params.featureFlagId
}
// Map surveyType to type for survey operations
if (
(params.operation === 'posthog_create_survey' ||
params.operation === 'posthog_update_survey') &&
@@ -1219,37 +1211,30 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
params.type = params.surveyType
}
// Map isStatic for cohorts
if (params.operation === 'posthog_create_cohort' && params.isStatic !== undefined) {
params.is_static = params.isStatic
}
// Map dateMarker to date_marker for annotations
if (params.operation === 'posthog_create_annotation' && params.dateMarker) {
params.date_marker = params.dateMarker
}
// Map propertyType to property_type
if (params.operation === 'posthog_update_property_definition' && params.propertyType) {
params.property_type = params.propertyType
}
// Map insightQuery to query for insights
if (params.operation === 'posthog_create_insight' && params.insightQuery) {
params.query = params.insightQuery
}
// Map insightTags to tags for insights
if (params.operation === 'posthog_create_insight' && params.insightTags) {
params.tags = params.insightTags
}
// Map distinctIdFilter to distinctId for list_persons
if (params.operation === 'posthog_list_persons' && params.distinctIdFilter) {
params.distinctId = params.distinctIdFilter
}
// Map experiment date fields
if (params.operation === 'posthog_create_experiment') {
if (params.experimentStartDate) {
params.startDate = params.experimentStartDate
@@ -1259,7 +1244,6 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
}
}
// Map survey date fields
if (
params.operation === 'posthog_create_survey' ||
params.operation === 'posthog_update_survey'
@@ -1272,13 +1256,17 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
}
}
// Convert responsesLimit to number
if (params.responsesLimit) {
params.responsesLimit = Number(params.responsesLimit)
}
return params.operation as string
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.limit) result.limit = Number(params.limit)
if (params.offset) result.offset = Number(params.offset)
if (params.rolloutPercentage) result.rolloutPercentage = Number(params.rolloutPercentage)
if (params.responsesLimit) result.responsesLimit = Number(params.responsesLimit)
return result
},
},
},

View File

@@ -602,11 +602,6 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
],
config: {
tool: (params) => {
// Convert numeric fields
if (params.limit) {
params.limit = Number(params.limit)
}
// Return the appropriate tool based on operation
switch (params.operation) {
case 'sentry_issues_list':
@@ -637,6 +632,11 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
return 'sentry_issues_list'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.limit) result.limit = Number(params.limit)
return result
},
},
},
inputs: {

View File

@@ -755,43 +755,24 @@ export const SpotifyBlock: BlockConfig<ToolResponse> = {
],
config: {
tool: (params) => {
// Convert numeric parameters
if (params.limit) {
params.limit = Number(params.limit)
}
if (params.volume_percent) {
params.volume_percent = Number(params.volume_percent)
}
if (params.range_start) {
params.range_start = Number(params.range_start)
}
if (params.insert_before) {
params.insert_before = Number(params.insert_before)
}
if (params.range_length) {
params.range_length = Number(params.range_length)
}
if (params.position_ms) {
params.position_ms = Number(params.position_ms)
}
// Map followType to type for check_following
if (params.followType) {
params.type = params.followType
}
// Map newName to name for update_playlist
if (params.newName) {
params.name = params.newName
}
// Map playUris to uris for play
if (params.playUris) {
params.uris = params.playUris
}
// Normalize file input for cover image
if (params.coverImage !== undefined) {
params.coverImage = normalizeFileInput(params.coverImage, { single: true })
}
if (params.followType) params.type = params.followType
if (params.newName) params.name = params.newName
if (params.playUris) params.uris = params.playUris
return params.operation || 'spotify_search'
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.limit) result.limit = Number(params.limit)
if (params.volume_percent) result.volume_percent = Number(params.volume_percent)
if (params.range_start) result.range_start = Number(params.range_start)
if (params.insert_before) result.insert_before = Number(params.insert_before)
if (params.range_length) result.range_length = Number(params.range_length)
if (params.position_ms) result.position_ms = Number(params.position_ms)
if (params.coverImage !== undefined) {
result.coverImage = normalizeFileInput(params.coverImage, { single: true })
}
return result
},
},
},
inputs: {

View File

@@ -64,11 +64,6 @@ export const WikipediaBlock: BlockConfig<WikipediaResponse> = {
access: ['wikipedia_summary', 'wikipedia_search', 'wikipedia_content', 'wikipedia_random'],
config: {
tool: (params) => {
// Convert searchLimit to a number for search operation
if (params.searchLimit) {
params.searchLimit = Number(params.searchLimit)
}
switch (params.operation) {
case 'wikipedia_summary':
return 'wikipedia_summary'
@@ -82,6 +77,11 @@ export const WikipediaBlock: BlockConfig<WikipediaResponse> = {
return 'wikipedia_summary'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.searchLimit) result.searchLimit = Number(params.searchLimit)
return result
},
},
},
inputs: {

View File

@@ -442,11 +442,6 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
],
config: {
tool: (params) => {
// Convert numeric parameters
if (params.maxResults) {
params.maxResults = Number(params.maxResults)
}
switch (params.operation) {
case 'youtube_search':
return 'youtube_search'
@@ -470,6 +465,11 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
return 'youtube_search'
}
},
params: (params) => {
const result: Record<string, unknown> = {}
if (params.maxResults) result.maxResults = Number(params.maxResults)
return result
},
},
},
inputs: {