feat: expose tool owner plugin in stage context

- add Plugin field to ToolDef, ToolCall, ToolResult
- track tool owner in StageHost
- annotate before/after_toolcall stage context with tool plugin
- add RegisterStageOwnTools() for plugin-scoped tool listeners
- keep interrupt input source/output channel context in stage messages
This commit is contained in:
root
2026-07-06 17:25:18 +08:00
parent f84b17f236
commit 753167bee4
4 changed files with 94 additions and 9 deletions

View File

@ -63,18 +63,21 @@ type MemItem struct {
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Plugin string `json:"plugin,omitempty"`
Arguments map[string]interface{} `json:"arguments"`
}
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"`
}
type ToolDef struct {
Name string `json:"name"`
Plugin string `json:"plugin,omitempty"`
Description string `json:"description"`
Parameters map[string]interface{} `json:"parameters"`
}
@ -225,6 +228,9 @@ func (s *PluginSDK) LLM() LLMAPI { return s.llm }
func (s *PluginSDK) Settings() SettingsAPI { return s.sett }
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)
}
@ -237,6 +243,33 @@ func (s *PluginSDK) RegisterStage(stage Stage, handler StageHandler) {
}
}
// RegisterStageOwnTools 仅在 before_toolcall / after_toolcall 阶段监听当前插件自己的工具调用。
// 其他阶段会退化为普通 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)
})
}
func (s *PluginSDK) RegisterPluginAPI(name string) error {
if s.regAPI != nil {
return s.regAPI(name)