config.ts
1 import { getSessionId } from '../bootstrap/state.js' 2 import { checkStatsigFeatureGate_CACHED_MAY_BE_STALE } from '../services/analytics/growthbook.js' 3 import type { SessionId } from '../types/ids.js' 4 import { isEnvTruthy } from '../utils/envUtils.js' 5 6 // -- config 7 8 // Immutable values snapshotted once at query() entry. Separating these from 9 // the per-iteration State struct and the mutable ToolUseContext makes future 10 // step() extraction tractable — a pure reducer can take (state, event, config) 11 // where config is plain data. 12 // 13 // Intentionally excludes feature() gates — those are tree-shaking boundaries 14 // and must stay inline at the guarded blocks for dead-code elimination. 15 export type QueryConfig = { 16 sessionId: SessionId 17 18 // Runtime gates (env/statsig). NOT feature() gates — see above. 19 gates: { 20 // Statsig — CACHED_MAY_BE_STALE already admits staleness, so snapshotting 21 // once per query() call stays within the existing contract. 22 streamingToolExecution: boolean 23 emitToolUseSummaries: boolean 24 isAnt: boolean 25 fastModeEnabled: boolean 26 } 27 } 28 29 export function buildQueryConfig(): QueryConfig { 30 return { 31 sessionId: getSessionId(), 32 gates: { 33 streamingToolExecution: checkStatsigFeatureGate_CACHED_MAY_BE_STALE( 34 'tengu_streaming_tool_execution2', 35 ), 36 emitToolUseSummaries: isEnvTruthy( 37 process.env.CLAUDE_CODE_EMIT_TOOL_USE_SUMMARIES, 38 ), 39 isAnt: process.env.USER_TYPE === 'ant', 40 // Inlined from fastMode.ts to avoid pulling its heavy module graph 41 // (axios, settings, auth, model, oauth, config) into test shards that 42 // didn't previously load it — changes init order and breaks unrelated tests. 43 fastModeEnabled: !isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_FAST_MODE), 44 }, 45 } 46 }