12 KiB
Boss 执行底座抽象层重构设计
背景
当前 Boss 已经有一条真实可运行的执行链:
Web / Android -> /api/v1/projects/[projectId]/messagesboss-master-agent.tsmaster-agent task queuelocal-agent/server.mjscodex exec resume/api/v1/master-agent/tasks/[taskId]/complete- 回写消息账本与聚合投影
同时,Boss 已经具备这些上层业务能力:
- 多租户
- 会话 / 群聊 / 审批
- 设备导入
- 主控切换
- 提示词 / 记忆
- 附件与分析
但当前执行链存在一个结构性问题:
- 执行逻辑主要分散在:
src/lib/boss-master-agent.tslocal-agent/server.mjssrc/app/api/v1/projects/[projectId]/messages/route.tssrc/app/api/v1/master-agent/tasks/[taskId]/complete/route.ts
- 不同执行后端的职责边界不够清晰:
master-codex-nodeopenai-apialiyun-qwen-api
- 审批、权限、提示词组装、远程执行适配等能力,已经在逻辑上出现,但还没有明确的稳定抽象层。
- 后续如果要接入:
claw-codeoh-my-codex就会面临“边接边重构”的高风险。
因此,Boss 必须先完成一次执行底座抽象层重构,把现有生产主链保留下来,同时把执行层拆成稳定接口。
目标
本轮目标不是替换任何现有执行后端,而是:
- 在 Boss 内部定义稳定的执行抽象层
- 把现有执行主链映射到这些抽象层上
- 保持当前生产主链继续可用
- 为后续接入:
ClawBackendAdapterOmxTeamBackendAdapter做准备
非目标
本轮不做:
- 不直接接入
claw-code - 不直接接入
oh-my-codex - 不替换当前
local-agent -> codex exec resume主链 - 不改 Web / Android 的产品交互
- 不修改群聊、审批、设备导入的业务语义
- 不做运行时协议大迁移
设计总览
本轮会在 Boss 现有业务层与现有执行实现之间,增加一层稳定接口:
Boss Product / Domain Layer
-> Execution Foundation Layer
-> Current Backends
-> MasterCodexNodeBackend
-> OpenAIBackend
-> AliyunQwenBackend
-> BossNativeOrchestrator
这层抽象的目标不是把系统复杂化,而是让当前已经存在的能力有清晰边界,避免后续所有能力都继续堆在 boss-master-agent.ts 和 local-agent/server.mjs 里。
需要新增的抽象
1. ExecutionBackend
职责:
- 统一描述“谁来执行一个实际任务”
适用对象:
- 主 Agent 单聊回复
- 普通线程单聊回复
- 附件分析
- 未来
claw-code单次执行
建议接口:
interface ExecutionBackend {
backendId: string;
canHandle(input: ExecutionRequest): Promise<boolean> | boolean;
execute(input: ExecutionRequest): Promise<ExecutionQueuedResult | ExecutionImmediateResult>;
describe(input: ExecutionRequest): Promise<ExecutionBackendDescription>;
}
说明:
- 当前阶段不强制所有 backend 都支持
cancel/resume - 先统一最核心的
canHandle + execute + describe
当前映射:
MasterCodexNodeBackendOpenAIBackendAliyunQwenBackend
2. ExecutionBackendSelector
职责:
- 根据当前任务上下文选择执行后端
必须考虑:
- 当前主控身份
- 当前对话模型 / 推理强度覆盖
- 当前后端健康状态
- 是否允许回退到备用链
当前映射来源:
getMasterAgentRuntimeAccountupdateAiAccountHealthresolveMasterAgentExecutionConfig
说明:
- 这层只负责“选择谁执行”,不负责组装 prompt,也不负责审批和业务决策
- 运行时选择语义应明确为:
ready primary优先- 否则按
aliyun_qwen -> openai -> master_codex_node顺序回退 - 如果没有任何 ready backend,再回 primary 兜底
- 同一 provider 下如果存在多个账号,只要其中任一账号
ready,该 backend 就视为可选
3. SessionRuntime
职责:
- 统一描述一次执行会话的运行态
当前 Boss 里已经隐式存在这些语义:
- queued
- running
- completed
- failed
- timeout
- retry-waiting
本轮不需要引入重型 session store,但要统一成明确结构。
建议接口:
interface SessionRuntime {
create(input: RuntimeSessionCreateInput): Promise<RuntimeSessionRecord>;
markRunning(sessionId: string): Promise<void>;
markCompleted(sessionId: string, payload: RuntimeCompletionPayload): Promise<void>;
markFailed(sessionId: string, error: RuntimeFailurePayload): Promise<void>;
get(sessionId: string): Promise<RuntimeSessionRecord | null>;
}
说明:
- 当前底层仍可继续落在
boss-state.json - 本轮重点是统一语义,而不是换存储
4. PermissionPolicy
职责:
- 统一描述执行权限与审批门槛
当前 Boss 已经有这些隐式能力:
approval_required- 群聊是否可直接协作
- 群聊是否允许直接下发
- 设备写接口鉴权
这层需要明确回答:
- 当前任务是否允许直接执行
- 是否必须先确认
- 允许哪些工具类型
- 是否允许跨线程直接对话
建议接口:
interface PermissionPolicy {
evaluate(input: PermissionCheckInput): Promise<PermissionCheckResult>;
}
其中 PermissionCheckResult 至少包含:
allowedrequiresApprovalreasontoolPolicycollaborationPolicy
5. ToolRegistry
职责:
- 统一声明 Boss 可以下发和使用的工具能力
当前不要求真正把工具全部重构出来,但必须定义 registry 层,避免工具能力继续散落在多个 backend 分支里。
建议接口:
interface ToolRegistry {
list(): Promise<ToolDefinition[]>;
get(toolName: string): Promise<ToolDefinition | null>;
}
说明:
- 本轮可以先只注册最基础的执行工具描述
- 先不追求完整 MCP / plugin 化
6. PromptAssembler
职责:
- 统一组装主 Agent 和线程执行时真正输入模型/执行引擎的内容
必须覆盖:
- 管理员全局主提示词
- 用户私有主提示词
- 当前对话附加提示词
- 用户通用记忆
- 项目记忆
- 当前运行时上下文
- 当前消息
说明:
- 当前已有相关逻辑在
resolveMasterAgentExecutionConfig和buildMasterAgentExecutionPrompt - 本轮要把它从 backend 逻辑里抽出来,变成独立模块
7. MemoryResolver
职责:
- 从用户记忆与项目记忆中选出当前真正相关的那一批
这层与 PromptAssembler 协作:
MemoryResolver负责挑选PromptAssembler负责拼装
8. RemoteRuntimeAdapter
职责:
- 统一连接设备上的远程执行能力
当前来源:
local-agent -> codex exec resume
未来来源:
claw remote runtimeomx team runtime
建议接口:
interface RemoteRuntimeAdapter {
claimTask(input: RemoteTaskClaimInput): Promise<RemoteClaimResult>;
executeTask(input: RemoteTaskExecutionInput): Promise<RemoteExecutionResult>;
completeTask(input: RemoteTaskCompletionInput): Promise<void>;
health(): Promise<RemoteRuntimeHealth>;
}
说明:
- 当前本轮不改变
local-agentAPI 主链 - 只是让它开始按 adapter 视角组织
9. OrchestrationBackend
职责:
- 统一描述多线程 / 多 worker / 群聊分发级别的编排能力
当前来源:
- Boss 自己已有的群聊 dispatch / approval / execution 逻辑
未来候选:
BossNativeOrchestratorOmxTeamBackendAdapter
说明:
- 这层只负责编排,不负责底层单次执行
- 与
ExecutionBackend明确分层
当前代码的映射关系
1. 现有保留不动的主链
这些主链行为本轮必须保持不变:
POST /api/v1/projects/[projectId]/messagesmaster-agent单聊快速入队 + 异步回流- 普通线程单聊
conversation_reply - 群聊
dispatch_execution /api/v1/master-agent/tasks/claim/api/v1/master-agent/tasks/[taskId]/completelocal-agent的codex exec resume
2. 主要重构落点
首批落点文件预计包括:
src/lib/boss-master-agent.tssrc/lib/boss-data.tslocal-agent/server.mjssrc/app/api/v1/projects/[projectId]/messages/route.tssrc/app/api/v1/master-agent/tasks/[taskId]/complete/route.ts
新增模块建议集中放在:
src/lib/execution/
建议初始文件:
src/lib/execution/types.tssrc/lib/execution/execution-backend.tssrc/lib/execution/backend-selector.tssrc/lib/execution/prompt-assembler.tssrc/lib/execution/memory-resolver.tssrc/lib/execution/permission-policy.tssrc/lib/execution/tool-registry.tssrc/lib/execution/remote-runtime-adapter.tssrc/lib/execution/orchestration-backend.ts
3. 适配策略
本轮不要求一次性把所有旧逻辑迁完。
建议策略:
- 先新增抽象层与默认实现
- 先让
master-agent单聊走新抽象 - 再把普通线程单聊映射进去
- 再把群聊 dispatch 的底层执行链映射进去
也就是说:
- 先平移,不先改行为
数据与状态设计
1. 执行请求
建议定义统一执行输入:
type ExecutionRequestKind =
| "master_agent_reply"
| "thread_reply"
| "dispatch_execution"
| "attachment_analysis";
interface ExecutionRequest {
kind: ExecutionRequestKind;
projectId: string;
requestMessageId: string;
requestedByAccount?: string;
requestedByLabel?: string;
taskId?: string;
targetThreadId?: string;
targetProjectId?: string;
body: string;
modelOverride?: string;
reasoningEffortOverride?: "low" | "medium" | "high";
}
2. 执行结果
建议统一执行结果:
type ExecutionResultStatus = "queued" | "running" | "completed" | "failed";
interface ExecutionQueuedResult {
status: "queued" | "running";
taskId: string;
backendId: string;
sessionId?: string;
}
interface ExecutionImmediateResult {
status: "completed" | "failed";
backendId: string;
output?: string;
error?: string;
}
3. 权限结果
interface PermissionCheckResult {
allowed: boolean;
requiresApproval: boolean;
reason?: string;
toolPolicy: {
allowedTools: string[];
deniedTools: string[];
};
collaborationPolicy: {
mode: "development" | "approval_required";
canDispatchDirectly: boolean;
canCrossThreadTalk: boolean;
};
}
分期落地
Phase 1:抽象定义 + 默认实现
输出:
- 所有接口定义
- 当前 Boss 原生执行链的默认实现
要求:
- 行为不变
- 现有测试继续通过
Phase 2:主 Agent 单聊迁移到新抽象
输出:
master-agent单聊通过ExecutionBackendSelector + PromptAssembler + PermissionPolicy
要求:
- 前台行为不变
- 仍然快速入队 + 异步回流
Phase 3:普通线程与群聊底层执行迁移
输出:
- 普通线程单聊
- 群聊 dispatch execution
要求:
- 不破坏 approval_required
- 不破坏群聊修复成员主链
Phase 4:为外部 adapter 预留接入点
输出:
ClawBackendAdapter所需 contract readyOmxTeamBackendAdapter所需 contract ready
本轮仍然不要求实际接入。
风险
1. 结构重构风险
如果一口气把所有旧逻辑迁完,极容易破坏:
- 主 Agent 单聊
- 普通线程回复
- 群聊 dispatch
- 设备导入
因此必须采用:
- 先定义抽象
- 再做行为等价迁移
2. 语义混淆风险
最大的风险不是代码量,而是把两类后端混在一起:
ExecutionBackendOrchestrationBackend
这两类必须严格分层。
3. 文档和实现偏离风险
如果文档只写“以后会有抽象层”,但实现不跟进,后面再接 claw-code 和 oh-my-codex 时仍然会重新失控。
因此本 spec 的验收必须以“接口和默认实现真正落地”为准。
验收标准
只有满足下面条件,才算这轮抽象层重构设计正确:
- Boss 现有生产主链不被替换
master-agent、普通线程、群聊 dispatch 都能映射到统一执行抽象- 提示词、记忆、权限、远程执行不再继续散在单个大文件里
- 单线程执行与多线程编排分层明确
- 后续接
claw-code与oh-my-codex时,不需要再先重做 Boss 主链
下一步
这份 spec 之后,下一份实现计划建议拆成 4 个任务:
- 抽
ExecutionBackend / ExecutionBackendSelector - 抽
PromptAssembler / MemoryResolver - 抽
PermissionPolicy / ToolRegistry - 抽
RemoteRuntimeAdapter / OrchestrationBackend
只有这 4 步完成后,才建议开始 ClawBackendAdapter 的最小接入设计。