Skip to content

QueryEngine 编排器

概述

QueryEnginequery() 函数之上的高层编排器,负责管理会话级别的状态:消息历史、系统提示词组装、文件快照、权限跟踪等。

Source: src/QueryEngine.ts (1320 行)

类定义

typescript
// Source: src/QueryEngine.ts:186-209
export class QueryEngine {
  private config: QueryEngineConfig
  private mutableMessages: Message[]
  private abortController: AbortController
  private permissionDenials: SDKPermissionDenial[]
  private totalUsage: NonNullableUsage
  private hasHandledOrphanedPermission = false
  private readFileState: FileStateCache
  private discoveredSkillNames = new Set<string>()
  private loadedNestedMemoryPaths = new Set<string>()
}

QueryEngineConfig

typescript
// Source: src/QueryEngine.ts:132-175
type QueryEngineConfig = {
  cwd: string
  tools: Tools
  commands: Command[]
  mcpClients: MCPServerConnection[]
  agents: AgentDefinition[]
  canUseTool: CanUseToolFn
  getAppState: () => AppState
  setAppState: (f: (prev: AppState) => AppState) => void
  initialMessages?: Message[]
  readFileCache: FileStateCache
  customSystemPrompt?: string
  appendSystemPrompt?: string
  userSpecifiedModel?: string
  fallbackModel?: string
  thinkingConfig?: ThinkingConfig
  maxTurns?: number
  maxBudgetUsd?: number
  taskBudget?: { total: number }
  verbose?: boolean
  // ... 更多选项
}

submitMessage() — 主入口

Source: src/QueryEngine.ts:211+

typescript
async *submitMessage(
  prompt: string | ContentBlockParam[],
  options?: { uuid?: string; isMeta?: boolean },
): AsyncGenerator<SDKMessage, void, unknown>

这是 SDK 和 REPL 提交用户消息的入口。它是一个 Generator,会逐步 yield 出消息事件。

执行流程

阶段 1:初始化 (行 215-286)

typescript
// 清理每轮技能发现
this.discoveredSkillNames.clear();

// 包装权限检查以跟踪拒绝
const wrappedCanUseTool = (tool, input, context) => {
  const result = await this.config.canUseTool(tool, input, context);
  if (result.behavior === 'deny') {
    this.permissionDenials.push({ tool, input, reason: result.message });
  }
  return result;
};

// 确定模型和思考配置
const model = this.config.userSpecifiedModel ?? getDefaultMainLoopModel();
const thinkingConfig = resolveThinkingConfig(model, this.config.thinkingConfig);

阶段 2:系统提示词组装 (行 287-328)

typescript
// 获取系统提示词的各部分
const parts = await fetchSystemPromptParts();

// 获取用户上下文
const userContext = await getUserContext();

// 组合最终系统提示词
const systemPrompt = composeSystemPrompt(
  this.config.customSystemPrompt ?? parts.defaultPrompt,
  memoryMechanicsPrompt,
  this.config.appendSystemPrompt
);

阶段 3:用户输入处理 (行 413-431)

processUserInput() 解析斜杠命令、附件等:

typescript
const { messages, shouldQuery, allowedTools, modelOverrides } =
  await processUserInput(prompt, context);

如果 shouldQueryfalse(例如 /help 命令),不会发起 API 查询。

阶段 4:查询循环

将处理后的消息传入 query() 函数执行核心循环。QueryEngine 逐步 yield 出来自 query() 的所有事件。

与 query() 的关系

职责QueryEnginequery()
消息历史持久化
系统提示词组装
用户输入解析
权限拒绝跟踪
用量统计
对话轮次循环
消息压缩
工具执行
错误恢复
流式事件分发

下一步