feat: config, OpenAI-compatible streaming provider and safe tools
This commit is contained in:
commit
c1c7b0e005
13 changed files with 1031 additions and 0 deletions
64
internal/tools/tools.go
Normal file
64
internal/tools/tools.go
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// Package tools contains the tool registry and built-in safe tools.
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/crypto/openclaw/internal/llm"
|
||||
)
|
||||
|
||||
type Tool interface {
|
||||
Spec() llm.ToolSpec
|
||||
Call(ctx context.Context, args json.RawMessage) (string, error)
|
||||
}
|
||||
|
||||
type Registry struct{ tools map[string]Tool }
|
||||
|
||||
func NewRegistry(ts ...Tool) *Registry {
|
||||
r := &Registry{tools: map[string]Tool{}}
|
||||
for _, t := range ts {
|
||||
r.Register(t)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Registry) Register(t Tool) { r.tools[t.Spec().Name] = t }
|
||||
|
||||
func (r *Registry) Specs() []llm.ToolSpec {
|
||||
out := make([]llm.ToolSpec, 0, len(r.tools))
|
||||
for _, t := range r.tools {
|
||||
out = append(out, t.Spec())
|
||||
}
|
||||
sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name })
|
||||
return out
|
||||
}
|
||||
|
||||
// Call runs a tool; errors are returned as text so the model can react to them.
|
||||
func (r *Registry) Call(ctx context.Context, name, args string) string {
|
||||
t, ok := r.tools[name]
|
||||
if !ok {
|
||||
return fmt.Sprintf("error: unknown tool %q", name)
|
||||
}
|
||||
if args == "" {
|
||||
args = "{}"
|
||||
}
|
||||
if !json.Valid([]byte(args)) {
|
||||
return "error: arguments are not valid JSON"
|
||||
}
|
||||
res, err := t.Call(ctx, json.RawMessage(args))
|
||||
if err != nil {
|
||||
return "error: " + err.Error()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func obj(props map[string]any, required ...string) map[string]any {
|
||||
m := map[string]any{"type": "object", "properties": props}
|
||||
if len(required) > 0 {
|
||||
m["required"] = required
|
||||
}
|
||||
return m
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue