From 69ff3089a40853b6e621367151f4fc88a2ea8f86 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sat, 12 Sep 2026 09:34:51 +0800 Subject: [PATCH] =?UTF-8?q?fix(mocksdk):=20=E8=A1=A5=E4=B8=8A=E6=BC=8F?= =?UTF-8?q?=E6=8E=89=E7=9A=84=20InjectInputSync=EF=BC=8C=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=E4=B8=8E=E5=85=AC=E5=85=B1=20SDK=20=E7=9A=84=E5=90=8C=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mocksdk 自己的注释立了规矩:「插件在 yaegi 下调得通的方法,编成 plugin.bin 后 必须也调得通,否则调试期与真实运行行为不一致」。但这个 mock 一直没有旧的三参数 `InjectInputSync`(`git log -S` 可证并非本次引入),而那正是通道类插件 (qq / a2a)完成「收到入站 → agent 处理 → 回复取回」闭环要调的方法: - 编译成 plugin.bin:能用(实现在模板里) - 在 yaegi 下调试:方法根本不存在 §九 早就点过 mocksdk 是最容易悄悄漂的一处(它没有任何代码对着编译,编译器抓不到; 上次漂的是 `Triple.Predicate` vs 公共 SDK 的 `Relation`)。 本次做的是**机械比对**而不是凭印象:抽出公共 SDK `IOInjector` 的 14 个方法名 与 mock 的方法集求差,差异恰好只有 `InjectInputSync` 一个,补上后差集为空。 mock 仍可编译,plugindev 测试全绿。 --- tools/plugindev/yaegi/mocksdk/plugin.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/plugindev/yaegi/mocksdk/plugin.go b/tools/plugindev/yaegi/mocksdk/plugin.go index 2af475b..cd25006 100644 --- a/tools/plugindev/yaegi/mocksdk/plugin.go +++ b/tools/plugindev/yaegi/mocksdk/plugin.go @@ -110,6 +110,11 @@ type IOInjector interface { InjectInterruptText(source, channel, text string) InjectText(source, channel, text string) InjectTextNoMemory(source, channel, text string) + // InjectInputSync 注入输入事件并同步等待 agent 回复(无回复时返回空串)。 + // 通道类插件(qq / a2a 等)靠它完成「收到入站 → agent 处理 → 回复取回」闭环, + // 而 mock 此前只有带 flags 的 InjectInputSyncOpts、没有这个零值糖—— + // 于是一个能在 plugin.bin 里编译通过、在 yaegi 下却调不通的方法就长住了。 + InjectInputSync(source, channel, text string) string // 1.1.0 媒体注入。与公共 SDK 同构:插件在 yaegi 下调得通的方法, // 编成 plugin.bin 后必须也调得通,否则调试期与真实运行行为不一致。 InjectInputMedia(source, channel, text string, blocks []ContentBlock) @@ -416,6 +421,11 @@ func (IOInjectorImpl) SetToolBlocks(blocks []ContentBlock) { // ---- 带 InjectOptions 的注入 ---- +func (IOInjectorImpl) InjectInputSync(source, channel, text string) string { + logf("inject_sync: source=%s channel=%s", source, channel) + return "" +} + func (IOInjectorImpl) InjectTextOpts(source, channel, text string, opts InjectOptions) { logf("inject_text_opts: source=%s channel=%s no_memory=%v policy=%s", source, channel, opts.NoMemory, opts.ContextPolicy) }