71f0a1abdb
- 所有Go模块路径从 github.com/yourname/cyrene-ai 迁移到 git.yeij.top/AskaEth/Cyrene - 5个Go Dockerfile添加 GOPROXY=https://goproxy.cn,direct 解决国内构建问题 - ai-core go.mod 添加 pkg/plugins replace 指令 - Caddyfile 简化为 http:// 通配 + handle 保留 /api 前缀 - ethend Dockerfile 适配 (npm install + 仅 COPY package.json) - ethend 新增 RUNNING_IN_DOCKER 环境变量,健康检查改用Docker服务名 - ethend 数据库状态检查支持Docker hostname (postgres/redis/qdrant/minio) - process-manager 新增 CONTAINER_SVC_MAP + Docker模式自动检测 - 统一 docker-compose.dev.db.yml 卷名 (pg_data/redis_data/qdrant_data/minio_data) - docker-compose.yml ethend服务挂载docker.sock + 端口变量化 - 清理 .env 统一后的残留文件与提示信息 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
133 lines
4.1 KiB
Go
133 lines
4.1 KiB
Go
package jsonplugin
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.yeij.top/AskaEth/Cyrene/pkg/plugins/sdk"
|
|
)
|
|
|
|
type JSONPlugin struct{ sdk.BasePlugin }
|
|
|
|
func (p *JSONPlugin) Metadata() sdk.PluginMetadata {
|
|
return sdk.PluginMetadata{
|
|
Name: "json", DisplayName: "JSON Processor", Version: "1.0.0",
|
|
Description: "JSON parsing, dot-path query, validation, pretty-print",
|
|
Category: "format", Author: sdk.PluginAuthor{Name: "Cyrene Team"},
|
|
}
|
|
}
|
|
|
|
func (p *JSONPlugin) Tools() []sdk.Tool { return []sdk.Tool{&JSONTool{}} }
|
|
|
|
type JSONTool struct{ sdk.BaseTool }
|
|
|
|
func (t *JSONTool) Definition() sdk.ToolDefinition {
|
|
return sdk.ToolDefinition{
|
|
ID: "json_ops", Name: "json_ops", DisplayName: "JSON Processor",
|
|
Description: "JSON processing. Parse/pretty-print, query by dot-notation path, validate.",
|
|
Category: "format", Complexity: sdk.ComplexitySimple,
|
|
Parameters: map[string]interface{}{
|
|
"type": "object",
|
|
"properties": map[string]interface{}{
|
|
"action": map[string]interface{}{"type": "string", "enum": []string{"parse", "query", "validate"}},
|
|
"json_string": map[string]interface{}{"type": "string"},
|
|
"path": map[string]interface{}{"type": "string"},
|
|
},
|
|
"required": []string{"action", "json_string"},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (t *JSONTool) Validate(args map[string]interface{}) error {
|
|
for _, k := range []string{"action", "json_string"} {
|
|
if _, ok := args[k]; !ok {
|
|
return fmt.Errorf("missing required parameter: %s", k)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (t *JSONTool) Execute(_ context.Context, args map[string]interface{}) (*sdk.ToolResult, error) {
|
|
action, _ := args["action"].(string)
|
|
jsonStr, _ := args["json_string"].(string)
|
|
|
|
switch action {
|
|
case "parse":
|
|
var v interface{}
|
|
if err := json.Unmarshal([]byte(jsonStr), &v); err != nil {
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: false, Error: err.Error()}, nil
|
|
}
|
|
pretty, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: false, Error: err.Error()}, nil
|
|
}
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: true, Output: string(pretty)}, nil
|
|
|
|
case "query":
|
|
var v interface{}
|
|
if err := json.Unmarshal([]byte(jsonStr), &v); err != nil {
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: false, Error: err.Error()}, nil
|
|
}
|
|
path, _ := args["path"].(string)
|
|
if path == "" {
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: false, Error: "path is required for query"}, nil
|
|
}
|
|
result, err := jsonPathQuery(v, path)
|
|
if err != nil {
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: false, Error: err.Error()}, nil
|
|
}
|
|
out, _ := json.Marshal(result)
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: true, Output: string(out)}, nil
|
|
|
|
case "validate":
|
|
var v interface{}
|
|
if err := json.Unmarshal([]byte(jsonStr), &v); err != nil {
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: true, Output: "Invalid JSON: " + err.Error()}, nil
|
|
}
|
|
typeStr := "unknown"
|
|
switch v.(type) {
|
|
case map[string]interface{}:
|
|
typeStr = "object"
|
|
case []interface{}:
|
|
typeStr = "array"
|
|
case string:
|
|
typeStr = "string"
|
|
case float64:
|
|
typeStr = "number"
|
|
case bool:
|
|
typeStr = "boolean"
|
|
}
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: true,
|
|
Output: fmt.Sprintf("Valid JSON (type: %s, size: %d bytes)", typeStr, len(jsonStr))}, nil
|
|
}
|
|
return &sdk.ToolResult{ToolName: "json_ops", Success: false, Error: "unknown action: " + action}, nil
|
|
}
|
|
|
|
func jsonPathQuery(root interface{}, path string) (interface{}, error) {
|
|
path = strings.TrimPrefix(path, "$.")
|
|
parts := strings.Split(path, ".")
|
|
current := root
|
|
for _, part := range parts {
|
|
switch v := current.(type) {
|
|
case map[string]interface{}:
|
|
var ok bool
|
|
current, ok = v[part]
|
|
if !ok {
|
|
return nil, fmt.Errorf("key %q not found", part)
|
|
}
|
|
case []interface{}:
|
|
idx, err := strconv.Atoi(part)
|
|
if err != nil || idx < 0 || idx >= len(v) {
|
|
return nil, fmt.Errorf("invalid array index: %s", part)
|
|
}
|
|
current = v[idx]
|
|
default:
|
|
return nil, fmt.Errorf("cannot traverse into %T at path segment %q", current, part)
|
|
}
|
|
}
|
|
return current, nil
|
|
}
|