feat(tools/basic): 内置基础工具(calculator(注入安全)/datetime/random/text/json/markdown)+ 批量注册
This commit is contained in:
1 parent
b3c61aa1ff
commit
08223c06a5
19 files changed
+2074
No files matched your search
@@ -0,0 +1,95 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// jsonTool exposes JSON parsing, formatting, validation and serialization for the
|
||||
// agent. `value` is unconstrained in the schema because it is a string for
|
||||
// parse/format/validate and any JSON value for stringify.
|
||||
type jsonTool struct{}
|
||||
|
||||
// Name returns the tool identifier.
|
||||
func (jsonTool) Name() string { return "json" }
|
||||
|
||||
// Description explains what the tool does for the model.
|
||||
func (jsonTool) Description() string {
|
||||
return "Parse, format, validate or serialize JSON for structured data handling."
|
||||
}
|
||||
|
||||
// Parameters returns the tool input JSON Schema.
|
||||
func (jsonTool) Parameters() (map[string]any, error) {
|
||||
return map[string]any{
|
||||
"type": "object",
|
||||
"properties": map[string]any{
|
||||
"operation": map[string]any{
|
||||
"type": "string",
|
||||
"enum": []any{"parse", "format", "validate", "stringify"},
|
||||
"description": "the operation to perform",
|
||||
},
|
||||
"value": map[string]any{"description": "input: a JSON string for parse/format/validate, any value for stringify"},
|
||||
},
|
||||
"required": []any{"operation"},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Execute runs the requested operation against value.
|
||||
func (jsonTool) Execute(ctx context.Context, args any) (any, error) {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, err := asMap(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
op, err := reqString(m, "operation")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !hasKey(m, "value") {
|
||||
return nil, fmt.Errorf("basic: missing required argument %q: %w", "value", ErrInvalidArgument)
|
||||
}
|
||||
value := m["value"]
|
||||
switch strings.ToLower(strings.TrimSpace(op)) {
|
||||
case "parse":
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("basic: argument %q must be a string for parse: %w", "value", ErrInvalidArgument)
|
||||
}
|
||||
var out any
|
||||
if err := json.Unmarshal([]byte(s), &out); err != nil {
|
||||
return nil, fmt.Errorf("basic: invalid json for parse: %w", err)
|
||||
}
|
||||
return map[string]any{"result": out}, nil
|
||||
case "format":
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("basic: argument %q must be a string for format: %w", "value", ErrInvalidArgument)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := json.Indent(&buf, []byte(s), "", " "); err != nil {
|
||||
return nil, fmt.Errorf("basic: invalid json for format: %w", err)
|
||||
}
|
||||
return map[string]any{"result": buf.String()}, nil
|
||||
case "validate":
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("basic: argument %q must be a string for validate: %w", "value", ErrInvalidArgument)
|
||||
}
|
||||
return map[string]any{"valid": json.Valid([]byte(s))}, nil
|
||||
case "stringify":
|
||||
var buf bytes.Buffer
|
||||
enc := json.NewEncoder(&buf)
|
||||
enc.SetIndent("", " ")
|
||||
if err := enc.Encode(value); err != nil {
|
||||
return nil, fmt.Errorf("basic: cannot serialize value: %w", err)
|
||||
}
|
||||
return map[string]any{"result": strings.TrimRight(buf.String(), "\n")}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("basic: unknown json operation %q: %w", op, ErrUnsupported)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user