Local Executor 本机委派
工具跨到本机后怎样返回
ExecutionHostRouter 决定工具交给哪个执行宿主。本机宿主完成能力调用并交回结果,Agent 继续组织后续执行。应沿请求和回执两条方向阅读,不能把本机能力调用理解成另一个企业 Agent loop。
Local File 架构族仍称 V4;独立的 Local File 协议版本与 local-files-v5 capability 已随 Desktop 协议 v3 删除,V4 就绪只看 localFileCapability。request/receipt 账本位于 Agent,Desktop Main 负责一次本机执行与对话级附件组装。绝对路径不出 Main,wire 使用 relativePath / attachmentId 等 path-free 字段。LE primitives 与普通文件 Local File 路径需要分开,Server session 与 Desktop session 的配对也是恢复时的边界条件。
本机原语收敛到 Skill 与 Local File(Desktop 协议 v3,钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db)
Agent ADR-0090 D1 与 Desktop ADR-0087 D1/D2 把 Agent 下发给 Desktop 的工具收敛为:readSkillFile、runSkillScript(官方 Skill 另有 runOfficialSkillScript)、Skill 管理四件套(list_skills / inspect_skill / prepare_skill_change / apply_skill_change)与 Local File V4 工具。readFile / writeFile / listDirectory / runBundledScript 从 SERVER_SUPPORTED_LOCAL_PRIMITIVE_SET 与 DESKTOP_LOCAL_EXECUTOR_PRIMITIVES 删除,durable 本机读工具只剩 readSkillFile;Desktop 侧同时删掉 shell / visionExtract 等从未由 Agent 下发的分支和 Full access / Trusted host User Skill 运行时。runSkillScript 是唯一脚本入口,入口 ABI 为 aida-json-file-v1 或 aida-argv-v1(Desktop ADR-0086),platforms 加入 linux。Desktop 删除面依据 ADR 与提交说明,未逐文件核对;Desktop Electron / E2E 未运行。
aida-agent·packages/agent/src/gateway/local-executor-schemas.tsL39–43 ·SERVER_SUPPORTED_LOCAL_PRIMITIVE_SET·e2adc9a3c325aida-agent·packages/tool-client/src/types/desktop-tools.tsL34–55 ·DESKTOP_LOCAL_EXECUTOR_PRIMITIVES·e2adc9a3c325aida-agent·packages/agent/src/shared/durable-local-execution.tsL37–39 ·DURABLE_LOCAL_READ_TOOL_NAMES·e2adc9a3c325aida-agent·docs/adr/0090-desktop-protocol-v3-and-retired-local-primitives.mdL17–19 ·readSkillFile·e2adc9a3c325aida-desktop·docs/adr/0087-local-capability-convergence-and-protocol-v3.mdL22–28 ·runSkillScript·4346d79eb364
交付端口移出门面(钉点 8eecd12081db)
Skills「另存为」的交付操作不再是 LocalExecutionGateway(钉点 Desktop 8eecd12081db 由 LocalExecutorService 改名,文件 local-executor-service.ts → local-execution-gateway.ts)的公开方法,而是收进一个只读的 deliveries 端口,只给 Main 启动恢复和 aida-local-executor:* IPC 用。行为不变,只是收窄了谁能调用。另:Desktop 的 AgentLoopHost 早在 91a25b75(2026-10-10,上一钉点之前)就已删除;本窗口只是让关停测试断言不再出现 agent-loop 关停项。
Skill 脚本:可准备 ≠ 可信,旧 root 效应冻结(钉点 Agent e2adc9a3c325 / Desktop 8eecd12081db)
canPrepareSkillScriptEntry:条目 ready,或原因是execution_untrusted/dependency_preparation_required/runtime_unavailable时,允许走到 Main 的准备检查并返回绑定的前置回执——不授予信任、不启动进程。用户答复后原 Work 可就同一已准入版本与输入范围重新准备,Main 重新核对信任、运行时、依赖和审批。Agent 与 Desktop(生成的合同副本)用同一函数(28a6ec920/9fdc200c)。- 旧 root 效应冻结:已有 C0 命令原样保留受理时的效应和摘要,答复或 Main 就绪刷新都不能给旧 root 加
execute_script;纠错沿用前驱的效应族与重试栅栏。 - 证据:
aida-agent·packages/tool-client/src/types/skill-script.tsL431–437 ·canPrepareSkillScriptEntry·e2adc9a3c325;aida-agent·packages/agent/src/runtime/README.mdL97–106 ·execution_untrusted·e2adc9a3c325;aida-desktop·apps/desktop/electron/local-executor/local-skill-catalog.tsL50–57 ·canPrepareSkillScriptEntry·4346d79eb364;aida-agent·packages/agent/src/runtime/work/run-work-effects.tsL4–32 ·Existing C0 commands·e2adc9a3c325;aida-agent·packages/agent/src/runtime/README.mdL108–118 ·Existing C0 commands·e2adc9a3c325
Runtime Work 挂起拉取、二次复核与产物执行证明(deliverRuntimeWorkSkill)
当 Work 在 Agent 侧挂起(work.status === 'suspended')等待本机 Skill、管理原语或 Plugin 工具时,Desktop Main 通过 deliverRuntimeWorkSkill 拉取并投递,不引入第二套模型循环或租约状态机:
- 绑定强校验:调用
queryPendingLocalReadRequest获取待办请求后,严格核对workBinding的rootRunId、carrierRunId、invocationId、skillExecutionPolicy、workStepRef(^model:[0-9]+:tool:0$)与effectRef。 - Plugin 派发前二次复核(
assertDispatchAllowed):在本地确认后、真正交由pluginRouter.settle执行前,Main 再次检查expiresAt未到期并重调queryPendingLocalReadRequest,比对canonicalJson(fresh.request.pluginToolCall)与workBinding完全未变,且重新验证assertPluginSkillSource。 - 本机产物执行证明(
executionProof):脚本生成的本地产物写入ArtifactRegistry(LocalArtifactRecord),其中executionProof(processTreeStopped: true、outputsValidated: true、observedAtMs)仅在整个进程树停止、输出校验通过且产物完成注册后由原执行器写入,作为原 O1 执行成功的唯一本机证据。
配对父子任务锁序与续接(Paired Parent / Child Continuation)
当父 Run 将子 Agent 作为工具调用(Agent-as-Tool)并涉及本机文件或工具挂起时,父子状态迁移遵守严格锁序与所有权证明(paired-child-continuation.ts):
- 防死锁固定锁序(
lockPairedRunsInTx):任何跨父子 Run 的状态或等待行迁移,必须在同一事务中先SELECT ... FOR UPDATE锁原 Parent 行,再锁 Child 行,然后才触碰任何 wait 或 effect 行。 - 持久化所有权白名单(
parsePairedChildOwnerMetadata):仅允许固定的 8 个字段(parentRunId、childRunId、parentInvocationId、childInvocationId、childAgentId、childAgentVersion、capabilityId、executorRef)落库,且严禁把瞬态租约 token(parentRunLeaseToken/childRunLeaseToken)写入持久化 owner 元数据。 - 透明转发幂等键(
transparentForwardKey):Child 恢复并产出结果后(ResumedChildRunResult),通过稳定的 insert-oncetransparentForwardKey向 Parent 转发,防止重复唤醒或重复注入工具结果。
本机工作台三轮实况与 Transcript 投影安全门禁(local-workbench-transcript)
以 local_workbench.spreadsheet_ops 的典型三轮执行为例(见视图 workbench-multiround-trace):
- Round 0(
readSkillFile)→ Round 1(runSkillScript):模型首轮调用readSkillFile挂起并由 Desktop Main 回传SKILL.md内容,经resumeOriginalToolRound零重调复跑后进入 Round 1 调用runSkillScript;Desktop 执行完脚本且进程树完全退出后写入ArtifactRegistry.executionProof并回传artifactCount。 - Round 2 投影安全门禁(
safeProjectionText/LOCAL_WORKBENCH_TRANSCRIPT_UNSAFE_PROJECTION):在捕获模型响应或提交轮次 Transcript 时,local-workbench-transcript.ts扫描凭证模式(credential)、原始异常栈(raw_exception)以及结构化值中的本机绝对/相对路径(fixed_local_path/relative_local_path)。一旦命中立即抛LocalWorkbenchTranscriptError('LOCAL_WORKBENCH_TRANSCRIPT_UNSAFE_PROJECTION')(fail-closed)。 - 脱敏审计与诊断(
reportProjectionRejection):WorkbenchWorkExecution捕获该错误后,仅将代码自有枚举(ruleId、fixedPathMatchKind、relativePathMatchKind、partType与位置索引)写入workbench_assistant_projection_rejected/workbench_transcript_projection_rejected审计事件,绝不把被拒文本、路径或原始结果写入审计日志。
Desktop 本机效应单次执行栅栏与崩溃补证(LocalEffectContinuationStore)
对于非幂等本机效应(runSkillScript、apply_skill_change,由 classifyLocalExecutorContinuation 标为 replaySafe: false),Desktop Main 通过 LocalEffectContinuationStore 保证至多执行一次、回执至少上送一次、崩溃绝不盲目重跑(见视图 local-effect-barrier):
- 三阶段持久化栅栏(
executing→receipt_pending→settled):调用前begin以identityScopeHash + recordId原子落盘executing(重复调用返回duplicate);子进程启动前经claimOriginalSkillDispatch将skillDispatch从unissued推进到issued(至多一次);执行完成后stageReceipt写入receipt_pending与 write-onceexecutionProof,服务端确认后acknowledge推进到settled。 - 崩溃恢复不自动重跑(
load):Desktop 重启恢复时,任何遗留在phase === 'executing'的记录都会被立即转换为phase: 'receipt_pending'且结果为outcome_unknown(「原脚本终结状态未确认,不能自动重跑。」),同时把未签发的skillDispatch置为closed。 - 原执行器晚到完成补证(
recordOriginalSkillCompletion→freezeSupplement→acknowledgeSupplement):若恢复已生成outcome_unknown,但原执行器随后完成并观察到processTreeStopped: true与outputsValidated: true,则写入 write-onceexecutionProof,并冻结补证摘要(freezeSupplement)上送服务端recordRuntimeWorkSupplementaryConclusion,确认后acknowledgeSupplement闭环。
证据与范围
aida-agent·packages/agent/src/execution-host/router.tsL50–80 ·ExecutionHostRouter·e2adc9a3c325aida-agent·docs/architecture/lifecycle-map.mdL42–98 ·e2adc9a3c325(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)aida-desktop·CONTEXT.mdL1388–1418 ·Dual session identity·4346d79eb364(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)aida-desktop·apps/desktop/shared/generated/protocol-version.tsL1–8 ·DESKTOP_PROTOCOL_VERSION·4346d79eb364
结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。
aida-desktop·apps/desktop/electron/local-executor/local-execution-gateway.tsL197–209 ·readonly deliveries·4346d79eb364aida-desktop·apps/desktop/electron/lifecycle/main-shutdown-coordinator.tsL96–113 ·coreScope.register('local-executor'·4346d79eb364