-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtool.go
More file actions
136 lines (121 loc) · 3.47 KB
/
tool.go
File metadata and controls
136 lines (121 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package syndicate
import (
"encoding/json"
"errors"
"fmt"
)
// ToolConfig holds the configuration for creating custom tool implementations
type ToolConfig struct {
Name string
Description string
Schema any
ExecuteFunc func(args json.RawMessage) (interface{}, error)
}
// ToolOption defines a function that configures a Tool implementation
type ToolOption func(*ToolConfig) error
// WithToolName sets the name for the tool
func WithToolName(name string) ToolOption {
return func(config *ToolConfig) error {
if name == "" {
return errors.New("tool name cannot be empty")
}
config.Name = name
return nil
}
}
// WithToolDescription sets the description for the tool
func WithToolDescription(description string) ToolOption {
return func(config *ToolConfig) error {
if description == "" {
return errors.New("tool description cannot be empty")
}
config.Description = description
return nil
}
}
// WithToolSchema sets the schema for the tool
func WithToolSchema(schema any) ToolOption {
return func(config *ToolConfig) error {
if schema == nil {
return errors.New("tool schema cannot be nil")
}
config.Schema = schema
return nil
}
}
// WithToolExecuteHandler sets the execute function for the tool
func WithToolExecuteHandler(executeFunc func(args json.RawMessage) (interface{}, error)) ToolOption {
return func(config *ToolConfig) error {
if executeFunc == nil {
return errors.New("execute function cannot be nil")
}
config.ExecuteFunc = executeFunc
return nil
}
}
// customTool implements Tool using provided functions
type customTool struct {
name string
description string
schema json.RawMessage
executeFunc func(args json.RawMessage) (interface{}, error)
}
func (t *customTool) GetDefinition() ToolDefinition {
return ToolDefinition{
Name: t.name,
Description: t.description,
Parameters: t.schema,
}
}
func (t *customTool) Execute(args json.RawMessage) (interface{}, error) {
return t.executeFunc(args)
}
// NewTool creates a custom Tool implementation using functional options.
// Returns an error if required options are not provided.
//
// Example:
//
// tool, err := syndicate.NewTool(
// syndicate.WithToolName("ProcessOrder"),
// syndicate.WithToolDescription("Process customer orders"),
// syndicate.WithToolSchema(OrderSchema{}),
// syndicate.WithToolExecuteHandler(func(args json.RawMessage) (interface{}, error) {
// var order OrderSchema
// if err := json.Unmarshal(args, &order); err != nil {
// return nil, err
// }
// // Process the order...
// return "Order processed successfully", nil
// }),
// )
func NewTool(options ...ToolOption) (Tool, error) {
config := &ToolConfig{}
for _, option := range options {
if err := option(config); err != nil {
return nil, fmt.Errorf("failed to apply tool option: %w", err)
}
}
// Validate that all required fields are provided
if config.Name == "" {
return nil, errors.New("tool name is required")
}
if config.Description == "" {
return nil, errors.New("tool description is required")
}
if config.Schema == nil {
return nil, errors.New("tool schema is required")
}
if config.ExecuteFunc == nil {
return nil, errors.New("tool execute function is required")
}
schema, err := GenerateRawSchema(config.Schema)
if err != nil {
return nil, fmt.Errorf("failed to generate schema: %w", err)
}
return &customTool{
name: config.Name,
description: config.Description,
schema: schema,
executeFunc: config.ExecuteFunc,
}, nil
}