fix: cap distiller startup scan and switch to formal SDK module dependency

- replace vendored third_party/homeagent-sdk with formal module dependency
- keep canonical SDK via go.mod pinned commit
- optimize distiller startup loading to stream recent raw records only
- parse timestamps correctly and cap startup load to 5000 records
- remove quadratic string building in raw record parsing
- restore fast startup while preserving memory pipeline
This commit is contained in:
root
2026-07-06 20:18:13 +08:00
parent 8103481254
commit 7a6a5157a2
32 changed files with 65 additions and 4322 deletions

View File

@ -1,553 +0,0 @@
# PluginSDK API 参考
HomeAgent 内核通过 `*sdk.PluginSDK` 向插件暴露所有能力。插件在 `Start(sdk *PluginSDK)` 中接收此对象。
## Plugin 接口
所有插件必须实现此接口:
```go
type Plugin interface {
Name() string // 返回插件名称,与注册名一致
Start(sdk *PluginSDK) error // 初始化:注册工具、阶段钩子等
Stop() error // 清理:关连接、停 goroutine
}
```
### 入口函数
`.so` 动态插件必须导出的工厂函数:
```go
func NewPlugin(name string, config map[string]interface{}) (sdk.Plugin, error)
```
- `name`: 插件目录名,也是配置命名空间
- `config`: 插件依赖注入(预留,当前为空)
- 返回 `Plugin` 实例
## PluginSDK 总览
```
PluginSDK
├── 工具注册
│ └── RegisterTool(name, def, handler) error
├── 阶段钩子
│ └── RegisterStage(stage, handler)
├── 输入投递
│ ├── InjectInterruptText(source, channel, text)
│ ├── InjectText(source, channel, text)
│ └── InjectTextNoMemory(source, channel, text)
├── 配置管理 (SettingsAPI)
│ ├── Get(key) / Set(key, value)
│ ├── GetCore(key) / SetCore(key, value)
│ ├── GetPlugin(plugin, key) / SetPlugin(plugin, key, value)
│ ├── List(prefix) / ListCore(prefix)
│ ├── RegisterDef(def) / Defs(prefix)
│ ├── Dump() / Plugins()
├── 记忆访问
│ ├── Memory() -> MemoryAPI
│ ├── TextMemory() -> TextMemoryAPI
│ ├── DocMemory() -> DocMemoryAPI
├── 知识库
│ └── Knowledge() -> KnowledgeAPI
└── LLM 管理
└── LLM() -> LLMAPI
```
## 工具注册
### RegisterTool
```go
func (s *PluginSDK) RegisterTool(name string, def ToolDef, handler ToolHandler) error
```
向 LLM 注册一个可调用的工具。`name` 必须全局唯一,建议用插件名前缀避免冲突。
### ToolDef
```go
type ToolDef struct {
Name string `json:"name"` // 工具名
Plugin string `json:"plugin,omitempty"` // 工具所属插件
Description string `json:"description"` // LLM 看到的描述
Parameters map[string]interface{} `json:"parameters"` // JSON Schema
}
```
`Parameters` 使用 JSON Schema 格式描述参数。示例:
```go
sdk.ToolDef{
Name: "weather_query",
Description: "查询指定城市的天气",
Parameters: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"city": map[string]interface{}{
"type": "string",
"description": "城市名称",
},
},
"required": []string{"city"},
},
}
```
### ToolHandler
```go
type ToolHandler func(args map[string]interface{}) (interface{}, error)
```
- `args`: LLM 传入的参数,key 为参数名,value 为对应值
- 返回值: `interface{}` 会被 JSON 序列化后返回给 LLM
- 返回 `error` 时 LLM 会收到错误信息并可能重试
```go
func(args map[string]interface{}) (interface{}, error) {
city, _ := args["city"].(string)
return map[string]interface{}{
"temp": 25, "weather": "晴",
}, nil
}
```
错误结果推荐返回含 `isError` 字段的 map,而非返回 error(避免 LLM 重试):
```go
return map[string]interface{}{
"isError": true,
"content": "错误描述",
}, nil
```
### ToolCall / ToolResult
阶段钩子中访问的 LLM 工具调用和结果结构:
```go
type ToolCall struct {
ID string `json:"id"` // 调用 ID
Name string `json:"name"` // 工具名
Plugin string `json:"plugin,omitempty"` // 工具所属插件
Arguments map[string]interface{} `json:"arguments"` // 参数
}
type ToolResult struct {
CallID string `json:"call_id"` // 对应 ToolCall.ID
Name string `json:"name"` // 工具名
Plugin string `json:"plugin,omitempty"` // 工具所属插件
Success bool `json:"success"`
Result interface{} `json:"result"` // handler 返回值
}
```
## 阶段钩子
### RegisterStage
```go
func (s *PluginSDK) RegisterStage(stage Stage, handler StageHandler)
```
在消息处理管道的指定阶段注入逻辑。同一阶段可注册多个 handler,按注册顺序执行。
### Stage
```go
type Stage string
const (
StageOnInput Stage = "on_input" // 消息到达,零处理
StagePreAction Stage = "pre_action" // LLM 调用前,上下文就绪
StagePostAction Stage = "post_action" // LLM 返回后
StageBeforeToolcall Stage = "before_toolcall" // 单个工具执行前
StageAfterToolcall Stage = "after_toolcall" // 单个工具执行后
StageBeforeOutput Stage = "before_output" // 最终输出前
StageAfterOutput Stage = "after_output" // 输出发送后
)
```
### StageHandler
```go
type StageHandler func(ctx *StageContext) error
```
### RegisterStageOwnTools
```go
func (s *PluginSDK) RegisterStageOwnTools(stage Stage, handler StageHandler)
```
仅在 `before_toolcall` / `after_toolcall` 阶段监听**当前插件自己的工具调用**。
适用场景:
- QQ 插件只审核 `qq_send_*` 自己的发送工具
- Web 插件只改写 `web_fetch` 自己的结果
- Files 插件只审计 `files_write` 自己的写操作
其他阶段会退化成普通 `RegisterStage`。
### StageContext
```go
type StageContext struct {
mu sync.RWMutex
RawMessage string // 原始输入文本(on_input 可改写)
UserID string // 用户标识
GroupID string // 群组标识
ContextMsgs []map[string]interface{} // 上下文消息列表(pre_action 可注入)
LLMText string // LLM 返回文本(post_action 可改写)
ReasoningContent string // LLM 推理过程文本
TokenUsage map[string]int // Token 用量
ToolCalls []ToolCall // LLM 请求的工具调用
ToolResults []ToolResult // 工具执行结果
FinalText string // 最终输出文本(before_output 可改写)
Response *string // 设置后短路管道
Phase Stage // 当前阶段
Memory []MemItem // 召回的记忆
NoMemory bool // 是否跳过记忆
Extra map[string]interface{} // 扩展字段
}
```
**阶段权限矩阵**:
| 字段 | on_input | pre_action | post_action | before_toolcall | after_toolcall | before_output | after_output |
|------|----------|------------|-------------|-----------------|----------------|---------------|--------------|
| RawMessage | 读写 | - | - | - | - | - | - |
| ContextMsgs | - | 读写 | - | - | - | - | - |
| LLMText | - | - | 读写 | - | - | - | - |
| ToolCalls | - | - | 读写 | 读写 | - | - | - |
| ToolCall.deny | - | - | - | 读写 | - | - | - |
| ToolResults | - | - | - | - | 读写 | - | - |
| FinalText | - | - | - | - | - | 读写 | 只读 |
| Response | 读写 | 读写 | 读写 | 读写 | 读写 | 读写 | - |
**短路规则**:任意阶段设置 `ctx.Response` 后,管道立即跳到 `after_output`。
### 阶段示例
```go
// on_input: 拦截黑名单用户
s.RegisterStage(sdk.StageOnInput, func(ctx *sdk.StageContext) error {
if ctx.UserID == "blocked_user" {
resp := "已被限制使用"
ctx.Response = &resp
}
return nil
})
// pre_action: 注入额外上下文
s.RegisterStage(sdk.StagePreAction, func(ctx *sdk.StageContext) error {
ctx.Lock()
ctx.ContextMsgs = append(ctx.ContextMsgs, map[string]interface{}{
"role": "system",
"content": "当前时间: " + time.Now().Format("15:04"),
})
ctx.Unlock()
return nil
})
```
### MemItem
```go
type MemItem struct {
Role string `json:"role"` // system / user / assistant
Content string `json:"content"` // 内容
Score float64 `json:"score"` // TF-IDF 相关性评分
}
```
## 输入投递
插件可以向 Agent 投递输入消息。
```go
// 中断投递:可打断当前 LLM 处理
// - source: 来源标识(插件名)
// - channel: 通道名
// - text: 消息文本
func (s *PluginSDK) InjectInterruptText(source, channel, text string)
// 普通投递:排队等待处理
func (s *PluginSDK) InjectText(source, channel, text string)
// 投递但不触发记忆记录
func (s *PluginSDK) InjectTextNoMemory(source, channel, text string)
```
**两种投递方式的区别**:
| | InjectText | InjectInterruptText |
|---|---|---|
| 处理顺序 | 排队 | 优先 |
| 打断 LLM | 否 | 是(取消当前请求) |
| 适用场景 | 普通消息 | 定时器、重要通知 |
## 配置管理
### SettingsAPI
插件通过 `s.Settings()` 获取 `SettingsAPI`。每个插件拥有独立的 `config_<name>` SQLite 表。
```go
type SettingsAPI interface {
// 自身配置(config_<name> 表)
Get(key string) (interface{}, error)
Set(key string, value interface{}) error
List(prefix string) ([]string, error)
// 核心配置(config 表)
GetCore(key string) (interface{}, error)
SetCore(key string, value interface{}) error
ListCore(prefix string) ([]string, error)
// 其他插件配置(config_<plugin> 表)
GetPlugin(plugin, key string) (interface{}, error)
SetPlugin(plugin, key string, value interface{}) error
ListPlugin(plugin, prefix string) ([]string, error)
// 配置定义(WebUI 显示用)
RegisterDef(def ConfigDef)
Defs(prefix string) []*ConfigDef
// 全局
Dump() map[string]interface{}
Plugins() []string
}
```
### ConfigDef
```go
type ConfigDef struct {
Key string `json:"key"` // 配置键名
Default interface{} `json:"default,omitempty"` // 默认值
Type string `json:"type"` // 类型:string / number / boolean
DisplayName string `json:"display_name"` // WebUI 显示名称
Description string `json:"description,omitempty"` // 说明
Category string `json:"category,omitempty"` // 分组
Options []string `json:"options,omitempty"` // 选项列表(下拉框)
Min float64 `json:"min,omitempty"`
Max float64 `json:"max,omitempty"`
Step float64 `json:"step,omitempty"`
Required bool `json:"required,omitempty"`
Secret bool `json:"secret,omitempty"` // 敏感信息(输入框掩码)
}
```
### 使用示例
```go
// 插件启动时注册配置定义
s.Settings().RegisterDef(sdk.ConfigDef{
Key: "provider_key",
Type: "string",
DisplayName: "API Key",
Description: "第三方服务 API 密钥",
Secret: true,
Required: true,
})
// 运行时读取配置
apiKey, err := s.Settings().Get("provider_key")
// 读取核心配置
dataDir, _ := s.Settings().GetCore("core.daemon.data_dir")
// 读取其他插件配置
qqNapcat, _ := s.Settings().GetPlugin("qq", "napcat_url")
```
## 记忆访问
### MemoryAPI(图记忆)
存储在 SQLite 图数据库中,entities + relations 表。
```go
type MemoryAPI interface {
// 召回:query 为关键词列表,depth 为 BFS 遍历深度
Recall(query []string, depth int) ([]Entity, []Relation, error)
// 写入三元组
Commit(triples []Triple) error
// 统计:返回实体数、关系数等
Introspect() (map[string]interface{}, error)
// 合并实体(同义消歧)
MergeEntities(source, target string) (int, error)
// 清理:mode 为 "soft"(标记删除)或 "hard"(物理删除)
Purge(criteria map[string]string, mode string) (int, error)
}
```
```go
type Entity struct {
Name string `json:"name"` // 实体名称
Type string `json:"type"` // 类型: Person / Location / Concept ...
MentionCount int `json:"mention_count"` // 提及次数
}
type Relation struct {
SourceName string `json:"source_name"` // 主体
TargetName string `json:"target_name"` // 客体
RelationType string `json:"relation_type"` // 关系类型: likes / works_at / friend_of ...
}
type Triple struct {
Subject string `json:"subject"` // 主体实体名
Relation string `json:"relation"` // 关系
Object string `json:"object"` // 客体实体名
}
```
### TextMemoryAPI(文本记忆)
按时间顺序的原始对话日志,JSONL 文件轮转存储。
```go
type TextMemoryAPI interface {
Append(evt TextEvent) error
}
type TextEvent struct {
Role string `json:"role"` // system / user / assistant
Content string `json:"content"` // 内容
Timestamp int64 `json:"timestamp"` // 时间戳
Channel string `json:"channel,omitempty"` // 来源通道
}
```
### DocMemoryAPI(文档记忆)
临时记忆层,JSON 文件 + TF-IDF 向量索引,消费即删。
```go
type DocMemoryAPI interface {
// 搜索文档,返回 topK 条
Query(text string, topK int) []*Doc
// 插入文档
Insert(doc *Doc) error
// 删除文档
Remove(id string)
// 统计
Stats() map[string]interface{}
}
type Doc struct {
ID string `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Score float64 `json:"score,omitempty"`
}
```
## 知识库
### KnowledgeAPI
文件系统 + TF-IDF 向量检索,独立于记忆系统的索引。
```go
type KnowledgeAPI interface {
// 搜索知识条目,返回 topK 匹配
Search(query string, topK int) ([]*Knowledge, error)
// 添加知识
Add(name, content string) error
// 列出所有知识条目名
List() ([]string, error)
}
type Knowledge struct {
Name string `json:"name"`
Content string `json:"content"`
}
```
## LLM 管理
### LLMAPI
管理 LLM 提供者源。
```go
type LLMAPI interface {
// 列出所有已注册的 LLM 源
ListSources() []string
// 切换默认 LLM 源
SetSource(name string) error
// 当前使用的 LLM 源
CurrentSource() string
}
```
## IOInjector
SDK 内部的输入投递接口,`PluginSDK.InjectInterruptText` / `InjectText` / `InjectTextNoMemory` 底层调用。
```go
type IOInjector interface {
InjectInterruptText(source, channel, text string)
InjectText(source, channel, text string)
InjectTextNoMemory(source, channel, text string)
}
```
内核在插件启动后调用 `sdk.SetIOInjector()` 注入此接口的实际实现。
## SDK 辅助类型
```go
// 工具注册回调类型
type ToolRegistrar func(name string, def ToolDef, handler ToolHandler) error
// 阶段注册回调类型
type StageRegistrar func(stage Stage, handler StageHandler)
// API 注册回调类型
type APIRegistrar func(name string) error
```
## 插件生命周期
```
内核启动
│
├── plugin.Registry.Load(dir)
│ ├── 扫描 plugins/ 目录
│ ├── 匹配已注册工厂或动态加载 .so
│ ├── 调用 NewPlugin(name, config)
│ └── 调用 plugin.Start(sdk) ← 插件注册工具/阶段/事件
│
├── 正常运行
│ ├── LLM 调用 → 路由到注册的工具
│ └── 消息处理 → 触发注册的阶段钩子
│
└── 内核关闭
└── plugin.Stop() ← 插件清理资源
```
### 内置插件 vs 动态插件
| | 内置插件 | 动态 .so 插件 |
|---|---|---|
| 注册方式 | `init()` → `RegisterFactory` | `plugin.Open` 动态加载 |
| 存放位置 | `internal/plugins/` | `<dataDir>/plugins/<name>/` |
| 编译 | 编译进内核 | 独立 `go build -buildmode=plugin` |
| SDK 导入 | `gitcode.com/JianFeeeee/HomeAgent/internal/sdk` | `gitcode.com/JianFeeeee/homeagent-sdk/sdk` |
| 热加载 | 需重新编译 | 可运行时加载/卸载 |

View File

@ -1,14 +0,0 @@
package sdk
// KnowledgeAPI provides access to the knowledge store.
type KnowledgeAPI interface {
Search(query string, topK int) ([]*Knowledge, error)
Add(name, content string) error
List() ([]string, error)
}
// Knowledge represents a knowledge entry.
type Knowledge struct {
Name string `json:"name"`
Content string `json:"content"`
}

View File

@ -1,8 +0,0 @@
package sdk
// LLMAPI provides access to the LLM provider manager.
type LLMAPI interface {
ListSources() []string
SetSource(name string) error
CurrentSource() string
}

View File

@ -1,60 +0,0 @@
package sdk
// MemoryAPI provides access to the graph memory (entity-relation store).
type MemoryAPI interface {
Recall(query []string, depth int) ([]Entity, []Relation, error)
Commit(triples []Triple) error
Introspect() (map[string]interface{}, error)
MergeEntities(source, target string) (int, error)
Purge(criteria map[string]string, mode string) (int, error)
}
// Entity represents a named entity in the knowledge graph.
type Entity struct {
Name string `json:"name"`
Type string `json:"type"`
MentionCount int `json:"mention_count"`
}
// Relation represents a relationship between two entities.
type Relation struct {
SourceName string `json:"source_name"`
TargetName string `json:"target_name"`
RelationType string `json:"relation_type"`
}
// Triple represents a subject-relation-object triple for the knowledge graph.
type Triple struct {
Subject string `json:"subject"`
Relation string `json:"relation"`
Object string `json:"object"`
}
// TextMemoryAPI provides access to chronological text event storage.
type TextMemoryAPI interface {
Append(evt TextEvent) error
}
// TextEvent represents a single text memory event.
type TextEvent struct {
Role string `json:"role"`
Content string `json:"content"`
Timestamp int64 `json:"timestamp"`
Channel string `json:"channel,omitempty"`
}
// DocMemoryAPI provides access to the document vector store.
type DocMemoryAPI interface {
Query(text string, topK int) []*Doc
Insert(doc *Doc) error
Remove(id string)
Stats() map[string]interface{}
}
// Doc represents a document in the document store.
type Doc struct {
ID string `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Score float64 `json:"score,omitempty"`
}

View File

@ -1,237 +0,0 @@
package sdk
import "sync"
// Plugin is the interface every plugin must implement.
type Plugin interface {
Name() string
Start(sdk *PluginSDK) error
Stop() error
}
// ToolHandler is a function that handles a tool call.
type ToolHandler func(args map[string]interface{}) (interface{}, error)
// StageHandler is a function that handles a pipeline stage event.
type StageHandler func(ctx *StageContext) error
// Stage represents a point in the message processing pipeline.
type Stage string
const (
StageOnInput Stage = "on_input"
StagePreAction Stage = "pre_action"
StagePostAction Stage = "post_action"
StageBeforeToolcall Stage = "before_toolcall"
StageAfterToolcall Stage = "after_toolcall"
StageBeforeOutput Stage = "before_output"
StageAfterOutput Stage = "after_output"
)
// StageContext provides context for stage handlers.
type StageContext struct {
mu sync.RWMutex
RawMessage string
UserID string
GroupID string
ContextMsgs []map[string]interface{}
LLMText string
ReasoningContent string
TokenUsage map[string]int
ToolCalls []ToolCall
ToolResults []ToolResult
FinalText string
Response *string
Phase Stage
Memory []MemItem
NoMemory bool
Extra map[string]interface{}
}
func (c *StageContext) RLock() { c.mu.RLock() }
func (c *StageContext) RUnlock() { c.mu.RUnlock() }
func (c *StageContext) Lock() { c.mu.Lock() }
func (c *StageContext) Unlock() { c.mu.Unlock() }
func (c *StageContext) IsResponded() bool { c.mu.RLock(); defer c.mu.RUnlock(); return c.Response != nil }
// MemItem represents a memory item in stage context.
type MemItem struct {
Role string `json:"role"`
Content string `json:"content"`
Score float64 `json:"score"`
}
// ToolCall represents a model's request to call a tool.
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Plugin string `json:"plugin,omitempty"`
Arguments map[string]interface{} `json:"arguments"`
}
// ToolResult represents the result of a tool call.
type ToolResult struct {
CallID string `json:"call_id"`
Name string `json:"name"`
Plugin string `json:"plugin,omitempty"`
Success bool `json:"success"`
Result interface{} `json:"result"`
}
// ToolDef describes a tool that the plugin exposes.
type ToolDef struct {
Name string `json:"name"`
Plugin string `json:"plugin,omitempty"`
Description string `json:"description"`
Parameters map[string]interface{} `json:"parameters"`
}
// IOInjector provides methods for injecting input and interrupts into the agent pipeline.
type IOInjector interface {
InjectInterruptText(source, channel, text string)
InjectText(source, channel, text string)
InjectTextNoMemory(source, channel, text string)
}
// ToolRegistrar registers a tool dynamically.
type ToolRegistrar func(name string, def ToolDef, handler ToolHandler) error
// StageRegistrar registers a stage handler.
type StageRegistrar func(stage Stage, handler StageHandler)
// APIRegistrar registers a plugin API for external access.
type APIRegistrar func(name string) error
// PluginSDK is the main API surface provided to plugins at runtime.
// It wraps tool registration, settings, memory, knowledge, LLM, and IO injection.
type PluginSDK struct {
name string
regTool ToolRegistrar
regStage StageRegistrar
regAPI APIRegistrar
io IOInjector
mem MemoryAPI
textMem TextMemoryAPI
docMem DocMemoryAPI
know KnowledgeAPI
llm LLMAPI
sett SettingsAPI
}
// New creates a PluginSDK with the given dependencies.
func New(name string, sett SettingsAPI, regTool ToolRegistrar, regStage StageRegistrar, regAPI APIRegistrar) *PluginSDK {
return &PluginSDK{
name: name,
sett: sett,
regTool: regTool,
regStage: regStage,
regAPI: regAPI,
}
}
// PluginName returns the name of the plugin.
func (s *PluginSDK) PluginName() string { return s.name }
// Settings returns the settings API for reading/writing plugin configuration.
func (s *PluginSDK) Settings() SettingsAPI { return s.sett }
// Memory returns the graph memory API (may be nil if not available).
func (s *PluginSDK) Memory() MemoryAPI { return s.mem }
// TextMemory returns the text memory API (may be nil if not available).
func (s *PluginSDK) TextMemory() TextMemoryAPI { return s.textMem }
// DocMemory returns the document memory API (may be nil if not available).
func (s *PluginSDK) DocMemory() DocMemoryAPI { return s.docMem }
// Knowledge returns the knowledge store API (may be nil if not available).
func (s *PluginSDK) Knowledge() KnowledgeAPI { return s.know }
// LLM returns the LLM provider API (may be nil if not available).
func (s *PluginSDK) LLM() LLMAPI { return s.llm }
// RegisterTool registers a tool that the LLM can call.
func (s *PluginSDK) RegisterTool(name string, def ToolDef, handler ToolHandler) error {
if def.Plugin == "" {
def.Plugin = s.name
}
if s.regTool != nil {
return s.regTool(name, def, handler)
}
return nil
}
// RegisterStage registers a handler for a pipeline stage.
func (s *PluginSDK) RegisterStage(stage Stage, handler StageHandler) {
if s.regStage != nil {
s.regStage(stage, handler)
}
}
// RegisterStageOwnTools only listens to this plugin's own tool calls/results in
// before_toolcall / after_toolcall stages. Other stages degrade to RegisterStage.
func (s *PluginSDK) RegisterStageOwnTools(stage Stage, handler StageHandler) {
if s.regStage == nil {
return
}
if stage != StageBeforeToolcall && stage != StageAfterToolcall {
s.regStage(stage, handler)
return
}
s.regStage(stage, func(ctx *StageContext) error {
ctx.RLock()
match := false
switch stage {
case StageBeforeToolcall:
match = len(ctx.ToolCalls) > 0 && ctx.ToolCalls[0].Plugin == s.name
case StageAfterToolcall:
match = len(ctx.ToolResults) > 0 && ctx.ToolResults[0].Plugin == s.name
}
ctx.RUnlock()
if !match {
return nil
}
return handler(ctx)
})
}
// RegisterPluginAPI registers this plugin's API for access by other plugins.
func (s *PluginSDK) RegisterPluginAPI(name string) error {
if s.regAPI != nil {
return s.regAPI(name)
}
return nil
}
// SetIOInjector sets the IO injector (called by the core at startup).
func (s *PluginSDK) SetIOInjector(io IOInjector) { s.io = io }
// SetMemoryAPI sets the memory API (called by the core at startup).
func (s *PluginSDK) SetMemoryAPI(mem MemoryAPI) { s.mem = mem }
func (s *PluginSDK) SetTextMemoryAPI(tm TextMemoryAPI) { s.textMem = tm }
func (s *PluginSDK) SetDocMemoryAPI(dm DocMemoryAPI) { s.docMem = dm }
func (s *PluginSDK) SetKnowledgeAPI(kn KnowledgeAPI) { s.know = kn }
func (s *PluginSDK) SetLLMAPI(llm LLMAPI) { s.llm = llm }
// ---- IO Convenience Methods ----
// InjectInterruptText injects a text interrupt that can preempt current LLM processing.
func (s *PluginSDK) InjectInterruptText(source, channel, text string) {
if s.io != nil {
s.io.InjectInterruptText(source, channel, text)
}
}
// InjectText injects a text message into the agent pipeline.
func (s *PluginSDK) InjectText(source, channel, text string) {
if s.io != nil {
s.io.InjectText(source, channel, text)
}
}
// InjectTextNoMemory injects a text message without generating memory.
func (s *PluginSDK) InjectTextNoMemory(source, channel, text string) {
if s.io != nil {
s.io.InjectTextNoMemory(source, channel, text)
}
}

View File

@ -1,58 +0,0 @@
package sdk
type SettingsAPI interface {
// Get reads the plugin's own config value (config_<name> table).
Get(key string) (interface{}, error)
// Set writes a config value to the plugin's own config table.
Set(key string, value interface{}) error
// List returns all keys matching the given prefix.
List(prefix string) ([]string, error)
// GetCore reads the core config table.
GetCore(key string) (interface{}, error)
// SetCore writes to the core config table.
SetCore(key string, value interface{}) error
// ListCore lists core config keys matching the prefix.
ListCore(prefix string) ([]string, error)
// GetPlugin reads another plugin's config table.
GetPlugin(plugin, key string) (interface{}, error)
// SetPlugin writes to another plugin's config table.
SetPlugin(plugin, key string, value interface{}) error
// ListPlugin lists another plugin's config keys matching the prefix.
ListPlugin(plugin, prefix string) ([]string, error)
// RegisterDef registers a config definition for UI display.
RegisterDef(def ConfigDef)
// Defs returns config definitions matching the prefix.
Defs(prefix string) []*ConfigDef
// Dump returns all config values.
Dump() map[string]interface{}
// Plugins returns a list of all plugin config namespaces.
Plugins() []string
}
// ConfigDef describes a configuration field for the WebUI.
type ConfigDef struct {
Key string `json:"key"`
Default interface{} `json:"default,omitempty"`
Type string `json:"type"`
DisplayName string `json:"display_name"`
Description string `json:"description,omitempty"`
Category string `json:"category,omitempty"`
Options []string `json:"options,omitempty"`
Min float64 `json:"min,omitempty"`
Max float64 `json:"max,omitempty"`
Step float64 `json:"step,omitempty"`
Required bool `json:"required,omitempty"`
Secret bool `json:"secret,omitempty"`
}