Plugin Run 投影 · call/receipt
广告、调用与回执是三次交接
listProjections 给出本机可用工具广告。Agent 的 buildPluginToolRuntime 把广告转换为本轮工具定义;被选中的调用再返回 Host 执行。广告只描述可调用能力,本身不是一次工具执行。
结果合同使用 structuredContent 和 ArtifactRef 表达结构化内容及产物引用。时序图只保留实际运行时消息,设计决策说明留在文字中,避免把 ADR 文档误读成参与者之间的消息。
插件视图双向闭环与本地工作台双轨(视图 plugin-view-and-batch)
对应交互图 /topics/plugin-run-projection/plugin-view-and-batch/(analyses/aidawork/plugin-run-projection/plugin-view-and-batch.sequence.json):
aida_plugin_open_view与视图只读隔离(assertWorkPluginView+readTaskView):- 模型调用合成工具
aida_plugin_open_view时,assertWorkPluginView(run-work-plugin-source.tsL76–99)强制校验:视图声明的stateToolId必须存在且sideEffect === 'read',所有actionToolIds的 schema 与 C0 广告投影完全一致;视图按钮只要求工具已声明且允许 UI origin(pluginToolAllowsOrigin(action, 'ui'),可复用普通工具操作,不再错误要求userActionOnly); - 服务端在
runtime_events中写入封存事实operationRef = 'plugin_view:<interactionId>'(含dedupKey = canonicalJsonSha256(sealed)),并创建plugin_view交互卡挂起载体; - Desktop 打开
PluginMainView面板后,前端通过PluginHost.readTaskView(binding)调callFromLocal(origin='ui')拉取视图初始数据:若插件含mainView.views,callFromLocal强制要求传入taskBinding且核对contractDigest、pluginVersion、toolId === view.stateToolId且effect === 'read'(相反,若 Agent 试图直接调stateToolId,会在invokeForRequest被PLUGIN_VIEW_ONLY拦截)。
- 模型调用合成工具
- 远端视图动作提交与血统反查(
readWorkPluginActionInTx):- 当用户在自定义视图里点击业务按钮时,并非由 Renderer 直接写库,而是作为
plugin_view交互卡的 answer 提交到InteractionKernel.settle; - 唤醒阶段调用
readWorkPluginActionInTx(run-work-plugin-interaction-source.tsL47–70):先调readOriginalViewCall从runtime_events和messages (role='assistant')中反查最初打开该视图的那次模型tool-call,验证buildPluginViewInteractionId(runId, toolCallId, invocationId) === interactionId; - 随后合成不可伪造的
SettledPluginAction(绑定{ interactionId, settlementId }),将检查点置为resume_point = 'plugin_action_ready',再生成stepId = settlementId的原生插件待办下发给 Desktop Host。
- 当用户在自定义视图里点击业务按钮时,并非由 Renderer 直接写库,而是作为
- Local Workbench 原生视图与本地回执闭环(
createLocalPluginProvider+LocalPluginTaskInteractions):- 本地工作台通过
createLocalPluginProvider(local-plugin-provider.tsL41–334)绑定不可变 Bundle 工具与视图:含actionToolIds的aida_plugin_open_view先在本地 Store 持久化待决交互事实并等待用户;仅展示视图(actionToolIds: [])不阻断 Run; - 原生视图经
LocalPluginTaskInteractions(local-plugin-task-interactions.tsL27–249)读写本地交互事实:拒绝答复强制校验精确{ kind: 'reject' }(活跃期重复拒绝幂等返回原提交,终态后报LOCAL_WORKBENCH_INTERACTION_UNAVAILABLE);接受答复经runtime.answer持久化answerFactId后,由PluginHost.executeLocal核对executionDigest并以local:executionId写入PluginCallJournal执行; - 旧协议中的
directory-output、directory-batch、manual-batch能力与 Host 目录批任务通道已随aida.mail切换一并从协议与 DesktopPluginHost移除。
- 本地工作台通过
证据与范围
aida-desktop·apps/desktop/electron/plugin-host/plugin-host.tsL659–689 ·listProjections·4346d79eb364aida-agent·packages/agent/src/gateway/delegated-desktop-capabilities.tsL57–87 ·buildPluginToolRuntime·e2adc9a3c325aida-plugins·docs/plugin-v2-contract.mdL1–44 ·a33ce3733365
结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。