package openapi import ( "context" "encoding/json" "testing" ) type TestArgs struct { Name string `json:"name" desc:"The name of the user"` Age int `json:"age" desc:"The age of the user"` Tags []string `json:"tags,omitempty" desc:"Optional tags"` Enabled bool `json:"enabled"` } func TestRegisterTool(t *testing.T) { registry := NewMapRegistry() err := RegisterTool(registry, "test_tool", "A test tool", func(ctx context.Context, s *Session, args TestArgs) (any, error) { return args.Name, nil }) if err != nil { t.Fatalf("failed to register tool: %v", err) } tools := registry.Tools(context.Background()) if len(tools) != 1 { t.Fatalf("expected 1 tool, got %d", len(tools)) } tool := tools[0] if tool.Function.Name != "test_tool" { t.Errorf("expected tool name 'test_tool', got '%s'", tool.Function.Name) } var schema map[string]any if err := json.Unmarshal(tool.Function.Parameters, &schema); err != nil { t.Fatalf("failed to unmarshal parameters: %v", err) } // Check schema if schema["type"] != "object" { t.Errorf("expected type 'object', got '%v'", schema["type"]) } properties := schema["properties"].(map[string]any) if _, ok := properties["name"]; !ok { t.Error("missing 'name' property") } if properties["name"].(map[string]any)["description"] != "The name of the user" { t.Errorf("wrong description for 'name': %v", properties["name"].(map[string]any)["description"]) } required := schema["required"].([]any) foundName := false for _, r := range required { if r == "name" { foundName = true } } if !foundName { t.Error("'name' should be required") } // Test execution args := json.RawMessage(`{"name": "Alice", "age": 30, "enabled": true}`) res, err := registry.Execute(context.Background(), nil, "test_tool", args) if err != nil { t.Fatalf("failed to execute tool: %v", err) } if res != "Alice" { t.Errorf("expected result 'Alice', got '%v'", res) } } func TestRequiredTag(t *testing.T) { type RequiredArgs struct { ExplicitTrue string `json:"explicit_true,omitempty" required:"true"` ExplicitFalse string `json:"explicit_false" required:"false"` DefaultTrue string `json:"default_true"` DefaultFalse string `json:"default_false,omitempty"` } registry := NewMapRegistry() err := RegisterTool(registry, "req_tool", "A tool with required tags", func(ctx context.Context, s *Session, args RequiredArgs) (any, error) { return nil, nil }) if err != nil { t.Fatalf("failed to register tool: %v", err) } tools := registry.Tools(context.Background()) tool := tools[0] var schema map[string]any if err := json.Unmarshal(tool.Function.Parameters, &schema); err != nil { t.Fatalf("failed to unmarshal parameters: %v", err) } required := schema["required"].([]any) reqMap := make(map[string]bool) for _, r := range required { reqMap[r.(string)] = true } if !reqMap["explicit_true"] { t.Error("expected 'explicit_true' to be required") } if reqMap["explicit_false"] { t.Error("expected 'explicit_false' to NOT be required") } if !reqMap["default_true"] { t.Error("expected 'default_true' to be required") } if reqMap["default_false"] { t.Error("expected 'default_false' to NOT be required") } }