claude code
hooks?mcpServers?agents?类别数量完整实现率控制请求类型8 种43%(3.5/8)完整实现3 个37.5%部分实现2 个25%占位实现3 个37.5%核心文件数5 个| CLIControlInitializeRequest // 初始化| CLIControlInterruptRequest // 中断| CLIControlSetModelRequest // 设置模型。
gemini-cli SDK/CLI 控制协议能力完整清单
📋 目录
1. CLI 端能力
1.1 控制请求类型(8种)
① initialize(初始化)
功能:初始化会话,接收 SDK 配置
请求参数:
{
subtype: 'initialize';
hooks?: Record<string, HookMatcher[]> | null; // Hook 注册(暂不处理)
sdkMcpServers?: Record<string, SdkMcpServerConfig>; // SDK MCP 服务器(暂不处理)
mcpServers?: Record<string, McpServerConfig>; // 外部 MCP 服务器(暂不处理)
agents?: AgentConfig[]; // Agent 配置(暂不处理)
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:190-221
实现状态:⚠️ 部分实现
返回值:
{
commands: string[]; // 支持的工具列表
output_style: 'stream-json'; // 输出格式
capabilities: {
tools: string[]; // 可用工具
mcpServers: false; // ❌ 暂不支持 MCP
hooks: false; // ❌ 暂不支持 Hook
permissionControl: boolean; // 是否支持权限控制
};
model: string; // 当前模型
permissionMode: string; // 当前权限模式
}
行为:
- 接收所有配置参数但不处理(注释标注"暂不实现")
- 返回初始化结果
- 标记
mcpServers: false,hooks: false
② interrupt(中断)
功能:中断当前会话
请求参数:
{
subtype: 'interrupt';
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:287-296
实现状态:✅ 完整实现
返回值:
null; // 无返回值
行为:
- 设置
interrupted = true - 触发
emit('interrupt')事件 - Session 监听该事件并调用
abortController.abort()
③ set_model(设置模型)
功能:设置当前模型(仅存储,不实际切换)
请求参数:
{
subtype: 'set_model';
model: string | null;
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:317-330
实现状态:⚠️ 占位实现
返回值:
null;
行为:
if (model) {
this.currentModel = model;
// TODO: 实际切换模型(需要重新创建客户端)
}
差异:只存储模型名称,不进行验证或实际切换
④ supported_commands(支持的命令)
功能:获取支持的工具列表
请求参数:
{
subtype: 'supported_commands';
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:358-362
实现状态:✅ 完整实现
返回值:
{
commands: string[]; // 从构造函数传入的 supportedTools
}
⑤ can_use_tool(工具权限检查)
功能:检查工具使用权限
请求参数:
{
subtype: 'can_use_tool';
tool_name: string;
tool_use_id: string;
input: unknown;
permission_suggestions?: PermissionSuggestion[];
blocked_path?: string | null;
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:226-282
实现状态:✅ 完整实现
返回值:
{
behavior: 'allow' | 'deny'; // 允许或拒绝
updatedInput?: unknown; // 修改后的输入
message?: string; // 拒绝原因
interrupt?: boolean; // 是否中断
}
行为:
- 如果没有提供
canUseToolCallback,默认允许所有工具 - 如果有回调,创建 60 秒超时控制
- 调用用户回调函数
- 超时或错误时默认拒绝(安全策略)
超时配置:
const DEFAULT_TIMEOUTS = {
canUseTool: 60000, // 60秒
controlRequest: 60000,
initialize: 60000,
};
⑥ set_permission_mode(设置权限模式)
功能:设置权限模式(仅存储,不实际切换)
请求参数:
{
subtype: 'set_permission_mode';
mode: string; // 'default' | 'plan' | 'auto-edit' | 'yolo'
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:301-312
实现状态:⚠️ 占位实现
返回值:
null;
行为:
this.currentPermissionMode = mode;
// TODO: 实际更新配置中的权限模式
差异:只存储模式字符串,不验证有效性或实际更新配置
⑦ mcp_server_status(MCP 服务器状态)
功能:获取 MCP 服务器状态(占位)
请求参数:
{
subtype: 'mcp_server_status';
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:349-353
实现状态:❌ 占位实现
返回值:
{
servers: {}; // 空对象
}
行为:返回空对象,不支持任何 MCP 服务器
⑧ mcp_message(MCP 消息传递)
功能:MCP 消息路由(占位)
请求参数:
{
subtype: 'mcp_message';
server_name: string;
message: McpMessage;
}
实现位置:packages/cli/src/sdk/controlProtocol.ts:335-344
实现状态:❌ 明确不支持
返回值:
{
error: 'MCP servers are not supported in Gemini CLI';
mcp_response: { jsonrpc: '2.0', result: {}, id: 0 };
}
行为:明确返回错误信息,不支持 MCP 消息
1.2 控制协议处理器
ControlProtocolHandler 类
位置:packages/cli/src/sdk/controlProtocol.ts
继承:extends EventEmitter
职责:
- 处理来自 SDK 的控制请求
- 调用用户提供的回调函数
- 返回控制响应
- 管理待处理的请求(pendingRequests Map)
字段:
private pendingRequests = new Map<string, {
resolve: (value: unknown) => void;
reject: (error: Error) => void;
timeout: NodeJS.Timeout;
abortController: AbortController;
}>();
private canUseToolCallback?: (toolName: string, toolInput: unknown, context: ToolPermissionContext) => Promise<PermissionResult>;
private currentPermissionMode: string = 'default';
private currentModel: string;
private initializationResult: unknown = null;
private debugMode: boolean;
private supportedTools: string[];
private interrupted: boolean = false;
公共方法:
handleControlRequest(request: SDKControlRequest)- 处理控制请求isInterrupted()- 检查是否已中断resetInterrupt()- 重置中断状态getCurrentModel()- 获取当前模型getCurrentPermissionMode()- 获取当前权限模式cleanup()- 清理资源
1.3 Session 集成
SDK 模式检测
位置:packages/cli/src/nonInteractive/session.ts:114-148
检测方式:
this.isSdkMode = process.env['GEMINI_CHANNEL'] === 'SDK' ||
process.argv.includes('--channel=SDK') ||
process.argv.findIndex((x, i) => x === '--channel' && isChannelArg(i)) >= 0;
初始化:
if (this.isSdkMode) {
const supportedTools = this.config.getCoreTools?.() ?? [];
const model = this.config.getModel();
this.controlHandler = new ControlProtocolHandler(
model,
supportedTools,
this.debugMode,
undefined // canUseToolCallback - 可选
);
// 监听中断事件
this.controlHandler.on('interrupt', () => {
this.abortController.abort();
});
}
控制请求路由:
// 在 Session.run() 主循环中
if (this.isSdkMode && isControlRequest(message)) {
await this.handleControlRequest(message);
continue;
}
1.4 输出写入机制
writeControlResponse() 方法
位置:packages/cli/src/nonInteractive/io/StreamJsonOutputAdapter.ts:625-644
写入方式:
writeControlResponse(response: SDKControlResponse): void {
const jsonStr = `${JSON.stringify(response)}\n`;
process.stderr.write(`[CONTROL_RESPONSE] Writing: ${jsonStr}`);
try {
// 获取 stdout 文件描述符
const fd = (process.stdout as any)._handle?.fd || (process.stdout as any).fd || 1;
const buffer = new TextEncoder().encode(jsonStr);
// 使用 fs.writeSync 同步写入,绕过所有缓冲
fsWriteSync(fd, buffer);
} catch (error) {
// 如果 writeSync 失败,回退到普通写入
process.stderr.write(`[CONTROL_RESPONSE] writeSync failed: ${error}\n`);
process.stdout.write(jsonStr);
}
}
特点:
- 同步写入:使用
fs.writeSync(fd, buffer) - 绕过缓冲:直接写入文件描述符,确保可靠性
- 回退机制:writeSync 失败时回退到
process.stdout.write() - 调试输出:写入 stderr 避免污染 stdout
对比:
- qwen-code:全部使用
process.stdout.write()(异步) - gemini-cli:
- 普通消息:
process.stdout.write()(异步) - 控制响应:
fs.writeSync()(同步)
- 普通消息:
2. SDK 端能力
2.1 类型定义(完整)
SDKControlRequest
interface SDKControlRequest {
type: 'control_request';
request_id: string;
request: ControlRequestPayload;
}
ControlRequestPayload(8种)
type ControlRequestPayload =
| InitializeRequest // 初始化
| CanUseToolRequest // 工具权限
| InterruptRequest // 中断
| SetPermissionModeRequest // 设置权限模式
| SetModelRequest // 设置模型
| McpMessageRequest // MCP 消息
| McpServerStatusRequest // MCP 状态
| SupportedCommandsRequest; // 支持的命令
SDKControlResponse
interface SDKControlResponse {
type: 'control_response';
response: ControlSuccessResponse | ControlErrorResponse;
}
interface ControlSuccessResponse {
subtype: 'success';
request_id: string;
response: unknown;
}
interface ControlErrorResponse {
subtype: 'error';
request_id: string;
error: string | { message: string; [key: string]: unknown };
}
类型守卫
function isControlRequest(message: unknown): message is SDKControlRequest;
function isControlResponse(message: unknown): message is SDKControlResponse;
function isControlCancel(message: unknown): message is ControlCancelRequest;
位置:packages/cli/src/sdk/types.ts
2.2 输入读取
StreamJsonInputReader
位置:packages/cli/src/nonInteractive/io/StreamJsonInputReader.ts
功能:从 stdin 逐行读取 JSON 消息
实现:
async *read(): AsyncGenerator<StreamJsonInputMessage> {
const rl = createInterface({
input: this.input,
crlfDelay: Number.POSITIVE_INFINITY, // 支持跨平台换行符
terminal: false, // 非终端模式(管道输入)
});
for await (const rawLine of rl) {
const line = rawLine.trim();
if (!line) continue;
yield this.parse(line);
}
}
支持的消息类型:
type StreamJsonInputMessage =
| CLIMessage
| CLIControlRequest
| CLIControlResponse
| ControlCancelRequest;
验证:
- 必须是对象
- 必须有
type字段 type必须是字符串
2.3 消息输出
StreamJsonOutputAdapter
位置:packages/cli/src/nonInteractive/io/StreamJsonOutputAdapter.ts
职责:
- 处理 Gemini API 事件流
- 构建标准格式的 JSON 消息
- 输出到 stdout
输出方法:
emitMessageImpl(message: CLIMessage)- 发送消息(异步)writeControlResponse(response: SDKControlResponse)- 发送控制响应(同步)emitResult(options: ResultOptions)- 发送结果消息emitUserMessage(parts: Part[])- 发送用户消息emitToolResult(request, response)- 发送工具结果emitSystemMessage(subtype, data)- 发送系统消息
写入方式对比:
| 方法 | 写入方式 | 用途 |
|---|---|---|
emitMessageImpl() |
process.stdout.write() |
普通消息(异步) |
writeControlResponse() |
fs.writeSync(fd, buffer) |
控制响应(同步) |
3. 类型定义清单
3.1 控制请求载荷(8种)
InitializeRequest
interface InitializeRequest {
subtype: 'initialize';
hooks?: Record<string, HookMatcher[]> | null;
sdkMcpServers?: Record<string, SdkMcpServerConfig>;
mcpServers?: Record<string, McpServerConfig>;
agents?: AgentConfig[];
}
CanUseToolRequest
interface CanUseToolRequest {
subtype: 'can_use_tool';
tool_name: string;
tool_use_id: string;
input: unknown;
permission_suggestions?: PermissionSuggestion[];
blocked_path?: string | null;
}
InterruptRequest
interface InterruptRequest {
subtype: 'interrupt';
}
SetPermissionModeRequest
interface SetPermissionModeRequest {
subtype: 'set_permission_mode';
mode: string;
}
SetModelRequest
interface SetModelRequest {
subtype: 'set_model';
model: string | null;
}
McpMessageRequest
interface McpMessageRequest {
subtype: 'mcp_message';
server_name: string;
message: McpMessage;
}
interface McpMessage {
jsonrpc?: string;
method: string;
params?: Record<string, unknown>;
id?: string | number | null;
}
McpServerStatusRequest
interface McpServerStatusRequest {
subtype: 'mcp_server_status';
}
SupportedCommandsRequest
interface SupportedCommandsRequest {
subtype: 'supported_commands';
}
3.2 配置类型
SdkMcpServerConfig
interface SdkMcpServerConfig {
type: 'sdk';
name: string;
}
McpServerConfig
interface McpServerConfig {
command?: string;
args?: string[];
env?: Record<string, string>;
cwd?: string;
url?: string;
httpUrl?: string;
headers?: Record<string, string>;
tcp?: string;
timeout?: number;
trust?: boolean;
description?: string;
includeTools?: string[];
excludeTools?: string[];
extensionName?: string;
}
AgentConfig
interface AgentConfig {
name: string;
description?: string;
tools?: string[];
systemPrompt?: string;
level?: string;
filePath?: string;
modelConfig?: {
model?: string;
temp?: number;
topP?: number;
};
runConfig?: {
maxTimeMinutes?: number;
maxTurns?: number;
};
color?: string;
}
PermissionSuggestion
interface PermissionSuggestion {
type: 'allow' | 'deny' | 'modify';
label: string;
description?: string;
modifiedInput?: unknown;
}
HookMatcher
interface HookMatcher {
matcher?: string | null;
hookCallbackIds: string[];
timeout?: number;
}
PermissionMode
type PermissionMode = 'default' | 'plan' | 'auto-edit' | 'yolo';
3.3 消息类型
CLIMessage(5种)
type CLIMessage =
| CLIUserMessage // 用户消息
| CLIAssistantMessage // 助手消息
| CLISystemMessage // 系统消息
| CLIResultMessage // 结果消息
| CLIPartialAssistantMessage; // 部分助手消息(流事件)
ContentBlock(4种)
type ContentBlock =
| TextBlock // { type: 'text', text: string }
| ThinkingBlock // { type: 'thinking', thinking: string }
| ToolUseBlock // { type: 'tool_use', id, name, input }
| ToolResultBlock; // { type: 'tool_result', tool_use_id, content }
4. 完整能力矩阵
4.1 控制请求能力矩阵
| # | 控制请求 | CLI 处理 | 实现状态 | 完整度 | 说明 |
|---|---|---|---|---|---|
| 1 | initialize | ✅ | ⚠️ 部分实现 | 30% | 接收配置但不处理 |
| 2 | interrupt | ✅ | ✅ 完整 | 100% | 完整实现 |
| 3 | set_model | ✅ | ⚠️ 占位 | 10% | 仅存储,TODO |
| 4 | supported_commands | ✅ | ✅ 完整 | 100% | 返回工具列表 |
| 5 | can_use_tool | ✅ | ✅ 完整 | 100% | 完整实现+超时 |
| 6 | set_permission_mode | ✅ | ⚠️ 占位 | 10% | 仅存储,TODO |
| 7 | mcp_server_status | ✅ | ❌ 占位 | 5% | 返回空对象 |
| 8 | mcp_message | ✅ | ❌ 不支持 | 0% | 明确返回错误 |
4.2 架构能力矩阵
| 能力 | gemini-cli | qwen-code | 实现差异 |
|---|---|---|---|
| 架构模式 | 单一 Handler 类 | 三层架构 | ⚠️ 简化 |
| 控制器数量 | 1 个 | 5 个 | ⚠️ 缺少分层 |
| 状态管理 | 字段存储 | ControlContext | ⚠️ 简化 |
| 请求路由 | switch-case | 自动路由 | ⚠️ 手动分发 |
| 生命周期管理 | ✅ pendingRequests Map | ✅ 注册表+超时+取消 | ✅ 相似 |
| 双向通信 | ❌ 无 | ✅ CLI→SDK 控制 | ❌ 缺失 |
| 错误处理 | ✅ 统一格式 | ✅ 统一格式 | ✅ 相似 |
| 类型安全 | ✅ 完整类型 | ✅ 完整类型 | ✅ 相似 |
| 可扩展性 | ⚠️ 需修改核心 | ✅ 添加 Controller | ⚠️ 中等 |
4.3 功能特性矩阵
权限系统特性
| 特性 | gemini-cli | qwen-code | 状态 |
|---|---|---|---|
| 4 种权限模式类型 | ✅ 类型定义 | ✅ 实际切换 | ⚠️ 仅类型 |
| 工具权限回调 | ✅ 支持 | ✅ 支持 | ✅ 相同 |
| 权限建议系统 | ✅ 接收 | ✅ 生成建议 | ⚠️ 仅接收 |
| 超时控制 | ✅ 60秒 | ✅ 60秒 | ✅ 相同 |
| 模式实际切换 | ❌ TODO | ✅ 验证+更新 | ❌ 缺失 |
MCP 集成特性
| 特性 | gemini-cli | qwen-code | 状态 |
|---|---|---|---|
| SDK MCP 服务器 | ❌ 不支持 | ✅ 完整支持 | ❌ 缺失 |
| 外部 MCP 服务器 | ❌ 不支持 | ✅ 完整支持 | ❌ 缺失 |
| OAuth 支持 | ❌ 无 | ✅ 3种认证 | ❌ 缺失 |
| 消息路由 | ❌ 返回错误 | ✅ 双向路由 | ❌ 缺失 |
| 服务器状态查询 | ❌ 返回空 | ✅ 实际状态 | ❌ 缺失 |
系统控制特性
| 特性 | gemini-cli | qwen-code | 状态 |
|---|---|---|---|
| 模型切换 | ⚠️ 仅存储 | ✅ 验证+切换+回滚 | ❌ 缺失 |
| 中断控制 | ✅ 完整 | ✅ 完整 | ✅ 相同 |
| 命令列表 | ✅ 静态列表 | ✅ 动态加载 | ⚠️ 静态 |
| 系统消息通知 | ✅ 支持 | ✅ 支持 | ✅ 相同 |
| Agent 配置 | ❌ 忽略 | ✅ 实际处理 | ❌ 缺失 |
写入机制特性
| 特性 | gemini-cli | qwen-code | 差异 |
|---|---|---|---|
| 普通消息写入 | 异步 | 异步 | ✅ 相同 |
| 控制响应写入 | 同步 | 异步 | ⚠️ 不同 |
| 写入方式 | fs.writeSync() |
process.stdout.write() |
⚠️ 不同 |
| 缓冲策略 | 绕过缓冲 | 使用缓冲 | ⚠️ 不同 |
| 回退机制 | ✅ 支持 | ❌ 无 | ✅ 优势 |
4.4 写入机制对比详解
gemini-cli
// 控制响应:同步写入
writeControlResponse(response: SDKControlResponse): void {
const fd = (process.stdout as any)._handle?.fd || 1;
const buffer = new TextEncoder().encode(jsonStr);
fsWriteSync(fd, buffer); // 绕过缓冲,确保可靠性
}
// 普通消息:异步写入
emitMessageImpl(message: CLIMessage): void {
process.stdout.write(`${JSON.stringify(message)}\n`);
}
qwen-code
// 所有消息:异步写入
emitMessageImpl(message: CLIMessage | ControlMessage): void {
process.stdout.write(`${JSON.stringify(message)}\n`);
}
关键差异:
- gemini-cli:控制响应使用同步写入,确保立即发送
- qwen-code:全部使用异步写入,依赖系统缓冲
5. 核心文件位置
5.1 CLI 端核心文件
packages/cli/src/
├── sdk/
│ ├── controlProtocol.ts # 控制协议处理器(435行)
│ └── types.ts # SDK 类型定义(323行)
└── nonInteractive/
├── session.ts # 会话管理(748行)
├── types.ts # CLI 类型定义(573行)
└── io/
├── StreamJsonInputReader.ts # 输入读取器(98行)
└── StreamJsonOutputAdapter.ts # 输出适配器(892行)
5.2 关键代码位置
ControlProtocolHandler
- 文件:
packages/cli/src/sdk/controlProtocol.ts:67-434 - 类定义:435行
- 控制请求处理:
handleControlRequest() - 初始化处理:
handleInitialize()(line 190) - 权限检查:
handleCanUseTool()(line 226) - 中断处理:
handleInterrupt()(line 287) - 权限模式设置:
handleSetPermissionMode()(line 301) - 模型设置:
handleSetModel()(line 317) - MCP 消息:
handleMcpMessage()(line 335) - MCP 状态:
handleMcpServerStatus()(line 349) - 命令列表:
handleSupportedCommands()(line 358)
Session 集成
- SDK 模式检测:
packages/cli/src/nonInteractive/session.ts:114-148 - 控制请求路由:
packages/cli/src/nonInteractive/session.ts:629-633 - 控制请求处理:
packages/cli/src/nonInteractive/session.ts:482-519
写入机制
- 同步写入:
packages/cli/src/nonInteractive/io/StreamJsonOutputAdapter.ts:625-644 - 异步写入:
packages/cli/src/nonInteractive/io/StreamJsonOutputAdapter.ts:523-536
6. 总结
6.1 功能统计
| 类别 | 数量 | 完整实现率 |
|---|---|---|
| 控制请求类型 | 8 种 | 43%(3.5/8) |
| 完整实现 | 3 个 | 37.5% |
| 部分实现 | 2 个 | 25% |
| 占位实现 | 3 个 | 37.5% |
| 核心文件数 | 5 个 | - |
6.2 实现完整度分析
✅ 完整实现(3个)
- interrupt - 中断控制
- supported_commands - 命令列表
- can_use_tool - 工具权限(含超时)
⚠️ 部分实现(2个)
- initialize - 接收配置但不处理
- hooks: 忽略
- sdkMcpServers: 忽略
- mcpServers: 忽略
- agents: 忽略
- can_use_tool - 仅回调,无工具注册表检查
❌ 占位/不支持(3个)
- set_model - 仅存储,TODO
- set_permission_mode - 仅存储,TODO
- mcp_server_status - 返回空对象
- mcp_message - 明确返回错误
6.3 关键特性
- ✅ 基础控制协议:8 种控制请求全部定义
- ✅ 权限回调机制:完整的 canUseTool 回调系统
- ✅ 超时控制:60秒超时保护
- ✅ 中断机制:完整的中断控制
- ⚠️ 权限模式切换:仅存储,不实际生效
- ⚠️ 模型切换:仅存储,不实际切换
- ❌ MCP 集成:完全不支持
- ❌ Hook 系统:类型定义存在但不处理
- ❌ Agent 配置:忽略所有配置
- ✅ 同步写入:控制响应使用 fs.writeSync
6.4 与 qwen-code 对比
| 维度 | gemini-cli | qwen-code | 差距 |
|---|---|---|---|
| 架构复杂度 | 简单(单类) | 复杂(三层) | -2 层 |
| 代码行数 | ~3,000 行 | ~5,000 行 | -40% |
| 控制请求完整度 | 43% | 95% | -52% |
| MCP 支持 | ❌ | ✅ | 完全缺失 |
| 权限系统 | ⚠️ 基础 | ✅ 完整 | 缺少实际切换 |
| 模型切换 | ⚠️ 占位 | ✅ 完整 | 缺少验证+切换 |
| 可扩展性 | ⚠️ 中等 | ✅ 高 | 需重构 |
6.5 实现优势
- ✅ 同步写入机制:控制响应使用
fs.writeSync(),确保可靠性 - ✅ 类型安全:完整的 TypeScript 类型定义
- ✅ 简洁架构:单一 Handler 类,易于理解
- ✅ 超时保护:60秒超时,防止阻塞
6.6 实现劣势
- ❌ 功能完整度低:仅 43% 控制请求完整实现
- ❌ MCP 完全缺失:不支持任何 MCP 功能
- ❌ TODO 标记多:多个核心功能仅占位
- ⚠️ 架构可扩展性差:添加新功能需修改核心类
- ❌ 配置忽略:初始化配置全部不处理
qwen-code SDK/CLI 控制协议能力完整清单
📋 目录
1. CLI 端能力
1.1 控制请求类型(8种)
① initialize(初始化)
功能:初始化会话,配置 SDK MCP 服务器和外部 MCP 服务器
请求参数:
{
subtype: 'initialize';
hooks?: HookRegistration[] | null; // Hook 注册
sdkMcpServers?: Record<string, {
type: 'sdk';
name: string;
}>; // SDK 端管理的 MCP 服务器
mcpServers?: Record<string, {
command?: string;
args?: string[];
env?: Record<string, string>;
cwd?: string;
url?: string;
httpUrl?: string;
headers?: Record<string, string>;
tcp?: string;
timeout?: number;
trust?: boolean;
description?: string;
includeTools?: string[];
excludeTools?: string[];
extensionName?: string;
oauth?: { /* OAuth 配置 */ };
authProviderType?: 'dynamic_discovery' | 'google_credentials' | 'service_account_impersonation';
targetAudience?: string;
targetServiceAccount?: string;
}>; // CLI 端管理的外部 MCP 服务器
agents?: Array<{
name: string;
description?: string;
tools?: string[];
systemPrompt?: string;
level?: string;
filePath?: string;
modelConfig?: {
model?: string;
temp?: number;
topP?: number;
};
runConfig?: {
maxTimeMinutes?: number;
maxTurns?: number;
};
color?: string;
}>; // 会话子代理配置
}
实现位置:packages/cli/src/nonInteractive/control/controllers/systemController.ts - handleInitialize()
返回值:
{
commands: string[]; // 支持的工具/命令
output_style: 'stream-json'; // 输出格式
capabilities: {
tools: string[]; // 可用工具列表
mcpServers: boolean; // 是否支持 MCP 服务器
hooks: boolean; // 是否支持 Hook
permissionControl: boolean; // 是否支持权限控制
};
model: string; // 当前模型
permissionMode: string; // 当前权限模式
agents?: string[]; // 支持的子代理
}
② interrupt(中断)
功能:中断当前正在执行的 AI 对话,触发中断回调
请求参数:
{
subtype: 'interrupt';
}
实现位置:packages/cli/src/nonInteractive/control/controllers/systemController.ts - handleInterrupt()
返回值:
null; // 无返回值,直接触发中断事件
行为:
- 设置
interrupted标志 - 触发
abortController.abort() - 发送
interrupt事件
③ set_model(设置模型)
功能:动态切换 AI 模型
请求参数:
{
subtype: 'set_model';
model: string; // 模型名称(如 "gemini-2.5-flash")
}
实现位置:packages/cli/src/nonInteractive/control/controllers/systemController.ts - handleSetModel()
返回值:
{
subtype: 'set_model';
model: string; // 新模型名称
}
行为:
- 验证模型名称有效性
- 保存旧模型(用于回滚)
- 更新当前模型
- 重新创建 Gemini 客户端
- 发送系统消息通知用户
- 失败时自动回滚
④ supported_commands(支持的命令)
功能:获取 CLI 支持的所有斜杠命令列表
请求参数:
{
subtype: 'supported_commands';
}
实现位置:packages/cli/src/nonInteractive/control/controllers/systemController.ts - handleSupportedCommands()
返回值:
{
commands: string[]; // 支持的命令名称列表(动态加载)
}
行为:动态从配置加载可用的斜杠命令
⑤ can_use_tool(工具权限检查)
功能:检查工具使用权限,支持权限验证和建议系统
请求参数:
{
subtype: 'can_use_tool';
tool_name: string; // 工具名称
tool_use_id: string; // 工具调用 ID
input: unknown; // 工具输入参数
permission_suggestions?: PermissionSuggestion[] | null; // 权限建议
blocked_path?: string | null; // 被阻塞的路径
}
实现位置:packages/cli/src/nonInteractive/control/controllers/permissionController.ts - handleCanUseTool()
返回值:
{
subtype: 'can_use_tool';
behavior: 'allow' | 'deny'; // 允许或拒绝
message?: string; // 拒绝原因
updatedInput?: unknown; // 修改后的输入
interrupt?: boolean; // 是否中断
}
决策逻辑:
- 检查工具注册表(已注册的工具自动允许)
- 根据权限模式决策:
yolo:全部允许auto-edit:安全操作自动允许plan:只读操作自动允许default:需要用户确认
- 调用用户回调(如果有)
- 超时或错误时默认拒绝
⑥ set_permission_mode(设置权限模式)
功能:动态设置权限模式
请求参数:
{
subtype: 'set_permission_mode';
mode: 'default' | 'plan' | 'auto-edit' | 'yolo';
}
实现位置:packages/cli/src/nonInteractive/control/controllers/permissionController.ts - handleSetPermissionMode()
返回值:
{
status: 'updated';
mode: PermissionMode; // 新的权限模式
}
行为:
- 验证模式有效性
- 更新
PermissionSystem的模式 - 发送系统消息通知用户
- 记录模式变更
权限模式说明:
default:默认模式,需要用户确认plan:计划模式,只允许只读操作auto-edit:自动编辑模式,安全操作自动允许yolo:完全信任模式,所有操作自动允许
⑦ mcp_server_status(MCP 服务器状态)
功能:获取 SDK 端 MCP 服务器状态
请求参数:
{
subtype: 'mcp_server_status';
}
实现位置:packages/cli/src/nonInteractive/control/controllers/sdkMcpController.ts - handleMcpStatus()
返回值:
{
subtype: 'mcp_server_status';
status: Record<string, string>; // 服务器名 → 状态映射
}
行为:返回所有 SDK MCP 服务器的连接状态
⑧ mcp_message(MCP 消息传递)
功能:在 CLI 和 SDK 之间路由 MCP 协议消息
请求参数:
{
subtype: 'mcp_message';
server_name: string; // MCP 服务器名称
message: {
jsonrpc?: string; // JSON-RPC 版本(如 "2.0")
method: string; // 方法名
params?: Record<string, unknown>; // 方法参数
id?: string | number | null; // 请求 ID
};
}
实现位置:packages/cli/src/nonInteractive/control/controllers/sdkMcpController.ts - handleMcpMessage()
返回值:
{
error: string | null; // 错误信息
mcp_response: {
jsonrpc: string;
result: Record<string, unknown>;
id: string | number;
};
}
行为:
- 查找或创建 MCP 客户端
- 转发消息到 MCP 服务器
- 返回响应或错误
⑧ hook_callback(Hook 回调)
功能:处理 Hook 回调(占位符实现)
请求参数:
{
subtype: 'hook_callback';
callback_id: string; // 回调 ID
input: unknown; // 回调输入
tool_use_id: string | null; // 工具使用 ID
}
实现位置:packages/cli/src/nonInteractive/control/controllers/hookController.ts - handleHookCallback()
返回值:
{
result: string; // "Hook callback processing not yet implemented"
callback_id: string;
}
状态:框架存在,但实际功能未实现
1.2 服务 API 能力(4 个域)
PermissionServiceAPI(权限服务)
方法列表:
-
buildPermissionSuggestions
- 功能:为工具确认对话框构建 UI 建议
- 参数:
confirmationDetails: ToolConfirmationDetails - 返回:
PermissionSuggestion[] | null - 位置:
permissionController.ts:246-356
-
getToolCallUpdateCallback
- 功能:获取监控工具调用状态更新的回调函数
- 返回:
(toolCalls: WaitingToolCall[]) => void - 用途:集成到 CoreToolScheduler
-
setCanUseToolCallback
- 功能:设置自定义工具权限回调
- 参数:
callback: CanUseToolCallback - 用途:允许外部自定义权限逻辑
SystemServiceAPI(系统服务)
方法列表:
- getControlCapabilities
- 功能:获取控制系统能力对象
- 返回:
Record<string, unknown> - 包含:commands, output_style, capabilities, model, permissionMode
McpServiceAPI(MCP 服务)
方法列表:
-
getMcpClient
- 功能:获取或创建 MCP 客户端(懒加载)
- 参数:
serverName: string - 返回:
Promise<{ client: Client; config: MCPServerConfig }>
-
listServers
- 功能:列出所有可用的 MCP 服务器
- 返回:
string[](服务器名称列表)
HookServiceAPI(Hook 服务)
方法列表:
- registerHookCallback
- 功能:注册钩子回调(占位符)
- 参数:
callback: unknown - 状态:框架存在,待实现
1.3 控制服务架构
三层架构
┌─────────────────────────────────────┐
│ ControlService (门面层) │
│ - 提供 domain-grouped APIs │
│ - PermissionServiceAPI │
│ - SystemServiceAPI │
│ - McpServiceAPI │
│ - HookServiceAPI │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ ControlDispatcher (路由层) │
│ - 控制请求路由 │
│ - 待处理请求管理 (Map) │
│ - 超时和取消处理 │
│ - 响应生成 │
└──────┬───────────────┬────────┬───────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ System │ │Permission│ │ SdkMcp │
│Controller│ │Controller│ │Controller│
└──────────┘ └──────────┘ └──────────┘
┌──────────┐
│ Hook │
│Controller│
└──────────┘
│
▼
┌──────────────────┐
│ BaseController │ (基类)
└──────────────────┘
2. SDK 端能力
2.1 控制请求发送
Query.sendControlRequest() 方法
功能:发送控制请求到 CLI
参数:
{
subtype: string; // 请求类型
data?: Record<string, unknown>; // 附加数据
options?: {
signal?: AbortSignal; // 取消信号
timeout?: number; // 超时时间(毫秒)
};
}
实现位置:packages/sdk-typescript/src/query/Query.ts
超时配置:
const DEFAULT_TIMEOUTS = {
canUseTool: 60000, // 工具权限:60秒
mcpRequest: 60000, // MCP 请求:60秒
controlRequest: 60000, // 控制请求:60秒
streamClose: 60000, // 流关闭:60秒
};
2.2 可发送的控制请求类型(9种)
控制请求枚举
enum ControlRequestType {
INITIALIZE = 'initialize',
INTERRUPT = 'interrupt',
SET_MODEL = 'set_model',
SUPPORTED_COMMANDS = 'supported_commands',
CAN_USE_TOOL = 'can_use_tool',
SET_PERMISSION_MODE = 'set_permission_mode',
MCP_MESSAGE = 'mcp_message',
MCP_SERVER_STATUS = 'mcp_server_status',
HOOK_CALLBACK = 'hook_callback',
}
SDK 提供的便捷方法
-
initialize()
- 发送初始化请求
- 配置 SDK MCP 服务器、外部 MCP 服务器、Agent
-
interrupt()
- 发送中断请求
- 取消当前操作
-
setModel(model)
- 切换 AI 模型
- 支持运行时动态切换
-
supportedCommands()
- 获取支持的命令列表
- 返回字符串数组
-
canUseTool(toolName, input)
- 检查工具权限
- 支持权限建议和超时
-
setPermissionMode(mode)
- 设置权限模式
- 支持 ‘default’, ‘plan’, ‘auto-edit’, ‘yolo’
-
mcpServerStatus()
- 获取 MCP 服务器状态
- 返回服务器状态映射
-
mcpMessage(serverName, message)
- 发送 MCP 消息
- 支持双向通信
2.3 控制响应处理
handleControlResponse() 方法
功能:处理来自 CLI 的控制响应
实现位置:packages/sdk-typescript/src/query/Query.ts
处理逻辑:
1. 根据 request_id 查找 pendingControlRequests
2. 清理定时器和回调监听器
3. 根据 subtype(success/error):
- success: resolve Promise
- error: reject Promise with error
响应格式:
成功响应:
{
subtype: 'success';
request_id: string;
response: unknown; // 具体响应数据
}
错误响应:
{
subtype: 'error';
request_id: string;
error: string | { message: string; [key: string]: unknown };
}
2.4 传输层能力
ProcessTransport 方法
write(message: string)
- 功能:发送控制请求到 CLI 进程
- 实现:通过 stdin 写入 JSON Lines 格式
- 错误处理:检查进程状态、写入权限
- 日志记录:记录写入操作和字节数
- 背压控制:检测缓冲区满时等待 drain 事件
readMessages()
- 功能:从 CLI 进程读取响应消息
- 实现:通过 stdout 读取 JSON Lines 流
- 解析:使用
parseJsonLinesStream解析消息 - 消息路由:根据消息类型分发
进程管理:
- 自动启动 CLI 子进程
- 自动关闭和清理
- 信号处理(SIGINT, SIGTERM)
- 错误恢复
2.5 SDK 消息路由
消息类型处理
| 消息类型 | 处理方法 |
|---|---|
control_request |
handleControlRequest() |
control_response |
handleControlResponse() |
control_cancel_request |
handleControlCancelRequest() |
| SDK 消息 | 传递到输出流 |
初始化流程
- 初始化 SDK MCP 服务器连接
- 发送
initialize请求到 CLI - 等待初始化完成
- 启动消息路由器
3. 类型定义清单
3.1 控制请求载荷(9种)
type ControlRequestPayload =
| CLIControlInitializeRequest // 初始化
| CLIControlInterruptRequest // 中断
| CLIControlSetModelRequest // 设置模型
| CLIControlSupportedCommandsRequest // 支持的命令
| CLIControlPermissionRequest // 权限检查
| CLIControlSetPermissionModeRequest // 设置权限模式
| CLIControlMcpMessageRequest // MCP 消息
| CLIControlMcpStatusRequest // MCP 状态
| CLIHookCallbackRequest // Hook 回调
3.2 控制响应(2种)
type ControlResponse =
| ControlResponse // 成功响应
| ControlErrorResponse; // 错误响应
3.3 配置类型
MCP 配置
SDKMcpServerConfig- SDK 端 MCP 服务器CLIMcpServerConfig- CLI 端 MCP 服务器MCPOAuthConfig- OAuth 配置AuthProviderType- 认证提供者类型
权限配置
PermissionMode- 权限模式枚举PermissionSuggestion- 权限建议ToolConfirmationDetails- 工具确认详情
子代理配置
SubagentConfig- 子代理配置ModelConfig- 模型配置RunConfig- 运行配置
4. 完整能力矩阵
4.1 控制请求能力矩阵
| # | 控制请求 | CLI 处理 | SDK 发送 | 权限控制 | MCP | Hook | 实现状态 |
|---|---|---|---|---|---|---|---|
| 1 | initialize | ✅ | ✅ | ❌ | ✅ | ⚠️ | 完整 |
| 2 | interrupt | ✅ | ✅ | ❌ | ❌ | ❌ | 完整 |
| 3 | set_model | ✅ | ✅ | ❌ | ❌ | ❌ | 完整 |
| 4 | supported_commands | ✅ | ✅ | ❌ | ❌ | ❌ | 完整 |
| 5 | can_use_tool | ✅ | ❌ | ✅ | ❌ | ❌ | 完整 |
| 6 | set_permission_mode | ✅ | ✅ | ✅ | ❌ | ❌ | 完整 |
| 7 | mcp_server_status | ✅ | ✅ | ❌ | ✅ | ❌ | 完整 |
| 8 | mcp_message | ✅ | ❌ | ❌ | ✅ | ❌ | 完整 |
| 9 | hook_callback | 🚧 | ❌ | ❌ | ❌ | 🚧 | 框架 |
4.2 架构能力矩阵
| 能力 | qwen-code | 实现复杂度 |
|---|---|---|
| 分层架构 | ✅ 3层(Service→Dispatcher→Controllers) | 复杂 |
| 状态管理 | ✅ ControlContext 共享状态 | 中等 |
| 请求路由 | ✅ 自动路由到对应 Controller | 简单 |
| 生命周期管理 | ✅ 超时、取消、清理 | 中等 |
| 双向通信 | ✅ CLI↔SDK 控制请求 | 复杂 |
| 错误处理 | ✅ 统一错误响应格式 | 简单 |
| 类型安全 | ✅ 完整 TypeScript 类型 | 中等 |
| 可扩展性 | ✅ 添加新 Controller 无需修改核心 | 中等 |
4.3 功能特性矩阵
权限系统特性
| 特性 | 状态 | 描述 |
|---|---|---|
| 4 种权限模式 | ✅ | default, plan, auto-edit, yolo |
| 工具注册表 | ✅ | 已注册工具自动允许 |
| 权限建议系统 | ✅ | 为不同工具类型生成 UI 建议 |
| 安全操作识别 | ✅ | 识别安全/只读操作 |
| 用户回调支持 | ✅ | 自定义权限逻辑 |
| 超时控制 | ✅ | 60秒超时,可配置 |
MCP 集成特性
| 特性 | 状态 | 描述 |
|---|---|---|
| SDK MCP 服务器 | ✅ | SDK 进程中的 MCP 服务器 |
| 外部 MCP 服务器 | ✅ | CLI 进程中的 MCP 服务器 |
| OAuth 支持 | ✅ | 支持 3 种认证方式 |
| 消息路由 | ✅ | 双向 MCP 消息传递 |
| 客户端缓存 | ✅ | 懒加载和缓存 MCP 客户端 |
| 服务器状态查询 | ✅ | 实时连接状态 |
系统控制特性
| 特性 | 状态 | 描述 |
|---|---|---|
| 模型切换 | ✅ | 运行时动态切换,带验证和回滚 |
| 中断控制 | ✅ | 立即中断当前操作 |
| 动态命令加载 | ✅ | 动态获取支持的斜杠命令 |
| 系统消息通知 | ✅ | 向用户发送系统事件通知 |
| Agent 配置 | ✅ | 支持会话子代理配置 |
5. 核心文件位置
5.1 CLI 端核心文件
packages/cli/src/nonInteractive/control/
├── ControlContext.ts # 控制上下文(共享状态)
├── ControlDispatcher.ts # 控制调度器(请求路由)
├── ControlService.ts # 控制服务(门面层)
├── controllers/
│ ├── BaseController.ts # 基础控制器
│ ├── SystemController.ts # 系统控制器
│ ├── PermissionController.ts # 权限控制器
│ ├── SdkMcpController.ts # MCP 控制器
│ └── HookController.ts # Hook 控制器
└── types/
└── serviceAPIs.ts # 服务 API 类型定义
5.2 SDK 端核心文件
packages/sdk-typescript/src/
├── query/Query.ts # 查询类(控制请求发送)
├── transport/
│ ├── ProcessTransport.ts # 进程传输层
│ └── Transport.ts # 传输接口
├── mcp/
│ ├── SdkControlServerTransport.ts # SDK MCP 服务器传输
│ └── ...
└── types/
├── protocol.ts # 协议类型定义
└── types.ts # 通用类型定义
6. 总结
6.1 功能统计
| 类别 | 数量 |
|---|---|
| 控制请求类型 | 9 种 |
| 服务 API 域 | 4 个(Permission/System/Mcp/Hook) |
| Controller 类 | 5 个(Base + 4个具体) |
| 权限模式 | 4 种 |
| 核心文件数 | 12 个 |
6.2 关键特性
- ✅ 完整的控制协议:9 种控制请求全部实现
- ✅ 分层架构:Service → Dispatcher → Controllers
- ✅ 权限系统:4 种模式 + 工具注册表 + 权限建议
- ✅ MCP 集成:SDK + 外部服务器 + OAuth 支持
- ✅ 双向通信:CLI ↔ SDK 控制请求
- ✅ 生命周期管理:超时、取消、清理
- ✅ 类型安全:完整的 TypeScript 类型定义
6.3 实现完整度
- 功能完整度:95%(只有 Hook 是占位符)
- 生产就绪度:高(已用于 qwen-code 生产环境)
- 可维护性:高(分层架构,职责清晰)
- 可扩展性:高(易于添加新功能)
更多推荐



所有评论(0)