Skip to content

fix(jef-91): run tool calls in parallel within a single LLM turn - #249

Merged
mankatcheung merged 1 commit into
mainfrom
fix/jef-91-parallelize-tool-calls
Aug 5, 2026
Merged

mankatcheung merged 1 commit into
mainfrom
fix/jef-91-parallelize-tool-calls

Conversation

@mankatcheung

@mankatcheung mankatcheung commented Aug 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • ChatWithAssistantUseCase.complete() executed each tool call in a turn one after another (for...await), even when the LLM requested multiple independent tools in the same turn (e.g. list_work_experiences, list_educations, list_skills for a cover-letter-style question).
  • Switched to Promise.all so independent tool calls run concurrently, and results are mapped back to their toolCallId by original array order (order doesn't depend on resolution order).
  • executeTool already catches its own errors and returns { error } instead of throwing, so Promise.all is safe — one failing tool won't reject the whole batch.

Linear: JEF-91

Test plan

  • Added a test asserting multiple tool calls from the same turn are dispatched concurrently and results are matched to the correct toolCallId even when they resolve out of order.
  • pnpm --filter @job-finder/api typecheck passes.
  • ChatWithAssistantUseCase.test.ts — 25/25 passing.
  • Full API test suite passes aside from a pre-existing, unrelated flaky test (DrizzleDocumentRepository ordering by createdAt timestamp) confirmed to fail intermittently on main too, unrelated to this change.

Summary by CodeRabbit

  • Performance
    • Multiple assistant tool calls are now processed concurrently, improving response times when several tools are requested together.
    • Results remain presented in the correct order, ensuring consistent assistant responses.

ChatWithAssistantUseCase awaited each tool call in a for-loop, so
independent tool calls (e.g. list_work_experiences, list_educations,
list_skills requested in the same turn) ran one after another instead
of concurrently. Switch to Promise.all and map results back to their
call ids in original order.
@coderabbitai

coderabbitai Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c1bafe10-b202-416d-9856-c2dd7025f1e6

📥 Commits

Reviewing files that changed from the base of the PR and between 3d34d51 and 44de04c.

📒 Files selected for processing (2)
  • apps/api/src/__tests__/application/chat/ChatWithAssistantUseCase.test.ts
  • apps/api/src/use-cases/chat/ChatWithAssistantUseCase.ts

Walkthrough

The chat use case now executes multiple tool calls concurrently. It preserves tool-result message order and requests the final assistant response after all tools complete. Tests cover argument forwarding, call-ID matching, completion-order independence, and final response generation.

Changes

Chat tool concurrency

Layer / File(s) Summary
Concurrent tool execution and ordered results
apps/api/src/use-cases/chat/ChatWithAssistantUseCase.ts, apps/api/src/__tests__/application/chat/ChatWithAssistantUseCase.test.ts
ChatWithAssistantUseCase runs tool calls with Promise.all and appends results in the original call order. Tests verify arguments, call IDs, differing completion times, and the final response.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant LLM
  participant ChatWithAssistantUseCase
  participant Tools
  participant MessageHistory
  LLM->>ChatWithAssistantUseCase: Return multiple tool calls
  ChatWithAssistantUseCase->>Tools: Execute tool calls concurrently
  Tools-->>ChatWithAssistantUseCase: Return results at different times
  ChatWithAssistantUseCase->>MessageHistory: Append results in call order
  ChatWithAssistantUseCase->>LLM: Request final assistant response
  LLM-->>ChatWithAssistantUseCase: Return final response
Loading

Poem

A rabbit saw tools race in flight,
Yet results lined up just right.
Calls kept their IDs and place,
Then the final words appeared with grace.
“Concurrent hops!” cheered the rabbit bright.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/jef-91-parallelize-tool-calls

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mankatcheung
mankatcheung marked this pull request as ready for review August 5, 2026 22:23
@mankatcheung
mankatcheung merged commit ba1f37d into main Aug 5, 2026
10 of 11 checks passed
@mankatcheung
mankatcheung deleted the fix/jef-91-parallelize-tool-calls branch August 6, 2026 16:50
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