package jsonplugin import ( "context" "encoding/json" "fmt" "strconv" "strings" "git.yeij.top/AskaEth/Cyrene-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 }