- plugins: calculator, datetime, crypto, random, text, json, markdown - plugins: web-search (SearXNG stub), web-fetch, file, http (stubs) - main.go: full wiring — config→db→nats→plugins→voice→memory→ persona→llm→context→subsession→orchestrator→gateway→ws - 15 packages passing, 11 plugins loaded at startup
90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
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
|
|
}
|