package calculator import ( "context" "fmt" "strconv" "strings" "git.yeij.top/AskaEth/Cyrene_v2/internal/plugin" ) type Plugin struct{} func New() *Plugin { return &Plugin{} } func (p *Plugin) Name() string { return "calculator" } func (p *Plugin) Version() string { return "1.0.0" } func (p *Plugin) Description() string { return "数学表达式求值" } func (p *Plugin) Init(_ context.Context, _ plugin.PluginConfig) error { return nil } func (p *Plugin) Close() error { return nil } func (p *Plugin) Enabled() bool { return true } func (p *Plugin) Tools() []plugin.ToolDefinition { return []plugin.ToolDefinition{{ Name: "calculator", Description: "Evaluate a math expression (supports +, -, *, /, parentheses)", Parameters: map[string]any{"expression": map[string]string{"type": "string", "description": "Math expression"}}, }} } func (p *Plugin) Execute(_ context.Context, _ string, params map[string]any) (string, error) { expr, _ := params["expression"].(string) if expr == "" { return "", fmt.Errorf("missing expression") } result, err := evalSimple(expr) if err != nil { return "", err } return fmt.Sprintf("%v", result), nil } func evalSimple(expr string) (float64, error) { expr = strings.ReplaceAll(expr, " ", "") // Simple operator evaluation: split by + and -, then by * and / parts := strings.FieldsFunc(expr, func(r rune) bool { return r == '+' || r == '-' }) if len(parts) == 1 { return evalMulDiv(expr) } var result float64 idx := 0 for i, p := range parts { val, err := evalMulDiv(p) if err != nil { return 0, err } if i == 0 { result = val } else { op := expr[idx-1] if op == '+' { result += val } else { result -= val } } idx += len(p) + 1 } return result, nil } func evalMulDiv(expr string) (float64, error) { parts := strings.FieldsFunc(expr, func(r rune) bool { return r == '*' || r == '/' }) if len(parts) == 1 { return strconv.ParseFloat(expr, 64) } var result float64 idx := 0 for i, p := range parts { val, err := strconv.ParseFloat(p, 64) if err != nil { return 0, err } if i == 0 { result = val } else { op := expr[idx-1] if op == '*' { result *= val } else { result /= val } } idx += len(p) + 1 } return result, nil }