blob: 9ad2addad47e94c0bc4dc175479c3f9cdb4203dd [file] [log] [blame]
Sketch🕴️305f8172026-02-27 13:58:43 +04001package tools
2
3import (
4 "encoding/json"
5 "fmt"
6 "strings"
7
8 "github.com/invopop/jsonschema"
9)
10
11type FuncTool[I any, O any] struct {
12 name string
13 desc string
14 schema *jsonschema.Schema
15 fn func(args I) (O, error)
16}
17
18func NewFuncTool[I any, O any](name string, fn func(args I) (O, error), desc string) *FuncTool[I, O] {
19 return &FuncTool[I, O]{
20 name,
21 fmt.Sprintf("%s\nResult schema: %s", desc, GenerateSchema[O]()),
22 GenerateSchema[I](),
23 fn,
24 }
25}
26
27func (ft *FuncTool[I, O]) Name() string {
28 return ft.name
29}
30
31func (ft *FuncTool[I, O]) Description() string {
32 return ft.desc
33}
34
35func (ft *FuncTool[I, O]) InputSchema() *jsonschema.Schema {
36 return ft.schema
37}
38
39func (ft *FuncTool[I, O]) Call(inp string) (string, error) {
40 var args I
41 if err := json.NewDecoder(strings.NewReader(inp)).Decode(&args); err != nil {
42 return "", err
43 }
44 out, err := ft.fn(args)
45 if err != nil {
46 return "", err
47 }
48 var resp strings.Builder
49 if err := json.NewEncoder(&resp).Encode(out); err != nil {
50 return "", err
51 }
52 ret := resp.String()
53 fmt.Printf("$$$ %s\n", ret)
54 return ret, nil
55
56}
57
58func GenerateSchema[T any]() *jsonschema.Schema {
59 reflector := jsonschema.Reflector{
60 AllowAdditionalProperties: false,
61 RequiredFromJSONSchemaTags: true,
62 DoNotReference: true,
63 }
64 var v T
65 return reflector.Reflect(v)
66}