メインコンテンツまでスキップ

Agent 引擎概览

Elftia 的 Agent 系统基于多引擎分发架构EngineDispatcher 作为统一的请求分发器,根据 EngineType 将请求路由到对应的引擎实现。每个引擎实现 IEngine 接口,封装不同的后端服务。

架构图

graph TB
Router["AgentRouter / MagiService"] --> Dispatcher["EngineDispatcher"]

Dispatcher --> TinyElf["TinyElfEngine<br/>tinyelf"]
Dispatcher --> ClaudeSdk["ClaudeSdkEngine<br/>claude-sdk"]
Dispatcher --> CliRunner["CliRunnerEngine<br/>cli"]
Dispatcher --> Chat["ChatEngine<br/>chat"]
Dispatcher --> STChat["STChatEngine<br/>st-chat"]
Dispatcher --> Api["ApiEngine<br/>api"]

TinyElf --> TinyLoop["TinyElfAgentLoop<br/>工具调用循环"]
TinyElf --> ToolReg["ToolRegistry<br/>工具注册表"]
TinyElf --> LLMAdapter["TinyElfLLMAdapter<br/>LLM 适配器"]

ClaudeSdk --> AgentSvc["AgentService<br/>Claude Agent SDK"]
ClaudeSdk --> Proxy["AgentProxyServer<br/>HTTP 代理"]

CliRunner --> Supervisor["ProcessSupervisor<br/>进程管理"]

Chat --> Pipeline["ChatCompletionPipeline<br/>聊天管线"]

IEngine 接口

所有引擎必须实现 IEngine 接口:

interface IEngine {
readonly engineType: EngineType;
startSession(ctx: EngineSessionContext): Promise<void>;
resumeSession(ctx: EngineSessionContext): Promise<void>;
interrupt(dbSessionId: string): Promise<boolean>;
isActive(dbSessionId: string): boolean;
reloadMcpForAllActive?(): Promise<void>;
}
方法说明
startSession启动新会话(保存用户消息,运行引擎循环)
resumeSession在已有会话上继续对话
interrupt中断活跃会话,返回是否成功
isActive检查会话是否正在运行
reloadMcpForAllActive热重载所有活跃会话的 MCP 工具(可选)

EngineSessionContext

所有引擎共享同一个会话上下文结构体。每个引擎按需使用其中的字段:

interface EngineSessionContext {
dbSessionId: string; // 数据库会话 ID
session: ChatSession; // 完整会话记录
sender: WebContents; // Electron IPC 发送器
prompt: string; // 用户消息
attachments?: Array<...>; // 多模态附件
providerId?: string; // LLM 提供商 ID
model?: string; // 模型 ID(v89+ 为裸 SDK id)
/**
* v89+:CLI 后端绑定(来自 chat_sessions.cliBackend 列)。
* 'claude-code' 走 ClaudeSdkEngine + AgentProxyServer.passThrough;
* 'codex' / 'gemini-cli' 走 CliRunnerEngine。
*/
cliBackend?: 'claude-code' | 'codex' | 'gemini-cli' | null;
/**
* v89+:1M-context 偏好(来自 chat_sessions.useExtendedContext 列)。
* Engines / AgentProxyServer / TransformerChainExecutor 据此决定
* 是否注入 'context-1m-2025-08-07' 到 anthropic_beta。
*/
useExtendedContext?: boolean;
engineConfig?: EngineConfig; // 引擎特定配置
projectPath?: string; // 项目路径
agentId?: string; // Agent ID

// Chat 引擎专用
systemPrompt?: string;
parentId?: string | null;
thinkingLevel?: string;
searchOrchestration?: PipelineSearchConfig;
mcpConfig?: PipelineMcpConfig;

// Magi/Agent 引擎专用
providerEnv?: Record<string, string>;
onSessionEnd?: () => void;
isOfficialProvider?: boolean;
customAgentOptions?: { ... };
permissionMode?: string;
channelSource?: string;
channelId?: string;
channelSenderId?: string;
channelUserPermissions?: { canUseTool: boolean; requireConfirmation: boolean };
}

EngineDispatcher

EngineDispatcher 是引擎注册和分发的核心:

class EngineDispatcher {
private engines = new Map<EngineType, IEngine>();

registerEngine(engine: IEngine): void;
getEngine(type: EngineType): IEngine;
hasEngine(type: EngineType): boolean;
dispatch(type: EngineType, ctx: EngineSessionContext): Promise<void>;
resume(type: EngineType, ctx: EngineSessionContext): Promise<void>;
interrupt(dbSessionId: string): Promise<boolean>;
reloadMcpForAllActive(): Promise<void>;
getEngineInfos(): EngineInfo[];
}

引擎注册

引擎在 packages/desktop/app/main/index.ts 中注册:

const dispatcher = new EngineDispatcher();
dispatcher.registerEngine(new TinyElfEngine(...));
dispatcher.registerEngine(new ClaudeSdkEngine(...));
dispatcher.registerEngine(new CliRunnerEngine(getProcessSupervisor(), db, logger));
dispatcher.registerEngine(new ChatEngine(...));
dispatcher.registerEngine(new STChatEngine(...));
dispatcher.registerEngine(new ApiEngine(...));

中断机制

interrupt() 方法遍历所有引擎,找到拥有目标会话的引擎并中断:

async interrupt(dbSessionId: string): Promise<boolean> {
for (const engine of this.engines.values()) {
if (engine.isActive(dbSessionId)) {
return engine.interrupt(dbSessionId);
}
}
return false;
}

引擎类型注册表

EngineType后端服务活跃会话追踪
tinyelfTinyElfEngine内置 Agent 循环Map<string, ActiveTinyElfSession>
claude-sdkClaudeSdkEngineAgentService (SDK)AgentService 内部管理
cliCliRunnerEngineProcessSupervisorMap<string, ActiveCliSession>
chatChatEngineChatCompletionPipeline内部 Map
st-chatSTChatEngineCompletionService内部 Map
apiApiEngineCompletionService无状态

活跃会话追踪

TinyElf 引擎使用 ActiveTinyElfSession 追踪每个活跃会话的状态:

interface ActiveTinyElfSession {
dbSessionId: string;
projectPath: string;
abortController: AbortController;
parentMessageId?: string;
lastAssistantMessageId?: string;
directMcpConnections?: Array<...>;
hookExecutor?: HookExecutor;
sdkDualWrite?: {
sdkSessionId: string;
lastUuid: string;
seqNum: number;
};
subagentManager?: SubagentManager;
}

IPC 事件

引擎通过 sender.send('agent:event', ...) 向渲染进程发送事件:

事件类型载荷说明
init{ sessionId, systemInfo }会话初始化
sessionCreated{ sessionId }会话创建完成
userMessage{ sessionId, message }用户消息已保存
streamDelta{ sessionId, delta }流式文本/思维增量
toolCallStart{ sessionId, block }工具调用开始
toolCallEnd{ sessionId, block, status }工具调用完成
assistantMessage{ sessionId, message }助手消息已保存
permissionRequest{ sessionId, requestId, toolName, input }权限确认请求
result{ sessionId, stats }执行统计结果
complete{ sessionId }会话完成
error{ sessionId, error }错误事件
retry{ sessionId, retry }API 重试通知
processing{ sessionId, message }处理中状态

关键文件

文件路径说明
IEngine 接口services/agent-core/engine/types.ts引擎接口和上下文定义
EngineDispatcherservices/agent-core/engine/EngineDispatcher.ts引擎注册和分发
模块入口services/agent-core/engine/index.ts所有引擎的导出
TinyElfEngineservices/agent-core/engine/tinyelf/TinyElfEngine.tsTinyElf 引擎实现
ClaudeSdkEngineservices/agent-core/engine/ClaudeSdkEngine.tsClaude SDK 引擎
CliRunnerEngineservices/agent-core/engine/cli/CliRunnerEngine.tsCLI 引擎
ChatEngineservices/agent-core/engine/ChatEngine.ts聊天引擎
STChatEngineservices/agent-core/engine/STChatEngine.ts单轮聊天引擎
ApiEngineservices/agent-core/engine/ApiEngine.tsAPI 引擎
EngineType 定义@shared/contracts/elftia-agent-types.ts类型定义

所有路径相对于 packages/desktop/app/main/

扩展点

  • 新增引擎:实现 IEngine 接口 + 在 EngineDispatcher 注册 + 添加 EngineType
  • 新增 IPC 事件:在引擎的回调中通过 sender.send() 发送
  • MCP 热重载:实现 reloadMcpForAllActive() 方法

相关模块

模块路径关系
AgentRouterservices/routers/AgentRouter.ts接收 IPC 调用 dispatcher
MagiServiceservices/agent-core/magi/MagiService.ts高层编排,选择引擎
CompletionServiceservices/capabilities/llm/completion/CompletionService.tsLLM API 调用
AgentServiceservices/agent-core/agent/AgentService.tsClaude SDK 会话管理