feat: Phase 3 插件与工具系统 — Plugin SDK + Plugin Manager + 13内置插件 (40文件, 3293行)
- Plugin SDK: Plugin/Tool/ComplexTool/HostAPI 标准化接口 - Plugin Manager: 插件生命周期管理 (Install/Enable/Disable/Uninstall/Reload) - Tool Registry: 聚合工具注册表 (Register/Execute/Dispatch) - 13 个内置插件: 将原有硬编码工具迁移为标准插件格式 - REST API: 11 个端点 (net/http, 零外部依赖) - ai-core 集成: PluginManagerClient 替代本地工具调用 - plugin.json 元数据: 每个插件含完整 author/version/category/permissions Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"hash"
|
||||
"net/url"
|
||||
|
||||
"github.com/yourname/cyrene-ai/plugin-manager/internal/sdk"
|
||||
)
|
||||
|
||||
type CryptoPlugin struct{ sdk.BasePlugin }
|
||||
|
||||
func (p *CryptoPlugin) Metadata() sdk.PluginMetadata {
|
||||
return sdk.PluginMetadata{
|
||||
Name: "crypto", DisplayName: "Crypto & Encoding", Version: "1.0.0",
|
||||
Description: "Hashing (MD5/SHA) and encoding (Base64, URL) utilities",
|
||||
Category: "utility", Author: sdk.PluginAuthor{Name: "Cyrene Team"},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *CryptoPlugin) Tools() []sdk.Tool { return []sdk.Tool{&CryptoTool{}} }
|
||||
|
||||
type CryptoTool struct{ sdk.BaseTool }
|
||||
|
||||
func (t *CryptoTool) Definition() sdk.ToolDefinition {
|
||||
return sdk.ToolDefinition{
|
||||
ID: "crypto", Name: "crypto", DisplayName: "Crypto & Encoding",
|
||||
Description: "Crypto hash and encoding utilities. MD5/SHA hashing, Base64 encode/decode, URL encode/decode.",
|
||||
Category: "utility", Complexity: sdk.ComplexitySimple,
|
||||
Parameters: map[string]interface{}{
|
||||
"type": "object",
|
||||
"properties": map[string]interface{}{
|
||||
"action": map[string]interface{}{"type": "string", "enum": []string{"hash", "base64_encode", "base64_decode", "url_encode", "url_decode"}},
|
||||
"input": map[string]interface{}{"type": "string"},
|
||||
"algorithm": map[string]interface{}{"type": "string", "enum": []string{"md5", "sha1", "sha256", "sha512"}},
|
||||
},
|
||||
"required": []string{"action", "input"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *CryptoTool) Validate(args map[string]interface{}) error {
|
||||
for _, k := range []string{"action", "input"} {
|
||||
if _, ok := args[k]; !ok {
|
||||
return fmt.Errorf("missing required parameter: %s", k)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CryptoTool) Execute(_ context.Context, args map[string]interface{}) (*sdk.ToolResult, error) {
|
||||
action, _ := args["action"].(string)
|
||||
input, _ := args["input"].(string)
|
||||
|
||||
switch action {
|
||||
case "hash":
|
||||
alg, _ := args["algorithm"].(string)
|
||||
if alg == "" {
|
||||
alg = "sha256"
|
||||
}
|
||||
var h hash.Hash
|
||||
switch alg {
|
||||
case "md5":
|
||||
h = md5.New()
|
||||
case "sha1":
|
||||
h = sha1.New()
|
||||
case "sha256":
|
||||
h = sha256.New()
|
||||
case "sha512":
|
||||
h = sha512.New()
|
||||
default:
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: false, Error: "unsupported algorithm: " + alg}, nil
|
||||
}
|
||||
h.Write([]byte(input))
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: true,
|
||||
Output: fmt.Sprintf("%s: %x", alg, h.Sum(nil))}, nil
|
||||
|
||||
case "base64_encode":
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: true,
|
||||
Output: base64.StdEncoding.EncodeToString([]byte(input))}, nil
|
||||
|
||||
case "base64_decode":
|
||||
for _, enc := range []*base64.Encoding{base64.StdEncoding, base64.RawStdEncoding, base64.URLEncoding, base64.RawURLEncoding} {
|
||||
if decoded, err := enc.DecodeString(input); err == nil {
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: true, Output: truncate(string(decoded), 200)}, nil
|
||||
}
|
||||
}
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: false, Error: "failed to decode base64"}, nil
|
||||
|
||||
case "url_encode":
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: true,
|
||||
Output: url.QueryEscape(input)}, nil
|
||||
|
||||
case "url_decode":
|
||||
decoded, err := url.QueryUnescape(input)
|
||||
if err != nil {
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: false, Error: err.Error()}, nil
|
||||
}
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: true, Output: decoded}, nil
|
||||
}
|
||||
return &sdk.ToolResult{ToolName: "crypto", Success: false, Error: "unknown action: " + action}, nil
|
||||
}
|
||||
|
||||
func truncate(s string, n int) string {
|
||||
runes := []rune(s)
|
||||
if len(runes) > n {
|
||||
return string(runes[:n]) + "..."
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "crypto",
|
||||
"displayName": "Crypto & Encoding",
|
||||
"version": "1.0.0",
|
||||
"minCyreneVersion": "1.0.0",
|
||||
"author": { "name": "Cyrene Team" },
|
||||
"description": "Hashing (MD5/SHA) and encoding (Base64, URL) utilities",
|
||||
"license": "MIT",
|
||||
"keywords": ["crypto", "hash", "base64", "encode"],
|
||||
"category": "utility"
|
||||
}
|
||||
Reference in New Issue
Block a user