mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 17:38:10 +00:00
主仓库: - 修复 4 份英文文档语言切换链接指向错误 (../zh/ → ../en/) - ARCHITECTURE.md 标题 "三种加载方式" → "四种加载方式" (实际表格4行) - PLUGIN_DEV.md 示例表: 添加 webfetch, 移除不存在的 luaplugintest/testlua - PLUGIN_DEV.md 代码示例: InjectInput/InjectInterrupt → InjectText/InjectInterruptText - PLUGIN_DEV.md 代码示例: Memory/Knowledge/LLM/Events 接口签名修正 - PLUGIN_DEV.md .hmap 内容统一, plugindev 编译去除 .exe 后缀 SDK 仓库: - Plugin.Start(sdk *PluginSDK) 接口签名改为指针 - 方法表重写: 移除 CallLLM/QueryKnowledge/SetMemory 等不存在方法 - IOInjector 参数顺序修正为 (source, channel, text) - 删除虚构 SDKConfig, 替换为实际 New() 构造函数签名 - .hmap 内容描述一致化 修正前一次会话中的 QQ/Bili 插件问题: - qq napcat() 超时, fetchBotInfo 竞态, handleWebhook 同步阻塞 - bili CDN 直连失败, 添加 HTTP_PROXY 代理
185 lines
5.0 KiB
Go
185 lines
5.0 KiB
Go
package sdk
|
|
|
|
import (
|
|
"log"
|
|
|
|
pubsdk "gitcode.com/JianFeeeee/homeagent-sdk/sdk"
|
|
agentIO "gitcode.com/JianFeeeee/HomeAgent/internal/agent/io"
|
|
"gitcode.com/JianFeeeee/HomeAgent/internal/events"
|
|
)
|
|
|
|
// SDKVersion 是对外 SDK 版本号,与核心 meta.Version 保持一致。
|
|
var SDKVersion = pubsdk.SDKVersion
|
|
|
|
type Plugin interface {
|
|
Name() string
|
|
Start(sdk *PluginSDK) error
|
|
Stop() error
|
|
}
|
|
|
|
type ToolHandler = pubsdk.ToolHandler
|
|
type StageHandler = pubsdk.StageHandler
|
|
|
|
type Stage = pubsdk.Stage
|
|
|
|
const (
|
|
StageOnInput = pubsdk.StageOnInput
|
|
StagePreAction = pubsdk.StagePreAction
|
|
StagePostAction = pubsdk.StagePostAction
|
|
StageBeforeToolcall = pubsdk.StageBeforeToolcall
|
|
StageAfterToolcall = pubsdk.StageAfterToolcall
|
|
StageBeforeOutput = pubsdk.StageBeforeOutput
|
|
StageAfterOutput = pubsdk.StageAfterOutput
|
|
)
|
|
|
|
type StageContext = pubsdk.StageContext
|
|
type MemItem = pubsdk.MemItem
|
|
type ToolCall = pubsdk.ToolCall
|
|
type ToolResult = pubsdk.ToolResult
|
|
type ToolDef = pubsdk.ToolDef
|
|
type IOInjector = pubsdk.IOInjector
|
|
type ToolRegistrar = pubsdk.ToolRegistrar
|
|
type StageRegistrar = pubsdk.StageRegistrar
|
|
type StageScope = pubsdk.StageScope
|
|
|
|
const (
|
|
StageScopeGlobal = pubsdk.StageScopeGlobal
|
|
StageScopeOwnTools = pubsdk.StageScopeOwnTools
|
|
)
|
|
type APIRegistrar = pubsdk.APIRegistrar
|
|
type OutputChannelRegistrar = pubsdk.OutputChannelRegistrar
|
|
|
|
type PluginSDK struct {
|
|
*pubsdk.PluginSDK
|
|
iom *agentIO.IOManager
|
|
eventBus *events.Bus
|
|
logger *log.Logger
|
|
}
|
|
|
|
// ioAdapter 桥接 IOManager 到公共 SDK 的 IOInjector 接口,
|
|
// 确保外部插件通过 s.InjectText() 等方法的调用能被路由到内核 IO 层。
|
|
type ioAdapter struct{ iom *agentIO.IOManager }
|
|
|
|
func (a ioAdapter) InjectInterruptText(source, channel, text string) {
|
|
if a.iom != nil {
|
|
a.iom.InjectInterrupt(source, channel, map[string]interface{}{"type": "text", "content": text})
|
|
}
|
|
}
|
|
|
|
func (a ioAdapter) InjectText(source, channel, text string) {
|
|
if a.iom != nil {
|
|
a.iom.InjectInputTo(source, channel, "text", map[string]interface{}{"content": text})
|
|
}
|
|
}
|
|
|
|
func (a ioAdapter) InjectTextNoMemory(source, channel, text string) {
|
|
if a.iom != nil {
|
|
a.iom.InjectInputTo(source, channel, "text", map[string]interface{}{"content": text, "no_memory": true})
|
|
}
|
|
}
|
|
|
|
// SDKConfig holds all dependencies for creating a PluginSDK.
|
|
type SDKConfig struct {
|
|
IOManager *agentIO.IOManager
|
|
EventBus *events.Bus
|
|
Memory MemoryAPI
|
|
TextMemory TextMemoryAPI
|
|
DocMemory DocMemoryAPI
|
|
Knowledge KnowledgeAPI
|
|
LLM LLMAPI
|
|
Settings SettingsAPI
|
|
RegTool ToolRegistrar
|
|
RegStage StageRegistrar
|
|
RegAPI APIRegistrar
|
|
RegOutput OutputChannelRegistrar
|
|
}
|
|
|
|
func New(name string, cfg SDKConfig) *PluginSDK {
|
|
base := pubsdk.New(name, cfg.Settings, cfg.RegTool, cfg.RegStage, cfg.RegAPI, cfg.RegOutput)
|
|
if cfg.IOManager != nil {
|
|
base.SetIOInjector(ioAdapter{iom: cfg.IOManager})
|
|
}
|
|
base.SetMemoryAPI(cfg.Memory)
|
|
base.SetTextMemoryAPI(cfg.TextMemory)
|
|
base.SetDocMemoryAPI(cfg.DocMemory)
|
|
base.SetKnowledgeAPI(cfg.Knowledge)
|
|
base.SetLLMAPI(cfg.LLM)
|
|
return &PluginSDK{
|
|
PluginSDK: base,
|
|
iom: cfg.IOManager,
|
|
eventBus: cfg.EventBus,
|
|
logger: log.Default(),
|
|
}
|
|
}
|
|
|
|
func (s *PluginSDK) InjectInput(source, channel, eventType string, payload map[string]interface{}) {
|
|
if s.iom != nil {
|
|
s.iom.InjectInputTo(source, channel, eventType, payload)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSDK) InjectInputSync(source, channel, eventType string, payload map[string]interface{}) *agentIO.OutputEvent {
|
|
if s.iom != nil {
|
|
return s.iom.InjectInputSyncTo(source, channel, eventType, payload)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *PluginSDK) InjectInterrupt(source, channel, eventType string, payload map[string]interface{}) {
|
|
if s.iom != nil {
|
|
if payload == nil {
|
|
payload = map[string]interface{}{}
|
|
}
|
|
payload["type"] = eventType
|
|
s.iom.InjectInterrupt(source, channel, payload)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSDK) InjectTextSync(source, channel, text string) *agentIO.OutputEvent {
|
|
return s.InjectInputSync(source, channel, "text", map[string]interface{}{"content": text})
|
|
}
|
|
|
|
func (s *PluginSDK) InjectTextSyncNoMemory(source, channel, text string) *agentIO.OutputEvent {
|
|
return s.InjectInputSync(source, channel, "text", map[string]interface{}{"content": text, "no_memory": true})
|
|
}
|
|
|
|
func (s *PluginSDK) OutputChan() <-chan *agentIO.OutputEvent {
|
|
if s.iom != nil {
|
|
return s.iom.OutputChan()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *PluginSDK) RegisterChannel(name string, dev agentIO.Device) error {
|
|
if s.iom != nil {
|
|
return s.iom.RegisterDevice(dev)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *PluginSDK) UnregisterChannel(name string) {
|
|
if s.iom != nil {
|
|
s.iom.UnregisterDevice(name)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSDK) ListChannels() []agentIO.ChannelInfo {
|
|
if s.iom != nil {
|
|
return s.iom.ListChannels()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *PluginSDK) Publish(evt *events.Event) {
|
|
if s.eventBus != nil {
|
|
s.eventBus.Publish(evt)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSDK) Subscribe(eventType events.EventType, handler events.Handler) func() {
|
|
if s.eventBus != nil {
|
|
return s.eventBus.Subscribe(eventType, handler)
|
|
}
|
|
return func() {}
|
|
}
|