fix(jef-91): run tool calls in parallel within a single LLM turn - #249
Conversation
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.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
WalkthroughThe 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. ChangesChat tool concurrency
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
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
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_skillsfor a cover-letter-style question).Promise.allso independent tool calls run concurrently, and results are mapped back to theirtoolCallIdby original array order (order doesn't depend on resolution order).executeToolalready catches its own errors and returns{ error }instead of throwing, soPromise.allis safe — one failing tool won't reject the whole batch.Linear: JEF-91
Test plan
toolCallIdeven when they resolve out of order.pnpm --filter @job-finder/api typecheckpasses.ChatWithAssistantUseCase.test.ts— 25/25 passing.DrizzleDocumentRepositoryordering bycreatedAttimestamp) confirmed to fail intermittently onmaintoo, unrelated to this change.Summary by CodeRabbit