feat(multimodal): 内置多模态感知插件 + process.go 原生支持 tool message 多模态块

【新插件 internal/plugins/multimodal】
- see_picture(path): 读取本地图片/URL,base64 注入 image_url block,
  模型在下一轮 LLM 请求的 tool message 里直接看到图(1024×1024 图约 8500 token)。
  自动识别 MIME,限 3MB 防爆 context。
- see_video(path, frames): ffmpeg 提取关键帧,多帧作为 image_url block 注入。
  默认 4 帧,最大 10 帧,每帧限 2MB。
- listen(path): 读取音频文件,转为 audio_url block 注入,支持 mp3/wav/ogg/m4a。
  限 5MB。

【内核多模态 tool message 支持】
- agent/api 新增 ToolOutput 类型(为后续 handler 直接返回 blocks 预留)
- SDK 公共层新增 ContentBlock/ImageURL/AudioURL(OpenAI 多模态格式)
- IOManager 新增 SetToolBlocks/ConsumeToolBlocks(interface{} 避免循环依赖)
- PluginSDK.SetToolBlocks(blocks) 插件工具调用后注入 blocks
- ioAdapter 桥接 IOInjector.SetToolBlocks
- process.go 工具执行后消费 pending blocks → 追加到 tool message 的 Blocks 字段
  → MarshalJSON 输出 content 数组格式 → LLM 看到图/音频

【验证】
multimodal_see_picture 注入 1024×1024 PNG 后 llmsproxy 统计:
  prompt_tokens=44407(含 ~8500 image token),模型正确描述了图片内容。
This commit is contained in:
JianFeeeee
2026-08-27 08:39:21 +08:00
parent f0cdbdb030
commit b777322b95
8 changed files with 368 additions and 1 deletions

View File

@ -11,6 +11,7 @@ import (
"time"
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
sdkpub "gitcode.com/JianFeeeee/homeagent-sdk/sdk"
)
type toolCapture struct {
@ -415,6 +416,10 @@ func (c *injectCapture) InjectTextNoMemory(source, channel, text string) {
c.texts = append(c.texts, text)
c.mu.Unlock()
}
func (c *injectCapture) SetToolBlocks(blocks []sdkpub.ContentBlock) {
// 测试桩:忽略多模态块
}
func (c *injectCapture) InjectInputSync(source, channel, text string) string { return "" }
func (c *injectCapture) snapshot() []string {