Skip to content

fix(mothership): fix tool call scheduling#3635

Merged
Sg312 merged 2 commits intostagingfrom
fix/mothership-tool-scheduling
Mar 17, 2026
Merged

fix(mothership): fix tool call scheduling#3635
Sg312 merged 2 commits intostagingfrom
fix/mothership-tool-scheduling

Conversation

@Sg312
Copy link
Collaborator

@Sg312 Sg312 commented Mar 17, 2026

Summary

Fix mothership tool call scheduling

Type of Change

  • Bug fix

Testing

Manual

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)

@vercel
Copy link

vercel bot commented Mar 17, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 17, 2026 8:23pm

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 17, 2026

Greptile Summary

This PR fixes tool call scheduling in the mothership copilot orchestrator by routing clientExecutable tools through server-side execution (via fireToolExecution) when isToolAvailableOnSimSide confirms the tool can run on the TypeScript/Sim side, rather than always delegating them to the React UI client. The same fix is applied symmetrically to both sseHandlers.tool_call and subAgentHandlers.tool_call.

Key changes:

  • clientExecutable tools that are available on the sim side now execute server-side instead of waiting for the client
  • An else branch is added to fall back to the client-wait path for tools not available on the sim side

Issue found:

  • The newly added else (client-wait) branch is unreachable dead code in both handlers. A pre-existing guard (if (!isToolAvailableOnSimSide(toolName)) { return } at lines 299–301 and 556–558) exits early for all tools not available on the sim side — including clientExecutable ones — before the new clientExecutable block is reached. This means the comment "Otherwise wait for the client (React UI) to complete it" describes behavior that cannot actually occur in the current control flow. If tools exist that are clientExecutable but not on the sim side, they will be silently dropped rather than delegated to the client.

Confidence Score: 3/5

  • The PR fixes a real scheduling bug but introduces an unreachable else branch that may mask a separate silent-drop issue for clientExecutable tools not on the sim side.
  • The core fix (server-side execution for sim-available clientExecutable tools) is correct and addresses the stated bug. However, the else branch added in both handlers is dead code due to the pre-existing !isToolAvailableOnSimSide guard that fires before the clientExecutable check. If any tools are clientExecutable but not on the sim side, those tools are silently dropped rather than being delegated to the client as the new code comment implies. This limits confidence in the completeness of the fix.
  • apps/sim/lib/copilot/orchestrator/sse/handlers/handlers.ts — specifically the else branches in the clientExecutable block at lines 401–415 (sseHandlers) and 650–664 (subAgentHandlers).

Important Files Changed

Filename Overview
apps/sim/lib/copilot/orchestrator/sse/handlers/handlers.ts Adds server-side execution for clientExecutable tools when isToolAvailableOnSimSide returns true; however, the newly added else (client-wait) branch is unreachable dead code in both sseHandlers and subAgentHandlers due to the pre-existing early-return guard at lines 299–301 and 556–558.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[tool_call event received] --> B{internal?}
    B -- yes --> Z[return early]
    B -- no --> C{isToolAvailableOnSimSide?}
    C -- no --> Z2[return early\n⚠️ clientExecutable tools also exit here]
    C -- yes --> D[define fireToolExecution]
    D --> E{options.interactive === false?}
    E -- yes --> F{autoExecuteTools !== false?}
    F -- yes --> G[fireToolExecution]
    F -- no --> Z3[return]
    E -- no --> H{requiresConfirmation AND promptForToolApproval?}
    H -- yes --> I[waitForToolDecision]
    I --> J{decision status?}
    J -- accepted/success --> K{clientExecutable?}
    K -- yes --> L[waitForToolCompletion\nclient-side path]
    K -- no --> G
    J -- rejected/error --> M[mark rejected, return]
    J -- background --> N[mark skipped, return]
    J -- timeout --> O[mark timeout, return]
    H -- no --> P{clientExecutable?}
    P -- yes --> Q{isToolAvailableOnSimSide?\nalways true here ⚠️}
    Q -- yes --> G
    Q -- no --> R[client-wait path\nDEAD CODE - unreachable]
    P -- no --> S{autoExecuteTools !== false?}
    S -- yes --> G
    S -- no --> Z4[return]

    style R fill:#ff6b6b,color:#fff
    style Z2 fill:#ffd93d,color:#000
Loading

Last reviewed commit: 23e9668

@Sg312 Sg312 merged commit 35c42ba into staging Mar 17, 2026
11 checks passed
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