Skip to content

refactor(tool-input): subblock-first rendering, component extraction, bug fixes#3207

Open
waleedlatif1 wants to merge 7 commits intostagingfrom
sim-609-tool-input-refactor
Open

refactor(tool-input): subblock-first rendering, component extraction, bug fixes#3207
waleedlatif1 wants to merge 7 commits intostagingfrom
sim-609-tool-input-refactor

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • Replace ~440-line SyncWrapper system with ToolSubBlockRenderer that delegates to <SubBlock> for full rendering parity
  • Restore "(optional)" indicator on tool params via labelSuffix prop on SubBlock
  • Fix folder selector missing for tools with canonicalParamId (e.g. Google Drive list files)
  • Fix canonical toggle (basic/advanced switch) not clickable in tool-input context
  • Extract ParameterWithLabel, ToolSubBlockRenderer, ToolCredentialSelector to components/tools/
  • Extract StoredTool to types.ts, selection helpers to utils.ts
  • Remove dead code and strengthen typing (no any)

Type of Change

  • Refactor
  • Bug fix

Testing

  • tsc --noEmit — zero errors
  • 42 tool-input tests pass
  • 31 params tests pass
  • Tested manually: registry tools, custom tools, MCP tools, canonical toggle, folder selector, optional indicator

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

waleedlatif1 and others added 2 commits February 11, 2026 22:46
…d dependsOn gating

Replace 17+ individual SyncWrapper components with a single centralized
ToolSubBlockRenderer that bridges the subblock store with StoredTool.params
via synthetic store keys. This reduces ~1000 lines of duplicated wrapper
code and ensures tool-input renders subblock components identically to
the standalone SubBlock path.

- Add ToolSubBlockRenderer with bidirectional store sync
- Add basic/advanced mode toggle (ArrowLeftRight) using collaborative functions
- Add dependsOn gating via useDependsOnGate (fields disable instead of hiding)
- Add paramVisibility field to SubBlockConfig for tool-input visibility control
- Pass canonicalModeOverrides through getSubBlocksForToolInput
- Show (optional) label for non-user-only fields (LLM can inject at runtime)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…canonical toggle, extract components

- Attach resolved paramVisibility to subblocks from getSubBlocksForToolInput
- Add labelSuffix prop to SubBlock for "(optional)" badge on user-or-llm params
- Fix folder selector missing for tools with canonicalParamId (e.g. Google Drive)
- Fix canonical toggle not clickable by letting SubBlock handle dependsOn internally
- Extract ParameterWithLabel, ToolSubBlockRenderer, ToolCredentialSelector to components/tools/
- Extract StoredTool interface to types.ts, selection helpers to utils.ts
- Remove dead code (mcpError, refreshTools, oldParamIds, initialParams)
- Strengthen typing: replace any with proper types on icon components and evaluateParameterCondition
@vercel
Copy link

vercel bot commented Feb 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Feb 12, 2026 7:42pm

Request Review

@waleedlatif1 waleedlatif1 changed the title refactor(tool-input): SubBlock-first rendering, component extraction, bug fixes refactor(tool-input): subblock-first rendering, component extraction, bug fixes Feb 12, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 12, 2026

Greptile Overview

Greptile Summary

This PR successfully replaces the ~440-line SyncWrapper system with a cleaner ToolSubBlockRenderer that delegates to <SubBlock> for full rendering parity. The refactor adds getSubBlocksForToolInput() to use subblock definitions as the primary source of UI metadata, inheriting features like wandConfig, rich conditions, dependsOn, and canonical mode switching.

Key improvements:

  • Restores "(optional)" indicator on tool params via labelSuffix prop
  • Fixes folder selector missing for tools with canonicalParamId (e.g., Google Drive list files)
  • Fixes canonical toggle (basic/advanced switch) not clickable in tool-input context by extracting it to ParameterWithLabel component
  • Extracts components to components/tools/ directory following proper component extraction patterns
  • Removes dead code and strengthens typing (eliminates any usage where possible)
  • All 42 tool-input tests and 31 params tests pass

Architecture:
The new ToolSubBlockRenderer creates synthetic store keys for bidirectional sync between StoredTool.params and the subblock store, with careful ref tracking to prevent echo loops. The getSubBlocksForToolInput() function filters subblocks by paramVisibility, evaluates conditions, and resolves canonical pairs to their active mode variant.

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk - well-tested refactor that maintains existing functionality while fixing bugs
  • Score of 4 reflects a large refactor (-1772/+1374 lines) with complex state synchronization logic, though all tests pass and the architecture is sound. The bidirectional sync in ToolSubBlockRenderer is well-designed with echo loop prevention, but the complexity warrants careful testing of edge cases in production.
  • Pay close attention to tool-input.tsx and params.ts during testing - these files contain the core logic for the new subblock-first rendering approach

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tools/sub-block-renderer.tsx New component that bridges tool params with SubBlock rendering via synthetic store keys. Clean bidirectional sync logic with proper echo loop prevention.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx Major refactor from ~2400 to ~1900 lines. Replaces SyncWrappers with ToolSubBlockRenderer for registry tools. Adds getSubBlocksForToolInput integration for subblock-first rendering.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx Added labelSuffix and dependencyContext props. Removes fieldDiffStatus (unused). Enables tool-input to provide sibling values for dependency resolution.
apps/sim/tools/params.ts Adds getSubBlocksForToolInput function (200 lines) to filter and resolve subblocks for tool-input rendering. Handles paramVisibility, conditions, and canonical mode resolution.

Sequence Diagram

sequenceDiagram
    participant TI as ToolInput
    participant TSR as ToolSubBlockRenderer
    participant SB as SubBlock
    participant Store as SubBlockStore
    participant Tool as StoredTool.params

    TI->>TI: getSubBlocksForToolInput(toolId)
    Note over TI: Filter subblocks by paramVisibility,<br/>conditions, canonical mode
    
    loop For each filtered subblock
        TI->>TSR: Render with effectiveParamId
        TSR->>TSR: Create synthetic store ID
        Note over TSR: syntheticId = subBlockId-tool-toolIndex-paramId
        
        TSR->>Store: useSubBlockValue(blockId, syntheticId)
        TSR->>Tool: Read tool.params[paramId]
        
        Note over TSR: Bidirectional sync with refs<br/>to prevent echo loops
        
        TSR->>TSR: Compute labelSuffix for (optional)
        TSR->>SB: Render with config + labelSuffix
        
        SB->>Store: User changes value
        Store->>TSR: storeValue updated
        TSR->>Tool: onParamChange(toolIndex, paramId, value)
        
        Tool->>TSR: tool.params[paramId] changed
        TSR->>Store: setStoreValue(newValue)
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

11 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

…evant in tool input, and removed unused param
@waleedlatif1
Copy link
Collaborator Author

@cursor review
@greptile

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

12 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

'messages-input',
'router-input',
'text',
])
Copy link

Choose a reason for hiding this comment

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

Workflow tool input mapping UI lost in subblock-first path

Medium Severity

When a workflow is added as an agent tool, the inputMapping parameter UI disappears. The WorkflowInputBlock has two subblocks: workflowId (type workflow-selector) and inputMapping (type input-mapping). Since input-mapping is in EXCLUDED_SUBBLOCK_TYPES, getSubBlocksForToolInput filters it out — but workflowId passes through, making useSubBlocks truthy. The subblock-first rendering path then only renders displaySubBlocks (just workflowId) and returns, so the fallback path containing the workflow-input-mapper case in renderParameterInput is never reached. Users lose the ability to pre-configure workflow input mappings in the tool-input context.

Additional Locations (1)

Fix in Cursor Fix in Web

The SubBlock-first rendering path was hard-returning after rendering
subblocks, so tool params without matching subblocks (like inputMapping
for workflow tools) were never rendered. Now renders subblocks first,
then any remaining displayParams not covered by subblocks via the legacy
ParameterWithLabel fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After redeploying a child workflow via the stale badge, the workflow
state cache was not invalidated, so WorkflowInputMapperInput kept
showing stale input fields until page refresh. Now invalidates
workflowKeys.state on deploy success.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tional) spacing

- Set workflowId param to user-only in workflow_executor tool config
  so "Select Workflow" no longer shows "(optional)" indicator
- Tighten (optional) label spacing with -ml-[3px] to counteract
  parent Label's gap-[6px], making it feel inline with the label text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant