Skip to content

fix(mothership): tool durability#3731

Merged
Sg312 merged 7 commits intostagingfrom
fix/mothership-nonexistent-tools
Mar 24, 2026
Merged

fix(mothership): tool durability#3731
Sg312 merged 7 commits intostagingfrom
fix/mothership-nonexistent-tools

Conversation

@Sg312
Copy link
Collaborator

@Sg312 Sg312 commented Mar 24, 2026

Summary

Fix tool durability

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 24, 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 24, 2026 3:28am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR adds a targeted fix for async tool durability in the copilot orchestrator. It handles a specific gap where tool calls executed entirely by the Go side (no Sim-side durable database row and no local pending promise) were being silently skipped during the async resume loop, causing valid continuations to be abandoned.

Key changes:

  • A new early-continue branch is inserted in the inner pendingToolCallIds loop (after the !durableRow && localPendingPromise check) that detects Go-handled tools via context.toolCalls.get(toolCallId) and includes them in claimableToolCallIds so the resume payload is built correctly.
  • The branch only adds to claimableToolCallIds (not claimedToolCallIds), which is consistent with the pattern for tools that have no corresponding database row to mark as delivered.
  • A structured logger.info call surfaces the tool name and status for observability when this path is taken.

One area to verify: when the results are assembled for these Go-handled tools (lines 254–301), both completion and durable are undefined, so success is determined entirely by toolState?.result?.success. If the Go streaming layer does not write a result back into context.toolCalls for these tools, success will default to false and the resume payload will carry an error object instead of the actual tool output.

Confidence Score: 4/5

  • Safe to merge; the fix correctly closes the gap where Go-handled tools were silently skipped, with one non-blocking question about how success is derived for tools with no Sim-side result.
  • The change is small, well-targeted, and consistent with the surrounding code patterns (matching the existing !durableRow && localPendingPromise branch idiom). The only open question is whether toolState.result is reliably populated for Go-handled tools — if it is, the fix is complete; if not, Go-handled tools would be reported as failed in the resume payload despite succeeding, which could cause subtle conversation-state issues but not a crash or data loss.
  • apps/sim/lib/copilot/orchestrator/index.ts — specifically the results-building block (lines 254–301) and how toolState.result is populated for Go-side tool calls.

Important Files Changed

Filename Overview
apps/sim/lib/copilot/orchestrator/index.ts Adds a new early-continue branch in the async tool resume loop to handle Go-side-executed tools that have no Sim-side durable row and no local pending promise, allowing them to be included in the resume payload rather than silently skipped.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[For each toolCallId in pendingToolCallIds] --> B{Claim in DB succeeds?}
    B -- Yes --> C[Add to claimable + claimed lists]
    C --> NEXT[Next toolCallId]
    B -- No --> D[Fetch durableRow + localPendingPromise]
    D --> E{no durableRow AND\nlocalPendingPromise exists?}
    E -- Yes --> F[Add to claimable only\n local async tool]
    F --> NEXT
    E -- No --> G{durableRow exists AND\nstatus=running AND\nlocalPendingPromise?}
    G -- Yes --> H[Add to localPendingPromises\nwait for completion]
    H --> NEXT
    G -- No --> I{NEW: no durableRow AND\nno localPendingPromise AND\ntoolState exists?}
    I -- Yes --> J[Add to claimable only\n Go-handled tool]
    J --> NEXT
    I -- No --> K[Log warning: skip tool call]
    K --> NEXT

    NEXT --> L{All toolCallIds processed}
    L --> M{claimable > 0?}
    M -- Yes --> N[Build resume payload with results]
    M -- No --> O{localPendingPromises > 0?}
    O -- Yes --> P[Await all pending, retry loop]
    O -- No --> Q[Abandon continuation]
Loading

Reviews (1): Last reviewed commit: "Durability" | Re-trigger Greptile

@cursor
Copy link

cursor bot commented Mar 24, 2026

PR Summary

Medium Risk
Medium risk because it changes Copilot async-tool resume success inference/claim behavior (durability path) and adjusts PPTX preview rendering/abort behavior, which could affect long-running tool executions and client preview stability.

Overview
Copilot tool durability: Updates async-tool resume handling to treat Go-handled tool states as claimable even without a Sim-side durable row, and refines success detection by considering explicit in-memory tool status (in addition to durable/completion signals).

PPTX preview robustness: Hardens the PPTX preview API to return 400 on missing/invalid JSON bodies, and refactors the client PPTX viewer to separate streaming vs non-streaming render effects so background file refreshes don’t abort in-flight streaming compilation/rendering.

Runtime packaging: Extends the Docker runner image to include pptxgenjs and the pptx-worker.cjs script needed at runtime for PPTX generation.

Written by Cursor Bugbot for commit 3001b50. Configure here.

@Sg312 Sg312 merged commit 852dc93 into staging Mar 24, 2026
11 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/mothership-nonexistent-tools branch March 24, 2026 06:12
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.

2 participants