Query System Architecture
Overview
The Query System is the heart of Claude Code - it manages the conversation with Claude's API, handles tool execution, and orchestrates the entire interaction flow.
Shared from "Claude-Code" on Inkdown
The Query System is the heart of Claude Code - it manages the conversation with Claude's API, handles tool execution, and orchestrates the entire interaction flow.
| File | Purpose |
|---|---|
QueryEngine.ts | Main class managing query lifecycle |
query.ts | Core streaming logic and API communication |
query/config.ts | Query configuration building |
query/deps.ts | Dependency injection for testing |
query/transitions.ts | State machine transitions |
query/tokenBudget.ts | Token limit management |
QueryEngine is reusable across turns. You create it once per conversation, then call submitMessage() for each user input.
Using AsyncGenerator allows incremental UI updates:
Before sending to API, messages are normalized:
| Error Type | Strategy |
|---|---|
| Rate Limit | Wait and retry with backoff |
| Server Error | Retry with exponential backoff |
| Context Length | Compact and retry |
| Max Output | Truncate and continue |
| Invalid Tool | Return error to LLM |
Each submitMessage() is one "turn" - a complete request/response cycle.
The query function calls itself recursively when tools need to continue the conversation.
All responses stream - no blocking waits. UI updates incrementally.
QueryEngine holds state, but the query() function is pure - takes params, returns events.
Context window management happens transparently to the user.