fix(agent): scope nested tool canonical-mode overrides by instance, not type#5534
fix(agent): scope nested tool canonical-mode overrides by instance, not type#5534waleedlatif1 wants to merge 115 commits into
Conversation
…ership workflow edits via sockets, ui improvements
…ng improvements, posthog, secrets mutations
…ration, signup method feature flags, SSO improvements
…nts, secrets performance, polling refactors, drag resources in mothership
…y invalidation, HITL docs
…endar triggers, docs updates, integrations/models pages improvements
…ions, jira forms endpoints
…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
…m integration, atlassian triggers
…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
…rovements, styling consolidation
…, db perf improvements
…nges, code hygiene
…lassian assets and google calendar tools
…d, security fixes
…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
…ming improvements
…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.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Canonical override keys change from The tool’s original array index is carried through agent execution ( Note: Workflows that still store overrides under the old Reviewed by Cursor Bugbot for commit 9f47896. Configure here. |
Greptile SummaryThis PR changes how Agent nested tool canonical-mode overrides are scoped. The main changes are:
Confidence Score: 4/5The changed key format can misapply nested tool modes after reorder/delete and can ignore saved overrides from existing workflows.
tool-input.tsx and visibility.ts Important Files Changed
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, | |||
There was a problem hiding this comment.
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)) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ 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) |
There was a problem hiding this comment.
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)
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}:` |
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit 9f47896. Configure here.


Summary
${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 arrayType of Change
Testing
scopeCanonicalModesForTooltest suite invisibility.test.tscovering the instance-scoping behavior directlyproviders/utils.test.tswith two Table tool instances resolving independent canonical modesdependent-reconfigs.test.tscovering two same-type nested tools in the fork/promote remap path${toolType}:${canonicalId}key format to the new${toolIndex}:${canonicalId}formatbun run type-check,bun run lint, andbun run check:api-validationall passChecklist