Skip to content

fix(agent): scope nested tool canonical-mode overrides by instance, not type#5534

Open
waleedlatif1 wants to merge 115 commits into
stagingfrom
worktree-fix-table-canonical-mode-shared
Open

fix(agent): scope nested tool canonical-mode overrides by instance, not type#5534
waleedlatif1 wants to merge 115 commits into
stagingfrom
worktree-fix-table-canonical-mode-shared

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Fixes a bug where two tool entries of the same type in an Agent block's tool-input array (e.g. two Table tools) shared one canonical-mode override, so switching basic/advanced mode on a field in one instance silently switched it for every other instance of the same tool type
  • The override key was ${toolType}:${canonicalId} (shared across every instance of a type); it's now ${toolIndex}:${canonicalId}, scoped to the tool's position in its own tool-input array
  • Threaded the tool's array index through every consumer of this key: the editor (tool-input.tsx read + write), execution (agent-handler.ts / providers/utils.ts transformBlockTool), the search index (search-replace/indexer.ts), and fork/promote remapping (dependent-reconfigs.ts)
  • This was also a correctness bug at execution time, not just the editor UI — the wrong basic/advanced value could be resolved for the second tool instance when running the workflow

Type of Change

  • Bug fix

Testing

  • Added a dedicated scopeCanonicalModesForTool test suite in visibility.test.ts covering the instance-scoping behavior directly
  • Added a regression test in providers/utils.test.ts with two Table tool instances resolving independent canonical modes
  • Added a regression test in dependent-reconfigs.test.ts covering two same-type nested tools in the fork/promote remap path
  • Updated existing tests that referenced the old ${toolType}:${canonicalId} key format to the new ${toolIndex}:${canonicalId} format
  • Full repo test suite (2864 tests, 175 files) passes; bun run type-check, bun run lint, and bun run check:api-validation all pass

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 30 commits April 3, 2026 23:30
…ership workflow edits via sockets, ui improvements
…ration, signup method feature flags, SSO improvements
* feat(posthog): Add tracking on mothership abort (#4023)

Co-authored-by: Theodore Li <theo@sim.ai>

* fix(login): fix captcha headers for manual login  (#4025)

* fix(signup): fix turnstile key loading

* fix(login): fix captcha header passing

* Catch user already exists, remove login form captcha
…nts, secrets performance, polling refactors, drag resources in mothership
…endar triggers, docs updates, integrations/models pages improvements
…mat, logs performance improvements

fix(csp): add missing analytics domains, remove unsafe-eval, fix workspace CSP gap (#4179)
fix(landing): return 404 for invalid dynamic route slugs (#4182)
improvement(seo): optimize sitemaps, robots.txt, and core web vitals across sim and docs (#4170)
fix(gemini): support structured output with tools on Gemini 3 models (#4184)
feat(brightdata): add Bright Data integration with 8 tools (#4183)
fix(mothership): fix superagent credentials (#4185)
fix(logs): close sidebar when selected log disappears from filtered list; cleanup (#4186)
v0.6.46: mothership streaming fixes, brightdata integration
TheodoreSpeaks and others added 25 commits June 10, 2026 20:01
…x, db migrations from ci, docs updates, read replicas

v0.7.3: jira oauth scope fix, read-replica client, table wire data fix, db migrations from ci, docs updates, read replicas
…uting, trigger.dev, temporal, latex, quartr, brex, convex integrations
…richment providers, deepseek models, db performance
…nce, file sharing, scheduled tasks granularity
…t harness, sakana fugu provider

v0.7.13: pii redaction, react query frontend refactor, pi coding agent harness, sakana fugu provider
…ix, settings overhaul, thrive learning integration
…extension, workspace forking, slack trigger extension, new README
…ot type

Two tool entries of the same type inside an Agent block's tool-input array
(e.g. two Table tools) shared a single canonical-mode override keyed by
${toolType}:${canonicalId}, so switching basic/advanced mode on one field
silently switched it on every other instance of the same tool type -
including at execution time, where the wrong basic/advanced value could be
resolved for the second tool.

Rescope the override key to the tool's position in its tool-input array
(${toolIndex}:${canonicalId}) instead of its type, and thread that index
through every consumer: the editor (read + write), execution
(agent-handler/providers), search-index, and fork/promote remapping.
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 9, 2026 6:37am

Request Review

@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches agent tool formatting and stored canonicalModes shape; wrong index would mis-resolve credentials/tables at runtime, and existing workflows with legacy ${toolType}: keys may lose explicit mode overrides until re-saved.

Overview
Fixes a bug where multiple nested tools of the same type on one Agent block (e.g. two Table tools) shared a single basic/advanced canonical-mode override, so toggling one instance affected every other instance of that type—and at run time the wrong basic vs advanced field value could be resolved.

Canonical override keys change from `${toolType}:${canonicalId}` to `${toolIndex}:${canonicalId}`. scopeCanonicalModesForTool now scopes by tool index; the editor writes that key on toggle and reads scoped overrides per tool row.

The tool’s original array index is carried through agent execution (toolIndexByRef so MCP/usage filtering doesn’t renumber tools), transformBlockTool / canonical param resolution, workflow search indexing, and fork/promote dependent reconfigs. Tests cover scoping, transform, and fork remap for two same-type tools.

Note: Workflows that still store overrides under the old `gmail:credential`-style keys won’t match until modes are set again under the new format (no migration in this PR).

Reviewed by Cursor Bugbot for commit 9f47896. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR changes how Agent nested tool canonical-mode overrides are scoped. The main changes are:

  • Uses the tool's array index instead of its type in canonical-mode keys.
  • Threads the tool index through editor, execution, search, and fork remap paths.
  • Adds tests for same-type nested tools resolving independent basic/advanced modes.

Confidence Score: 4/5

The changed key format can misapply nested tool modes after reorder/delete and can ignore saved overrides from existing workflows.

  • Array indexes are not stable persisted tool identities.
  • Existing type-prefixed override keys are no longer recognized by the new scoping helper.
  • Execution now consumes the same scoped keys, so the wrong basic/advanced value can affect workflow runs.

tool-input.tsx and visibility.ts

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx Reads and writes nested tool canonical-mode overrides using the rendered tool array index.
apps/sim/lib/workflows/subblocks/visibility.ts Updates the nested tool canonical-mode scoping helper to parse index-prefixed override keys.
apps/sim/executor/handlers/agent/agent-handler.ts Preserves original tool indexes through Agent tool filtering before formatting tools.
apps/sim/providers/utils.ts Scopes canonical overrides before resolving tool resource params and generated provider tool IDs.
apps/sim/lib/workflows/search-replace/indexer.ts Passes nested tool indexes into search-index parameter config resolution.
apps/sim/lib/workspaces/fork/mapping/dependent-reconfigs.ts Uses nested tool indexes when resolving canonical modes for fork dependent reconfiguration.

Reviews (1): Last reviewed commit: "fix(agent): scope nested tool canonical-..." | Re-trigger Greptile

@@ -2072,7 +2072,7 @@ export const ToolInput = memo(function ToolInput({
const nextMode = canonicalMode === 'advanced' ? 'basic' : 'advanced'
collaborativeSetBlockCanonicalMode(
blockId,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Index Slot Owns Tool Mode

When a user reorders or removes tools, the tool-input array changes but data.canonicalModes is not rewritten. A saved key like 0:tableId then applies to whichever tool later occupies index 0, so the editor and execution can use another tool instance's basic/advanced resource after a normal drag or delete.

if (!overrides || toolIndex === undefined) return undefined
const prefix = `${toolIndex}:`
let scoped: CanonicalModeOverrides | undefined
for (const [key, value] of Object.entries(overrides)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Old Override Keys Disappear

Existing workflows can still have nested tool overrides stored as ${toolType}:${canonicalId}, but this parser now only matches ${toolIndex}: prefixes. Those saved explicit modes become invisible on load, so a workflow that was set to an advanced value can fall back to the value heuristic and run with a stale basic field instead.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9f47896. Configure here.

if (!blockConfig?.subBlocks) continue
const toolCanonical = buildCanonicalIndex(blockConfig.subBlocks)
const scopedOverrides = scopeCanonicalModesForTool(canonicalModeOverrides, tool.type)
const scopedOverrides = scopeCanonicalModesForTool(canonicalModeOverrides, toolIndex)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale modes after tool removal

Medium Severity

Canonical-mode overrides are now keyed by each tool’s array index (${toolIndex}:${canonicalId}), but removing a tool only updates the tools list and leaves block.data.canonicalModes unchanged. After a delete, surviving tools keep their old indices in storage while the UI and executor resolve modes by the new positions, so basic/advanced toggles and runtime param resolution can attach the wrong mode to the wrong instance.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9f47896. Configure here.

if (!overrides || !toolType) return undefined
const prefix = `${toolType}:`
if (!overrides || toolIndex === undefined) return undefined
const prefix = `${toolIndex}:`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Legacy override keys ignored

Medium Severity

Persisted agent blocks may still store nested tool canonical modes under the old ${toolType}:${canonicalId} keys from before this change. scopeCanonicalModesForTool only recognizes the new ${toolIndex}: prefix, so those overrides are ignored until the user toggles again, and execution falls back to the value heuristic—which can pick a different basic vs advanced field than the saved preference when both sides are populated.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9f47896. Configure here.

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.

4 participants