MCPcopy
hub / github.com/liuup/claude-code-analysis / queryLoop

Function queryLoop

src/query.ts:241–1729  ·  view source on GitHub ↗
(
  params: QueryParams,
  consumedCommandUuids: string[],
)

Source from the content-addressed store, hash-verified

239}
240
241async function* queryLoop(
242 params: QueryParams,
243 consumedCommandUuids: string[],
244): AsyncGenerator<
245 | StreamEvent
246 | RequestStartEvent
247 | Message
248 | TombstoneMessage
249 | ToolUseSummaryMessage,
250 Terminal
251> {
252 // Immutable params — never reassigned during the query loop.
253 const {
254 systemPrompt,
255 userContext,
256 systemContext,
257 canUseTool,
258 fallbackModel,
259 querySource,
260 maxTurns,
261 skipCacheWrite,
262 } = params
263 const deps = params.deps ?? productionDeps()
264
265 // Mutable cross-iteration state. The loop body destructures this at the top
266 // of each iteration so reads stay bare-name (`messages`, `toolUseContext`).
267 // Continue sites write `state = { ... }` instead of 9 separate assignments.
268 let state: State = {
269 messages: params.messages,
270 toolUseContext: params.toolUseContext,
271 maxOutputTokensOverride: params.maxOutputTokensOverride,
272 autoCompactTracking: undefined,
273 stopHookActive: undefined,
274 maxOutputTokensRecoveryCount: 0,
275 hasAttemptedReactiveCompact: false,
276 turnCount: 1,
277 pendingToolUseSummary: undefined,
278 transition: undefined,
279 }
280 const budgetTracker = feature('TOKEN_BUDGET') ? createBudgetTracker() : null
281
282 // task_budget.remaining tracking across compaction boundaries. Undefined
283 // until first compact fires — while context is uncompacted the server can
284 // see the full history and handles the countdown from {total} itself (see
285 // api/api/sampling/prompt/renderer.py:292). After a compact, the server sees
286 // only the summary and would under-count spend; remaining tells it the
287 // pre-compact final window that got summarized away. Cumulative across
288 // multiple compacts: each subtracts the final context at that compact's
289 // trigger point. Loop-local (not on State) to avoid touching the 7 continue
290 // sites.
291 let taskBudgetRemaining: number | undefined = undefined
292
293 // Snapshot immutable env/statsig/session state once at entry. See QueryConfig
294 // for what's included and why feature() gates are intentionally excluded.
295 const config = buildQueryConfig()
296
297 // Fired once per user turn — the prompt is invariant across loop iterations,
298 // so per-iteration firing would ask sideQuery the same question N times.

Callers 1

queryFunction · 0.85

Calls 15

productionDepsFunction · 0.85
createBudgetTrackerFunction · 0.85
buildQueryConfigFunction · 0.85
queryCheckpointFunction · 0.85
applyToolResultBudgetFunction · 0.85
recordContentReplacementFunction · 0.85
asSystemPromptFunction · 0.85
appendSystemContextFunction · 0.85
logEventFunction · 0.85

Tested by

no test coverage detected