The pipeline that turns a user message into Claude's response
// biome-ignore-all assist/source/organizeImports: ANT-ONLY import markers must not be reordered
import type {ToolResultBlockParam,
ToolUseBlock,
} from '@anthropic-ai/sdk/resources/index.mjs'
import type { CanUseToolFn } from './hooks/useCanUseTool.js'import { FallbackTriggeredError } from './services/api/withRetry.js'import {calculateTokenWarningState,
isAutoCompactEnabled,
type AutoCompactTrackingState,
} from './services/compact/autoCompact.js'
import { buildPostCompactMessages } from './services/compact/compact.js'/* eslint-disable @typescript-eslint/no-require-imports */
const reactiveCompact = feature('REACTIVE_COMPACT') ? (require('./services/compact/reactiveCompact.js') as typeof import('./services/compact/reactiveCompact.js')): null
const contextCollapse = feature('CONTEXT_COLLAPSE') ? (require('./services/contextCollapse/index.js') as typeof import('./services/contextCollapse/index.js')): null
/* eslint-enable @typescript-eslint/no-require-imports */
import {logEvent,
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
} from 'src/services/analytics/index.js'
import { ImageSizeError } from './utils/imageValidation.js'import { ImageResizeError } from './utils/imageResizer.js'import { findToolByName, type ToolUseContext } from './Tool.js'import { asSystemPrompt, type SystemPrompt } from './utils/systemPromptType.js'import type {AssistantMessage,
AttachmentMessage,
Message,
RequestStartEvent,
StreamEvent,
ToolUseSummaryMessage,
UserMessage,
TombstoneMessage,
} from './types/message.js'
import { logError } from './utils/log.js'import {PROMPT_TOO_LONG_ERROR_MESSAGE,
isPromptTooLongMessage,
} from './services/api/errors.js'
import { logAntError, logForDebugging } from './utils/debug.js'import {createUserMessage,
createUserInterruptionMessage,
normalizeMessagesForAPI,
createSystemMessage,
createAssistantAPIErrorMessage,
getMessagesAfterCompactBoundary,
createToolUseSummaryMessage,
createMicrocompactBoundaryMessage,
stripSignatureBlocks,
} from './utils/messages.js'
import { generateToolUseSummary } from './services/toolUseSummary/toolUseSummaryGenerator.js'import { prependUserContext, appendSystemContext } from './utils/api.js'import {createAttachmentMessage,
The query() function in src/query.ts is the heart of Claude Code. It takes a conversation history, calls the Anthropic API with streaming, and yields messages back to the REPL as they arrive.
`query()` is an async generator function — it `yield`s messages one at a time as they stream in, rather than buffering everything and returning at the end. This is what makes the UI feel live.
The pipeline has distinct phases: message normalization → system prompt assembly → streaming API call → tool execution → token budget check → optional compaction. Each phase is independent and testable.
When the API stream fails mid-response, the executor calls `discard()` on the StreamingToolExecutor so any in-flight tool calls are abandoned rather than producing partial results.
Ask anything about Query Engine & Main Loop
Powered by Groq · Enter to send, Shift+Enter for newline