fix(lua): 同步注入在 Lua 中明确报不可用(避免自锁)+ 文档/mock 同步

sdk.inject_input_sync / *_opts / inject_input_media_sync* 在 Lua 里必然自锁:
Lua 代码只在 Start/工具/阶段/输出/事件回调中执行,这些路径都持有 plg.mu,
而同步注入要等本轮回复(回复路径上的回调又需要同一把锁)。原实现会挂死
直到超时;现改为立即返回明确错误,并在中英文 PLUGIN_DEV 里标注不可用 +
指向 Go 插件/异步注入。mock sdk.lua(SDK 仓为事实源)同步为同样的错误语义。
新增 TestLuaSyncInjectUnavailable 钉住不挂死。
This commit is contained in:
HomeAgent Agent
2026-09-13 21:59:23 +08:00
parent 52127a3323
commit 6878f0126d
6 changed files with 92 additions and 40 deletions

View File

@ -648,11 +648,11 @@ Writable fields: `raw_message`, `llm_text`, `final_text`, `user_id`, `group_id`,
| `sdk.inject_interrupt(source, channel, text)` | Interrupt delivery |
| `sdk.inject_text_no_memory(source, channel, text)` | Deliver without memory computation |
| `sdk.inject_text_opts` / `sdk.inject_interrupt_opts(source, channel, text, opts)` | Delivery with flags; `opts = { no_memory=bool, context_policy="none"|"prune", cleaner_name=string, priority="L1".."L3" }` |
| `sdk.inject_input_sync(source, channel, text)` | Inject synchronously and wait for this turn's reply; returns `(reply, err)`, reply is nil when there is none |
| `sdk.inject_input_sync_opts(source, channel, text, opts)` | Same, with flags |
| `sdk.inject_input_sync(source, channel, text)` | ⚠️ **Unavailable in Lua**: always returns `(nil, err)`. It waits for this turn's reply while a Lua callback holds the plugin lock, so it would self-deadlock. Use a Go plugin for synchronous waits, or the async injectors below |
| `sdk.inject_input_sync_opts(source, channel, text, opts)` | Same (unavailable) |
| `sdk.inject_input_media(source, channel, text, blocks)` | Inject text + multimodal content blocks |
| `sdk.inject_input_media_opts(source, channel, text, blocks, opts)` | Same, with flags |
| `sdk.inject_input_media_sync` / `..._sync_opts(...)` | Synchronous media injection; returns `(reply, err)` |
| `sdk.inject_input_media_sync` / `..._sync_opts(...)` | ⚠️ **Unavailable in Lua** (same as `inject_input_sync`) |
| `sdk.inject_interrupt_media(source, channel, text, blocks)` | Interrupt delivery with media |
| `sdk.inject_interrupt_media_opts(source, channel, text, blocks, opts)` | Same, with flags |
| `sdk.set_tool_blocks(blocks)` | Set multimodal blocks carried by the next tool message (lets the model see images / hear audio) |