diff --git a/cmd/root_test.go b/cmd/root_test.go index d30ca67d61..ccabb114ba 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -45,6 +45,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools/http" "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgressql" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/spf13/cobra" ) @@ -515,8 +516,8 @@ func TestParseToolFile(t *testing.T) { Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, AuthRequired: []string{}, }, @@ -552,7 +553,7 @@ func TestParseToolFile(t *testing.T) { Name: "my-prompt", Description: "A prompt template for data analysis.", Arguments: prompts.Arguments{ - {Parameter: tools.NewStringParameter("country", "The country to analyze.")}, + {Parameter: parameters.NewStringParameter("country", "The country to analyze.")}, }, Messages: []prompts.Message{ {Role: "user", Content: "Analyze the data for {{.country}}."}, @@ -682,10 +683,10 @@ func TestParseToolFileWithAuth(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), - tools.NewIntParameterWithAuth("id", "user id", []tools.ParamAuthService{{Name: "my-google-service", Field: "user_id"}}), - tools.NewStringParameterWithAuth("email", "user email", []tools.ParamAuthService{{Name: "my-google-service", Field: "email"}, {Name: "other-google-service", Field: "other_email"}}), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), + parameters.NewIntParameterWithAuth("id", "user id", []parameters.ParamAuthService{{Name: "my-google-service", Field: "user_id"}}), + parameters.NewStringParameterWithAuth("email", "user email", []parameters.ParamAuthService{{Name: "my-google-service", Field: "email"}, {Name: "other-google-service", Field: "other_email"}}), }, }, }, @@ -782,10 +783,10 @@ func TestParseToolFileWithAuth(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), - tools.NewIntParameterWithAuth("id", "user id", []tools.ParamAuthService{{Name: "my-google-service", Field: "user_id"}}), - tools.NewStringParameterWithAuth("email", "user email", []tools.ParamAuthService{{Name: "my-google-service", Field: "email"}, {Name: "other-google-service", Field: "other_email"}}), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), + parameters.NewIntParameterWithAuth("id", "user id", []parameters.ParamAuthService{{Name: "my-google-service", Field: "user_id"}}), + parameters.NewStringParameterWithAuth("email", "user email", []parameters.ParamAuthService{{Name: "my-google-service", Field: "email"}, {Name: "other-google-service", Field: "other_email"}}), }, }, }, @@ -884,10 +885,10 @@ func TestParseToolFileWithAuth(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), - tools.NewIntParameterWithAuth("id", "user id", []tools.ParamAuthService{{Name: "my-google-service", Field: "user_id"}}), - tools.NewStringParameterWithAuth("email", "user email", []tools.ParamAuthService{{Name: "my-google-service", Field: "email"}, {Name: "other-google-service", Field: "other_email"}}), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), + parameters.NewIntParameterWithAuth("id", "user id", []parameters.ParamAuthService{{Name: "my-google-service", Field: "user_id"}}), + parameters.NewStringParameterWithAuth("email", "user email", []parameters.ParamAuthService{{Name: "my-google-service", Field: "email"}, {Name: "other-google-service", Field: "other_email"}}), }, }, }, @@ -1053,9 +1054,9 @@ func TestEnvVarReplacement(t *testing.T) { Path: "search?name=alice&pet=cat", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - QueryParams: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + QueryParams: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, RequestBody: `{ @@ -1065,9 +1066,9 @@ func TestEnvVarReplacement(t *testing.T) { "other": "$OTHER" } `, - BodyParams: []tools.Parameter{tools.NewIntParameter("age", "age num"), tools.NewStringParameter("city", "city string")}, + BodyParams: []parameters.Parameter{parameters.NewIntParameter("age", "age num"), parameters.NewStringParameter("city", "city string")}, Headers: map[string]string{"Authorization": "API_KEY", "Content-Type": "application/json"}, - HeaderParams: []tools.Parameter{tools.NewStringParameter("Language", "language string")}, + HeaderParams: []parameters.Parameter{parameters.NewStringParameter("Language", "language string")}, }, }, Toolsets: server.ToolsetConfigs{ diff --git a/internal/prompts/arguments.go b/internal/prompts/arguments.go index a7064923e9..b6ba426faf 100644 --- a/internal/prompts/arguments.go +++ b/internal/prompts/arguments.go @@ -18,8 +18,8 @@ import ( "context" "fmt" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // ArgMcpManifest is the simplified manifest structure for an argument required for prompts. @@ -29,10 +29,10 @@ type ArgMcpManifest struct { Required bool `json:"required"` } -// Argument is a wrapper around a tools.Parameter that provides prompt-specific functionality. +// Argument is a wrapper around a parameters.Parameter that provides prompt-specific functionality. // If the 'type' field is not specified in a YAML definition, it defaults to 'string'. type Argument struct { - tools.Parameter + parameters.Parameter } // McpManifest returns the simplified manifest structure required for prompts. @@ -40,7 +40,7 @@ func (a Argument) McpManifest() ArgMcpManifest { return ArgMcpManifest{ Name: a.GetName(), Description: a.Manifest().Description, - Required: tools.CheckParamRequired(a.GetRequired(), a.GetDefault()), + Required: parameters.CheckParamRequired(a.GetRequired(), a.GetDefault()), } } @@ -64,12 +64,12 @@ func (args *Arguments) UnmarshalYAML(ctx context.Context, unmarshal func(interfa // If 'type' is missing, default it to string. paramType, ok := p["type"] if !ok { - p["type"] = tools.TypeString - paramType = tools.TypeString + p["type"] = parameters.TypeString + paramType = parameters.TypeString } // Call the clean, exported parser from the tools package. No more duplicated logic! - param, err := tools.ParseParameter(ctx, p, paramType.(string)) + param, err := parameters.ParseParameter(ctx, p, paramType.(string)) if err != nil { return err } @@ -80,10 +80,10 @@ func (args *Arguments) UnmarshalYAML(ctx context.Context, unmarshal func(interfa } // ParseArguments validates and processes the user-provided arguments against the prompt's requirements. -func ParseArguments(arguments Arguments, args map[string]any, data map[string]map[string]any) (tools.ParamValues, error) { - var parameters tools.Parameters +func ParseArguments(arguments Arguments, args map[string]any, data map[string]map[string]any) (parameters.ParamValues, error) { + var params parameters.Parameters for _, arg := range arguments { - parameters = append(parameters, arg.Parameter) + params = append(params, arg.Parameter) } - return tools.ParseParams(parameters, args, data) + return parameters.ParseParams(params, args, data) } diff --git a/internal/prompts/arguments_test.go b/internal/prompts/arguments_test.go index 0bdec1b1f6..53245bc00d 100644 --- a/internal/prompts/arguments_test.go +++ b/internal/prompts/arguments_test.go @@ -23,7 +23,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/prompts" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // Test type aliases for convenience. @@ -38,8 +38,8 @@ func Ptr[T any](v T) *T { return &v } -func makeArrayArg(name, desc string, items tools.Parameter) Argument { - return Argument{Parameter: tools.NewArrayParameter(name, desc, items)} +func makeArrayArg(name, desc string, items parameters.Parameter) Argument { + return Argument{Parameter: parameters.NewArrayParameter(name, desc, items)} } func TestArgMcpManifest(t *testing.T) { @@ -51,21 +51,21 @@ func TestArgMcpManifest(t *testing.T) { }{ { name: "Required with no default", - arg: Argument{Parameter: tools.NewStringParameterWithRequired("name1", "desc1", true)}, + arg: Argument{Parameter: parameters.NewStringParameterWithRequired("name1", "desc1", true)}, expected: ArgMcpManifest{ Name: "name1", Description: "desc1", Required: true, }, }, { name: "Not required with no default", - arg: Argument{Parameter: tools.NewStringParameterWithRequired("name2", "desc2", false)}, + arg: Argument{Parameter: parameters.NewStringParameterWithRequired("name2", "desc2", false)}, expected: ArgMcpManifest{ Name: "name2", Description: "desc2", Required: false, }, }, { name: "Implicitly required with default", - arg: Argument{Parameter: tools.NewStringParameterWithDefault("name3", "defaultVal", "desc3")}, + arg: Argument{Parameter: parameters.NewStringParameterWithDefault("name3", "defaultVal", "desc3")}, expected: ArgMcpManifest{ Name: "name3", Description: "desc3", Required: false, }, @@ -86,14 +86,14 @@ func TestArgMcpManifest(t *testing.T) { func TestArgumentsUnmarshalYAML(t *testing.T) { t.Parallel() // paramComparer allows cmp.Diff to intelligently compare the parsed results. - var transformFunc func(tools.Parameter) any - transformFunc = func(p tools.Parameter) any { + var transformFunc func(parameters.Parameter) any + transformFunc = func(p parameters.Parameter) any { s := struct{ Name, Type, Desc string }{ Name: p.GetName(), Type: p.GetType(), Desc: p.Manifest().Description, } - if arr, ok := p.(*tools.ArrayParameter); ok { + if arr, ok := p.(*parameters.ArrayParameter); ok { s.Desc = fmt.Sprintf("%s items:%v", s.Desc, transformFunc(arr.GetItems())) } return s @@ -112,7 +112,7 @@ func TestArgumentsUnmarshalYAML(t *testing.T) { {"name": "p1", "description": "d1"}, }, expectedArgs: Arguments{ - {Parameter: tools.NewStringParameter("p1", "d1")}, + {Parameter: parameters.NewStringParameter("p1", "d1")}, }, }, { @@ -121,7 +121,7 @@ func TestArgumentsUnmarshalYAML(t *testing.T) { {"name": "p1", "description": "d1", "type": "integer"}, }, expectedArgs: Arguments{ - {Parameter: tools.NewIntParameter("p1", "d1")}, + {Parameter: parameters.NewIntParameter("p1", "d1")}, }, }, { @@ -139,7 +139,7 @@ func TestArgumentsUnmarshalYAML(t *testing.T) { }, }, expectedArgs: Arguments{ - makeArrayArg("param_array", "an array", tools.NewStringParameter("item_name", "an item")), + makeArrayArg("param_array", "an array", parameters.NewStringParameter("item_name", "an item")), }, }, { @@ -186,14 +186,14 @@ func TestArgumentsUnmarshalYAML(t *testing.T) { func TestParseArguments(t *testing.T) { t.Parallel() testArguments := prompts.Arguments{ - {Parameter: tools.NewStringParameter("name", "A required name.")}, - {Parameter: tools.NewIntParameterWithRequired("count", "An optional count.", false)}, + {Parameter: parameters.NewStringParameter("name", "A required name.")}, + {Parameter: parameters.NewIntParameterWithRequired("count", "An optional count.", false)}, } testCases := []struct { name string argsIn map[string]any - want tools.ParamValues + want parameters.ParamValues wantErr string }{ { @@ -202,7 +202,7 @@ func TestParseArguments(t *testing.T) { "name": "test-name", "count": 42, }, - want: tools.ParamValues{ + want: parameters.ParamValues{ {Name: "name", Value: "test-name"}, {Name: "count", Value: 42}, }, @@ -212,7 +212,7 @@ func TestParseArguments(t *testing.T) { argsIn: map[string]any{ "name": "another-name", }, - want: tools.ParamValues{ + want: parameters.ParamValues{ {Name: "name", Value: "another-name"}, {Name: "count", Value: nil}, }, diff --git a/internal/prompts/custom/custom.go b/internal/prompts/custom/custom.go index 8a8a9a7f6c..6d08d8ca83 100644 --- a/internal/prompts/custom/custom.go +++ b/internal/prompts/custom/custom.go @@ -20,7 +20,7 @@ import ( yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/prompts" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) type Message = prompts.Message @@ -72,10 +72,10 @@ func (c *Config) McpManifest() prompts.McpManifest { return prompts.GetMcpManifest(c.Name, c.Description, c.Arguments) } -func (c *Config) SubstituteParams(argValues tools.ParamValues) (any, error) { +func (c *Config) SubstituteParams(argValues parameters.ParamValues) (any, error) { return prompts.SubstituteMessages(c.Messages, c.Arguments, argValues) } -func (c *Config) ParseArgs(args map[string]any, data map[string]map[string]any) (tools.ParamValues, error) { +func (c *Config) ParseArgs(args map[string]any, data map[string]map[string]any) (parameters.ParamValues, error) { return prompts.ParseArguments(c.Arguments, args, data) } diff --git a/internal/prompts/custom/custom_test.go b/internal/prompts/custom/custom_test.go index be6fc62af5..06d5d5d170 100644 --- a/internal/prompts/custom/custom_test.go +++ b/internal/prompts/custom/custom_test.go @@ -21,7 +21,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/prompts" "github.com/googleapis/genai-toolbox/internal/prompts/custom" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestConfig(t *testing.T) { @@ -29,8 +29,8 @@ func TestConfig(t *testing.T) { // Setup a shared config for testing its methods testArgs := prompts.Arguments{ - {Parameter: tools.NewStringParameter("name", "The name to use.")}, - {Parameter: tools.NewStringParameterWithRequired("location", "The location.", false)}, + {Parameter: parameters.NewStringParameter("name", "The name to use.")}, + {Parameter: parameters.NewStringParameterWithRequired("location", "The location.", false)}, } cfg := &custom.Config{ @@ -58,7 +58,7 @@ func TestConfig(t *testing.T) { t.Run("Manifest", func(t *testing.T) { want := prompts.Manifest{ Description: "A test config.", - Arguments: []tools.ParameterManifest{ + Arguments: []parameters.ParameterManifest{ {Name: "name", Type: "string", Required: true, Description: "The name to use.", AuthServices: []string{}}, {Name: "location", Type: "string", Required: false, Description: "The location.", AuthServices: []string{}}, }, @@ -85,7 +85,7 @@ func TestConfig(t *testing.T) { }) t.Run("SubstituteParams", func(t *testing.T) { - argValues := tools.ParamValues{ + argValues := parameters.ParamValues{ {Name: "name", Value: "Alice"}, {Name: "location", Value: "Wonderland"}, } @@ -114,7 +114,7 @@ func TestConfig(t *testing.T) { "name": "Bob", "location": "the Builder", } - want := tools.ParamValues{ + want := parameters.ParamValues{ {Name: "name", Value: "Bob"}, {Name: "location", Value: "the Builder"}, } diff --git a/internal/prompts/messages.go b/internal/prompts/messages.go index 1830b87a84..df2618bbe1 100644 --- a/internal/prompts/messages.go +++ b/internal/prompts/messages.go @@ -17,7 +17,7 @@ package prompts import ( "fmt" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // Message represents a single message in a prompt, with a role and content. @@ -52,17 +52,17 @@ func (m *Message) UnmarshalYAML(unmarshal func(interface{}) error) error { // SubstituteMessages takes a slice of Messages and a set of parameter values, // and returns a new slice with all template variables resolved. -func SubstituteMessages(messages []Message, arguments Arguments, argValues tools.ParamValues) ([]Message, error) { +func SubstituteMessages(messages []Message, arguments Arguments, argValues parameters.ParamValues) ([]Message, error) { substitutedMessages := make([]Message, 0, len(messages)) argsMap := argValues.AsMap() - var parameters tools.Parameters + var params parameters.Parameters for _, arg := range arguments { - parameters = append(parameters, arg.Parameter) + params = append(params, arg.Parameter) } for _, msg := range messages { - substitutedContent, err := tools.ResolveTemplateParams(parameters, msg.Content, argsMap) + substitutedContent, err := parameters.ResolveTemplateParams(params, msg.Content, argsMap) if err != nil { return nil, fmt.Errorf("error substituting params for message: %w", err) } diff --git a/internal/prompts/messages_test.go b/internal/prompts/messages_test.go index a2b733e93a..bafcfc58ab 100644 --- a/internal/prompts/messages_test.go +++ b/internal/prompts/messages_test.go @@ -21,7 +21,7 @@ import ( yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/prompts" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestMessageUnmarshalYAML(t *testing.T) { @@ -87,14 +87,14 @@ func TestSubstituteMessages(t *testing.T) { t.Parallel() t.Run("Success", func(t *testing.T) { arguments := prompts.Arguments{ - {Parameter: tools.NewStringParameter("name", "The name to use.")}, - {Parameter: tools.NewStringParameterWithRequired("location", "The location.", false)}, + {Parameter: parameters.NewStringParameter("name", "The name to use.")}, + {Parameter: parameters.NewStringParameterWithRequired("location", "The location.", false)}, } messages := []prompts.Message{ {Role: "user", Content: "Hello, my name is {{.name}} and I am in {{.location}}."}, {Role: "assistant", Content: "Nice to meet you, {{.name}}!"}, } - argValues := tools.ParamValues{ + argValues := parameters.ParamValues{ {Name: "name", Value: "Alice"}, {Name: "location", Value: "Wonderland"}, } @@ -119,7 +119,7 @@ func TestSubstituteMessages(t *testing.T) { messages := []prompts.Message{ {Content: "This has an {{.unclosed template"}, } - argValues := tools.ParamValues{} + argValues := parameters.ParamValues{} _, err := prompts.SubstituteMessages(messages, arguments, argValues) if err == nil { diff --git a/internal/prompts/prompts.go b/internal/prompts/prompts.go index a5931170ce..8ca17286f6 100644 --- a/internal/prompts/prompts.go +++ b/internal/prompts/prompts.go @@ -19,7 +19,7 @@ import ( "fmt" yaml "github.com/goccy/go-yaml" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // PromptConfigFactory defines the signature for a function that creates and @@ -68,16 +68,16 @@ type PromptConfig interface { } type Prompt interface { - SubstituteParams(tools.ParamValues) (any, error) - ParseArgs(map[string]any, map[string]map[string]any) (tools.ParamValues, error) + SubstituteParams(parameters.ParamValues) (any, error) + ParseArgs(map[string]any, map[string]map[string]any) (parameters.ParamValues, error) Manifest() Manifest McpManifest() McpManifest } // Manifest is the representation of prompts sent to Client SDKs. type Manifest struct { - Description string `json:"description"` - Arguments []tools.ParameterManifest `json:"arguments"` + Description string `json:"description"` + Arguments []parameters.ParameterManifest `json:"arguments"` } // McpManifest is the definition for a prompt the MCP client can get. @@ -100,7 +100,7 @@ func GetMcpManifest(name, desc string, args Arguments) McpManifest { } func GetManifest(desc string, args Arguments) Manifest { - paramManifests := make([]tools.ParameterManifest, 0, len(args)) + paramManifests := make([]parameters.ParameterManifest, 0, len(args)) for _, arg := range args { paramManifests = append(paramManifests, arg.Manifest()) } diff --git a/internal/prompts/prompts_test.go b/internal/prompts/prompts_test.go index e19ed93eb2..d0fe0a95f5 100644 --- a/internal/prompts/prompts_test.go +++ b/internal/prompts/prompts_test.go @@ -24,7 +24,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/prompts" _ "github.com/googleapis/genai-toolbox/internal/prompts/custom" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) type mockPromptConfig struct { @@ -136,8 +136,8 @@ func TestGetMcpManifest(t *testing.T) { promptName: "arg-prompt", description: "Prompt with args.", args: prompts.Arguments{ - {Parameter: tools.NewStringParameter("param1", "First param")}, - {Parameter: tools.NewIntParameterWithRequired("param2", "Second param", false)}, + {Parameter: parameters.NewStringParameter("param1", "First param")}, + {Parameter: parameters.NewIntParameterWithRequired("param2", "Second param", false)}, }, want: prompts.McpManifest{ Name: "arg-prompt", @@ -173,19 +173,19 @@ func TestGetManifest(t *testing.T) { args: prompts.Arguments{}, want: prompts.Manifest{ Description: "A simple prompt.", - Arguments: []tools.ParameterManifest{}, + Arguments: []parameters.ParameterManifest{}, }, }, { name: "With arguments", description: "Prompt with arguments.", args: prompts.Arguments{ - {Parameter: tools.NewStringParameter("param1", "First param")}, - {Parameter: tools.NewBooleanParameterWithRequired("param2", "Second param", false)}, + {Parameter: parameters.NewStringParameter("param1", "First param")}, + {Parameter: parameters.NewBooleanParameterWithRequired("param2", "Second param", false)}, }, want: prompts.Manifest{ Description: "Prompt with arguments.", - Arguments: []tools.ParameterManifest{ + Arguments: []parameters.ParameterManifest{ {Name: "param1", Type: "string", Required: true, Description: "First param", AuthServices: []string{}}, {Name: "param2", Type: "boolean", Required: false, Description: "Second param", AuthServices: []string{}}, }, diff --git a/internal/prompts/promptsets_test.go b/internal/prompts/promptsets_test.go index 13d86f562b..064ae0564a 100644 --- a/internal/prompts/promptsets_test.go +++ b/internal/prompts/promptsets_test.go @@ -20,7 +20,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/prompts" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // mockPrompt is a simple mock implementation of prompts.Prompt for testing. @@ -32,8 +32,8 @@ type mockPrompt struct { mcpManifest prompts.McpManifest } -func (m *mockPrompt) SubstituteParams(tools.ParamValues) (any, error) { return nil, nil } -func (m *mockPrompt) ParseArgs(map[string]any, map[string]map[string]any) (tools.ParamValues, error) { +func (m *mockPrompt) SubstituteParams(parameters.ParamValues) (any, error) { return nil, nil } +func (m *mockPrompt) ParseArgs(map[string]any, map[string]map[string]any) (parameters.ParamValues, error) { return nil, nil } func (m *mockPrompt) Manifest() prompts.Manifest { return m.manifest } @@ -42,7 +42,7 @@ func (m *mockPrompt) McpManifest() prompts.McpManifest { return m.mcpManifest } // newMockPrompt creates a new mock prompt for testing. func newMockPrompt(name, desc string) prompts.Prompt { args := prompts.Arguments{ - {Parameter: tools.NewStringParameter("arg1", "Test argument")}, + {Parameter: parameters.NewStringParameter("arg1", "Test argument")}, } return &mockPrompt{ name: name, @@ -50,7 +50,7 @@ func newMockPrompt(name, desc string) prompts.Prompt { args: args, manifest: prompts.Manifest{ Description: desc, - Arguments: []tools.ParameterManifest{ + Arguments: []parameters.ParameterManifest{ {Name: "arg1", Type: "string", Required: true, Description: "Test argument", AuthServices: []string{}}, }, }, diff --git a/internal/server/api.go b/internal/server/api.go index d26cfa7d0c..22068e3015 100644 --- a/internal/server/api.go +++ b/internal/server/api.go @@ -227,7 +227,7 @@ func toolInvokeHandler(s *Server, w http.ResponseWriter, r *http.Request) { params, err := tool.ParseParams(data, claimsFromAuth) if err != nil { // If auth error, return 401 - if errors.Is(err, tools.ErrUnauthorized) { + if errors.Is(err, util.ErrUnauthorized) { s.logger.DebugContext(ctx, fmt.Sprintf("error parsing authenticated parameters from ID token: %s", err)) _ = render.Render(w, r, newErrResponse(err, http.StatusUnauthorized)) return diff --git a/internal/server/common_test.go b/internal/server/common_test.go index 15ee11bbac..86cace906e 100644 --- a/internal/server/common_test.go +++ b/internal/server/common_test.go @@ -28,6 +28,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/prompts" "github.com/googleapis/genai-toolbox/internal/telemetry" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // fakeVersionString is used as a temporary version string in tests @@ -42,24 +43,24 @@ var ( type MockTool struct { Name string Description string - Params []tools.Parameter + Params []parameters.Parameter manifest tools.Manifest unauthorized bool requiresClientAuthrorization bool } -func (t MockTool) Invoke(context.Context, tools.ParamValues, tools.AccessToken) (any, error) { +func (t MockTool) Invoke(context.Context, parameters.ParamValues, tools.AccessToken) (any, error) { mock := []any{t.Name} return mock, nil } // claims is a map of user info decoded from an auth token -func (t MockTool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Params, data, claimsMap) +func (t MockTool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Params, data, claimsMap) } func (t MockTool) Manifest() tools.Manifest { - pMs := make([]tools.ParameterManifest, 0, len(t.Params)) + pMs := make([]parameters.ParameterManifest, 0, len(t.Params)) for _, p := range t.Params { pMs = append(pMs, p.Manifest()) } @@ -77,7 +78,7 @@ func (t MockTool) RequiresClientAuthorization() bool { } func (t MockTool) McpManifest() tools.McpManifest { - properties := make(map[string]tools.ParameterMcpManifest) + properties := make(map[string]parameters.ParameterMcpManifest) required := make([]string, 0) authParams := make(map[string][]string) @@ -92,7 +93,7 @@ func (t MockTool) McpManifest() tools.McpManifest { } } - toolsSchema := tools.McpToolsSchema{ + toolsSchema := parameters.McpToolsSchema{ Type: "object", Properties: properties, Required: required, @@ -120,7 +121,7 @@ type MockPrompt struct { Args prompts.Arguments } -func (p MockPrompt) SubstituteParams(vals tools.ParamValues) (any, error) { +func (p MockPrompt) SubstituteParams(vals parameters.ParamValues) (any, error) { return []prompts.Message{ { Role: "user", @@ -129,16 +130,16 @@ func (p MockPrompt) SubstituteParams(vals tools.ParamValues) (any, error) { }, nil } -func (p MockPrompt) ParseArgs(data map[string]any, claimsMap map[string]map[string]any) (tools.ParamValues, error) { - var parameters tools.Parameters +func (p MockPrompt) ParseArgs(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) { + var params parameters.Parameters for _, arg := range p.Args { - parameters = append(parameters, arg.Parameter) + params = append(params, arg.Parameter) } - return tools.ParseParams(parameters, data, claimsMap) + return parameters.ParseParams(params, data, claimsMap) } func (p MockPrompt) Manifest() prompts.Manifest { - var argManifests []tools.ParameterManifest + var argManifests []parameters.ParameterManifest for _, arg := range p.Args { argManifests = append(argManifests, arg.Manifest()) } @@ -154,34 +155,34 @@ func (p MockPrompt) McpManifest() prompts.McpManifest { var tool1 = MockTool{ Name: "no_params", - Params: []tools.Parameter{}, + Params: []parameters.Parameter{}, } var tool2 = MockTool{ Name: "some_params", - Params: tools.Parameters{ - tools.NewIntParameter("param1", "This is the first parameter."), - tools.NewIntParameter("param2", "This is the second parameter."), + Params: parameters.Parameters{ + parameters.NewIntParameter("param1", "This is the first parameter."), + parameters.NewIntParameter("param2", "This is the second parameter."), }, } var tool3 = MockTool{ Name: "array_param", Description: "some description", - Params: tools.Parameters{ - tools.NewArrayParameter("my_array", "this param is an array of strings", tools.NewStringParameter("my_string", "string item")), + Params: parameters.Parameters{ + parameters.NewArrayParameter("my_array", "this param is an array of strings", parameters.NewStringParameter("my_string", "string item")), }, } var tool4 = MockTool{ Name: "unauthorized_tool", - Params: []tools.Parameter{}, + Params: []parameters.Parameter{}, unauthorized: true, } var tool5 = MockTool{ Name: "require_client_auth_tool", - Params: []tools.Parameter{}, + Params: []parameters.Parameter{}, requiresClientAuthrorization: true, } @@ -193,7 +194,7 @@ var prompt1 = MockPrompt{ var prompt2 = MockPrompt{ Name: "prompt2", Args: prompts.Arguments{ - {Parameter: tools.NewStringParameter("arg1", "This is the first argument.")}, + {Parameter: parameters.NewStringParameter("arg1", "This is the first argument.")}, }, } diff --git a/internal/server/mcp.go b/internal/server/mcp.go index 7bc0d34d56..e6a58e9b88 100644 --- a/internal/server/mcp.go +++ b/internal/server/mcp.go @@ -36,7 +36,6 @@ import ( mcputil "github.com/googleapis/genai-toolbox/internal/server/mcp/util" v20241105 "github.com/googleapis/genai-toolbox/internal/server/mcp/v20241105" v20250326 "github.com/googleapis/genai-toolbox/internal/server/mcp/v20250326" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" @@ -445,7 +444,7 @@ func httpHandler(s *Server, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) case jsonrpc.INVALID_REQUEST: errStr := err.Error() - if errors.Is(err, tools.ErrUnauthorized) { + if errors.Is(err, util.ErrUnauthorized) { w.WriteHeader(http.StatusUnauthorized) } else if strings.Contains(errStr, "Error 401") { w.WriteHeader(http.StatusUnauthorized) diff --git a/internal/server/mcp/v20241105/method.go b/internal/server/mcp/v20241105/method.go index 0c24d81110..212883b0c1 100644 --- a/internal/server/mcp/v20241105/method.go +++ b/internal/server/mcp/v20241105/method.go @@ -104,7 +104,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st // Check if this specific tool requires the standard authorization header if tool.RequiresClientAuthorization() { if accessToken == "" { - return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, "missing access token in the 'Authorization' header", nil), tools.ErrUnauthorized + return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, "missing access token in the 'Authorization' header", nil), util.ErrUnauthorized } } @@ -152,7 +152,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st // Check if any of the specified auth services is verified isAuthorized := tool.Authorized(verifiedAuthServices) if !isAuthorized { - err = fmt.Errorf("unauthorized Tool call: Please make sure your specify correct auth headers: %w", tools.ErrUnauthorized) + err = fmt.Errorf("unauthorized Tool call: Please make sure your specify correct auth headers: %w", util.ErrUnauthorized) return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err } logger.DebugContext(ctx, "tool invocation authorized") @@ -169,7 +169,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st if err != nil { errStr := err.Error() // Missing authService tokens. - if errors.Is(err, tools.ErrUnauthorized) { + if errors.Is(err, util.ErrUnauthorized) { return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err } // Upstream auth error diff --git a/internal/server/mcp/v20250326/method.go b/internal/server/mcp/v20250326/method.go index 2f04da2ebc..98ac8f13b4 100644 --- a/internal/server/mcp/v20250326/method.go +++ b/internal/server/mcp/v20250326/method.go @@ -104,7 +104,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st // Check if this specific tool requires the standard authorization header if tool.RequiresClientAuthorization() { if accessToken == "" { - return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, "missing access token in the 'Authorization' header", nil), tools.ErrUnauthorized + return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, "missing access token in the 'Authorization' header", nil), util.ErrUnauthorized } } @@ -152,7 +152,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st // Check if any of the specified auth services is verified isAuthorized := tool.Authorized(verifiedAuthServices) if !isAuthorized { - err = fmt.Errorf("unauthorized Tool call: Please make sure your specify correct auth headers: %w", tools.ErrUnauthorized) + err = fmt.Errorf("unauthorized Tool call: Please make sure your specify correct auth headers: %w", util.ErrUnauthorized) return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err } logger.DebugContext(ctx, "tool invocation authorized") @@ -169,7 +169,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st if err != nil { errStr := err.Error() // Missing authService tokens. - if errors.Is(err, tools.ErrUnauthorized) { + if errors.Is(err, util.ErrUnauthorized) { return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err } // Upstream auth error diff --git a/internal/server/mcp/v20250618/method.go b/internal/server/mcp/v20250618/method.go index e8dacd5f3d..45be99039b 100644 --- a/internal/server/mcp/v20250618/method.go +++ b/internal/server/mcp/v20250618/method.go @@ -104,7 +104,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st // Check if this specific tool requires the standard authorization header if tool.RequiresClientAuthorization() { if accessToken == "" { - return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, "missing access token in the 'Authorization' header", nil), tools.ErrUnauthorized + return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, "missing access token in the 'Authorization' header", nil), util.ErrUnauthorized } } @@ -152,7 +152,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st // Check if any of the specified auth services is verified isAuthorized := tool.Authorized(verifiedAuthServices) if !isAuthorized { - err = fmt.Errorf("unauthorized Tool call: Please make sure your specify correct auth headers: %w", tools.ErrUnauthorized) + err = fmt.Errorf("unauthorized Tool call: Please make sure your specify correct auth headers: %w", util.ErrUnauthorized) return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err } logger.DebugContext(ctx, "tool invocation authorized") @@ -169,7 +169,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolsMap map[st if err != nil { errStr := err.Error() // Missing authService tokens. - if errors.Is(err, tools.ErrUnauthorized) { + if errors.Is(err, util.ErrUnauthorized) { return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err } // Upstream auth error diff --git a/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go b/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go index 55a53586c9..6bf920b2dd 100644 --- a/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go +++ b/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/alloydb/v1" ) @@ -71,20 +72,20 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameterWithDefault("location", "us-central1", "The location to create the cluster in. The default value is us-central1. If quota is exhausted then use other regions."), - tools.NewStringParameter("cluster", "A unique ID for the AlloyDB cluster."), - tools.NewStringParameter("password", "A secure password for the initial user."), - tools.NewStringParameterWithDefault("network", "default", "The name of the VPC network to connect the cluster to (e.g., 'default')."), - tools.NewStringParameterWithDefault("user", "postgres", "The name for the initial superuser. Defaults to 'postgres' if not provided."), + parameters.NewStringParameterWithDefault("location", "us-central1", "The location to create the cluster in. The default value is us-central1. If quota is exhausted then use other regions."), + parameters.NewStringParameter("cluster", "A unique ID for the AlloyDB cluster."), + parameters.NewStringParameter("password", "A secure password for the initial user."), + parameters.NewStringParameterWithDefault("network", "default", "The name of the VPC network to connect the cluster to (e.g., 'default')."), + parameters.NewStringParameterWithDefault("user", "postgres", "The name for the initial superuser. Defaults to 'postgres' if not provided."), } paramManifest := allParameters.Manifest() @@ -111,14 +112,14 @@ type Tool struct { Description string `yaml:"description"` Source *alloydbadmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) if !ok || project == "" { @@ -178,8 +179,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go b/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go index fdcdec38ca..82147dda32 100644 --- a/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go +++ b/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/alloydb/v1" ) @@ -71,21 +72,21 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), - tools.NewStringParameter("cluster", "The ID of the cluster to create the instance in."), - tools.NewStringParameter("instance", "A unique ID for the new AlloyDB instance."), - tools.NewStringParameterWithDefault("instanceType", "PRIMARY", "The type of instance to create. Valid values are: PRIMARY and READ_POOL. Default is PRIMARY"), - tools.NewStringParameterWithRequired("displayName", "An optional, user-friendly name for the instance.", false), - tools.NewIntParameterWithDefault("nodeCount", 1, "The number of nodes in the read pool. Required only if instanceType is READ_POOL. Default is 1."), + parameters.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), + parameters.NewStringParameter("cluster", "The ID of the cluster to create the instance in."), + parameters.NewStringParameter("instance", "A unique ID for the new AlloyDB instance."), + parameters.NewStringParameterWithDefault("instanceType", "PRIMARY", "The type of instance to create. Valid values are: PRIMARY and READ_POOL. Default is PRIMARY"), + parameters.NewStringParameterWithRequired("displayName", "An optional, user-friendly name for the instance.", false), + parameters.NewIntParameterWithDefault("nodeCount", 1, "The number of nodes in the read pool. Required only if instanceType is READ_POOL. Default is 1."), } paramManifest := allParameters.Manifest() @@ -112,14 +113,14 @@ type Tool struct { Description string `yaml:"description"` Source *alloydbadmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) if !ok || project == "" { @@ -188,8 +189,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go b/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go index 919e3e6c06..0e880cd4b3 100644 --- a/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go +++ b/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/alloydb/v1" ) @@ -71,21 +72,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), - tools.NewStringParameter("cluster", "The ID of the cluster where the user will be created."), - tools.NewStringParameter("user", "The name for the new user. Must be unique within the cluster."), - tools.NewStringParameterWithRequired("password", "A secure password for the new user. Required only for ALLOYDB_BUILT_IN userType.", false), - tools.NewArrayParameterWithDefault("databaseRoles", []any{}, "Optional. A list of database roles to grant to the new user (e.g., ['pg_read_all_data']).", tools.NewStringParameter("role", "A single database role to grant to the user (e.g., 'pg_read_all_data').")), - tools.NewStringParameter("userType", "The type of user to create. Valid values are: ALLOYDB_BUILT_IN and ALLOYDB_IAM_USER. ALLOYDB_IAM_USER is recommended."), + parameters.NewStringParameter("project", "The GCP project ID."), + parameters.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), + parameters.NewStringParameter("cluster", "The ID of the cluster where the user will be created."), + parameters.NewStringParameter("user", "The name for the new user. Must be unique within the cluster."), + parameters.NewStringParameterWithRequired("password", "A secure password for the new user. Required only for ALLOYDB_BUILT_IN userType.", false), + parameters.NewArrayParameterWithDefault("databaseRoles", []any{}, "Optional. A list of database roles to grant to the new user (e.g., ['pg_read_all_data']).", parameters.NewStringParameter("role", "A single database role to grant to the user (e.g., 'pg_read_all_data').")), + parameters.NewStringParameter("userType", "The type of user to create. Valid values are: ALLOYDB_BUILT_IN and ALLOYDB_IAM_USER. ALLOYDB_IAM_USER is recommended."), } paramManifest := allParameters.Manifest() @@ -112,14 +114,14 @@ type Tool struct { Description string `yaml:"description"` Source *alloydbadmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) if !ok || project == "" { @@ -188,8 +190,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go b/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go index 017bb1de60..064b4f6cd7 100644 --- a/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go +++ b/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "alloydb-get-cluster" @@ -71,17 +72,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), - tools.NewStringParameter("cluster", "The ID of the cluster."), + parameters.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), + parameters.NewStringParameter("cluster", "The ID of the cluster."), } paramManifest := allParameters.Manifest() @@ -107,14 +108,14 @@ type Tool struct { Kind string `yaml:"kind"` Source *alloydbadmin.Source - AllParams tools.Parameters + AllParams parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -146,8 +147,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go b/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go index b68deda304..db2a9685d1 100644 --- a/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go +++ b/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "alloydb-get-instance" @@ -71,18 +72,21 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("location", "The location of the instance (e.g., 'us-central1')."), - tools.NewStringParameter("cluster", "The ID of the cluster."), - tools.NewStringParameter("instance", "The ID of the instance."), + parameters.NewStringParameter("location", "The location of the instance (e.g., 'us-central1')."), + parameters.NewStringParameter("cluster", "The ID of the cluster."), + parameters.NewStringParameter("instance", "The ID of the instance."), + parameters.NewStringParameter("location", "The location of the instance (e.g., 'us-central1')."), + parameters.NewStringParameter("cluster", "The ID of the cluster."), + parameters.NewStringParameter("instance", "The ID of the instance."), } paramManifest := allParameters.Manifest() @@ -108,14 +112,14 @@ type Tool struct { Kind string `yaml:"kind"` Source *alloydbadmin.Source - AllParams tools.Parameters + AllParams parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -151,8 +155,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go b/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go index 1e4cfee789..9a916e62c2 100644 --- a/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go +++ b/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "alloydb-get-user" @@ -71,18 +72,18 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), - tools.NewStringParameter("cluster", "The ID of the cluster."), - tools.NewStringParameter("user", "The ID of the user."), + parameters.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), + parameters.NewStringParameter("cluster", "The ID of the cluster."), + parameters.NewStringParameter("user", "The ID of the user."), } paramManifest := allParameters.Manifest() @@ -108,14 +109,14 @@ type Tool struct { Kind string `yaml:"kind"` Source *alloydbadmin.Source - AllParams tools.Parameters + AllParams parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -151,8 +152,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go b/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go index fc790cdfea..ca1f10a676 100644 --- a/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go +++ b/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "alloydb-list-clusters" @@ -71,16 +72,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID to list clusters for.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID to list clusters for.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameterWithDefault("location", "-", "Optional: The location to list clusters in (e.g., 'us-central1'). Use '-' to list clusters across all locations.(Default: '-')"), + parameters.NewStringParameterWithDefault("location", "-", "Optional: The location to list clusters in (e.g., 'us-central1'). Use '-' to list clusters across all locations.(Default: '-')"), } paramManifest := allParameters.Manifest() @@ -107,14 +108,14 @@ type Tool struct { Description string `yaml:"description"` Source *alloydbadmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -142,8 +143,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go b/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go index 41fe823182..4a2b7bba01 100644 --- a/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go +++ b/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "alloydb-list-instances" @@ -71,17 +72,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID to list instances for.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID to list instances for.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameterWithDefault("location", "-", "Optional: The location of the cluster (e.g., 'us-central1'). Use '-' to get results for all regions.(Default: '-')"), - tools.NewStringParameterWithDefault("cluster", "-", "Optional: The ID of the cluster to list instances from. Use '-' to get results for all clusters.(Default: '-')"), + parameters.NewStringParameterWithDefault("location", "-", "Optional: The location of the cluster (e.g., 'us-central1'). Use '-' to get results for all regions.(Default: '-')"), + parameters.NewStringParameterWithDefault("cluster", "-", "Optional: The ID of the cluster to list instances from. Use '-' to get results for all clusters.(Default: '-')"), } paramManifest := allParameters.Manifest() @@ -108,14 +109,14 @@ type Tool struct { Description string `yaml:"description"` Source *alloydbadmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -147,8 +148,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydblistusers/alloydblistusers.go b/internal/tools/alloydb/alloydblistusers/alloydblistusers.go index df94fa1b7a..4be8328e59 100644 --- a/internal/tools/alloydb/alloydblistusers/alloydblistusers.go +++ b/internal/tools/alloydb/alloydblistusers/alloydblistusers.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "alloydb-list-users" @@ -71,17 +72,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The GCP project ID.") + projectParam = parameters.NewStringParameter("project", "The GCP project ID.") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), - tools.NewStringParameter("cluster", "The ID of the cluster to list users from."), + parameters.NewStringParameter("location", "The location of the cluster (e.g., 'us-central1')."), + parameters.NewStringParameter("cluster", "The ID of the cluster to list users from."), } paramManifest := allParameters.Manifest() @@ -108,14 +109,14 @@ type Tool struct { Description string `yaml:"description"` Source *alloydbadmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -147,8 +148,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go b/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go index 8e11b110e7..7945e11a15 100644 --- a/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go +++ b/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go @@ -27,6 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" alloydbadmin "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "alloydb-wait-for-operation" @@ -124,17 +125,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("location", "The location ID"), - tools.NewStringParameter("operation", "The operation ID"), + parameters.NewStringParameter("location", "The location ID"), + parameters.NewStringParameter("operation", "The operation ID"), } paramManifest := allParameters.Manifest() @@ -200,7 +201,7 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *alloydbadmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` // Polling configuration Delay time.Duration @@ -214,7 +215,7 @@ type Tool struct { } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -344,8 +345,8 @@ func (t Tool) generateAlloyDBConnectionMessage(responseData map[string]any) (str } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/alloydbainl/alloydbainl.go b/internal/tools/alloydbainl/alloydbainl.go index 4691977de6..efaa24d78e 100644 --- a/internal/tools/alloydbainl/alloydbainl.go +++ b/internal/tools/alloydbainl/alloydbainl.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/alloydbpg" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -52,13 +53,13 @@ var _ compatibleSource = &alloydbpg.Source{} var compatibleSources = [...]string{alloydbpg.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - NLConfig string `yaml:"nlConfig" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - NLConfigParameters tools.Parameters `yaml:"nlConfigParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + NLConfig string `yaml:"nlConfig" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + NLConfigParameters parameters.Parameters `yaml:"nlConfigParameters"` } // validate interface @@ -112,12 +113,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) stmtFormat := "SELECT alloydb_ai_nl.execute_nl_query(nl_question => $1, nl_config_id => $2, param_names => %s, param_values => %s);" stmt := fmt.Sprintf(stmtFormat, paramNamesSQL, paramValuesSQL) - newQuestionParam := tools.NewStringParameter( + newQuestionParam := parameters.NewStringParameter( "question", // name "The natural language question to ask.", // description ) - cfg.NLConfigParameters = append([]tools.Parameter{newQuestionParam}, cfg.NLConfigParameters...) + cfg.NLConfigParameters = append([]parameters.Parameter{newQuestionParam}, cfg.NLConfigParameters...) mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, cfg.NLConfigParameters) @@ -140,10 +141,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *pgxpool.Pool Statement string @@ -152,7 +153,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() allParamValues := make([]any, len(sliceParams)+1) allParamValues[0] = fmt.Sprintf("%s", sliceParams[0]) // nl_question @@ -184,8 +185,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/alloydbainl/alloydbainl_test.go b/internal/tools/alloydbainl/alloydbainl_test.go index 2061450c0a..2e618e66cc 100644 --- a/internal/tools/alloydbainl/alloydbainl_test.go +++ b/internal/tools/alloydbainl/alloydbainl_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/alloydbainl" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlAlloyDBNLA(t *testing.T) { @@ -62,9 +62,9 @@ func TestParseFromYamlAlloyDBNLA(t *testing.T) { Description: "AlloyDB natural language query tool", NLConfig: "my_nl_config", AuthRequired: []string{"my-google-auth-service"}, - NLConfigParameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("user_id", "user_id to use", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "sub"}}), + NLConfigParameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("user_id", "user_id to use", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "sub"}}), }, }, }, @@ -103,11 +103,11 @@ func TestParseFromYamlAlloyDBNLA(t *testing.T) { Description: "AlloyDB natural language query tool with multiple parameters", NLConfig: "complex_nl_config", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - NLConfigParameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("user_id", "user_id to use", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "sub"}}), - tools.NewStringParameterWithAuth("user_email", "user_email to use", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_email"}}), + NLConfigParameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("user_id", "user_id to use", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "sub"}}), + parameters.NewStringParameterWithAuth("user_email", "user_email to use", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_email"}}), }, }, }, diff --git a/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go b/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go index a5115e7a2a..4ac8a2d447 100644 --- a/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go +++ b/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go @@ -26,6 +26,7 @@ import ( bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" bqutil "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerycommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" bigqueryrestapi "google.golang.org/api/bigquery/v2" "google.golang.org/api/iterator" ) @@ -99,8 +100,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) inputDataDescription += fmt.Sprintf(" The query or table must only access datasets from the following list: %s.", strings.Join(datasetIDs, ", ")) } - inputDataParameter := tools.NewStringParameter("input_data", inputDataDescription) - contributionMetricParameter := tools.NewStringParameter("contribution_metric", + inputDataParameter := parameters.NewStringParameter("input_data", inputDataDescription) + contributionMetricParameter := parameters.NewStringParameter("contribution_metric", `The name of the column that contains the metric to analyze. Provides the expression to use to calculate the metric you are analyzing. To calculate a summable metric, the expression must be in the form SUM(metric_column_name), @@ -113,16 +114,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) To calculate a summable by category metric, the expression must be in the form SUM(metric_sum_column_name)/COUNT(DISTINCT categorical_column_name). The summed column must be a numeric data type. The categorical column must have type BOOL, DATE, DATETIME, TIME, TIMESTAMP, STRING, or INT64.`) - isTestColParameter := tools.NewStringParameter("is_test_col", + isTestColParameter := parameters.NewStringParameter("is_test_col", "The name of the column that identifies whether a row is in the test or control group.") - dimensionIDColsParameter := tools.NewArrayParameterWithRequired("dimension_id_cols", - "An array of column names that uniquely identify each dimension.", false, tools.NewStringParameter("dimension_id_col", "A dimension column name.")) - topKInsightsParameter := tools.NewIntParameterWithDefault("top_k_insights_by_apriori_support", 30, + dimensionIDColsParameter := parameters.NewArrayParameterWithRequired("dimension_id_cols", + "An array of column names that uniquely identify each dimension.", false, parameters.NewStringParameter("dimension_id_col", "A dimension column name.")) + topKInsightsParameter := parameters.NewIntParameterWithDefault("top_k_insights_by_apriori_support", 30, "The number of top insights to return, ranked by apriori support.") - pruningMethodParameter := tools.NewStringParameterWithDefault("pruning_method", "PRUNE_REDUNDANT_INSIGHTS", + pruningMethodParameter := parameters.NewStringParameterWithDefault("pruning_method", "PRUNE_REDUNDANT_INSIGHTS", "The method to use for pruning redundant insights. Can be 'NO_PRUNING' or 'PRUNE_REDUNDANT_INSIGHTS'.") - parameters := tools.Parameters{ + params := parameters.Parameters{ inputDataParameter, contributionMetricParameter, isTestColParameter, @@ -131,13 +132,13 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) pruningMethodParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), ClientCreator: s.BigQueryClientCreator(), @@ -146,7 +147,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) IsDatasetAllowed: s.IsDatasetAllowed, AllowedDatasets: allowedDatasets, SessionProvider: s.BigQuerySession(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -156,11 +157,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Client *bigqueryapi.Client RestService *bigqueryrestapi.Service @@ -173,7 +174,7 @@ type Tool struct { } // Invoke runs the contribution analysis. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() inputData, ok := paramsMap["input_data"].(string) if !ok { @@ -368,8 +369,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return "The query returned 0 rows.", nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerycommon/util.go b/internal/tools/bigquery/bigquerycommon/util.go index 0f4d027732..5486ac36ed 100644 --- a/internal/tools/bigquery/bigquerycommon/util.go +++ b/internal/tools/bigquery/bigquerycommon/util.go @@ -21,7 +21,7 @@ import ( "strings" bigqueryapi "cloud.google.com/go/bigquery" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" bigqueryrestapi "google.golang.org/api/bigquery/v2" ) @@ -79,7 +79,7 @@ func InitializeDatasetParameters( defaultProjectID string, projectKey, datasetKey string, projectDescription, datasetDescription string, -) (projectParam, datasetParam tools.Parameter) { +) (projectParam, datasetParam parameters.Parameter) { if len(allowedDatasets) > 0 { if len(allowedDatasets) == 1 { parts := strings.Split(allowedDatasets[0], ".") @@ -87,7 +87,7 @@ func InitializeDatasetParameters( datasetID := parts[1] projectDescription += fmt.Sprintf(" Must be `%s`.", defaultProjectID) datasetDescription += fmt.Sprintf(" Must be `%s`.", datasetID) - datasetParam = tools.NewStringParameterWithDefault(datasetKey, datasetID, datasetDescription) + datasetParam = parameters.NewStringParameterWithDefault(datasetKey, datasetID, datasetDescription) } else { datasetIDsByProject := make(map[string][]string) for _, ds := range allowedDatasets { @@ -108,13 +108,13 @@ func InitializeDatasetParameters( sort.Strings(datasetDescriptions) projectDescription += fmt.Sprintf(" Must be one of the following: %s.", strings.Join(projectIDList, ", ")) datasetDescription += fmt.Sprintf(" Must be one of the allowed datasets: %s.", strings.Join(datasetDescriptions, "; ")) - datasetParam = tools.NewStringParameter(datasetKey, datasetDescription) + datasetParam = parameters.NewStringParameter(datasetKey, datasetDescription) } } else { - datasetParam = tools.NewStringParameter(datasetKey, datasetDescription) + datasetParam = parameters.NewStringParameter(datasetKey, datasetDescription) } - projectParam = tools.NewStringParameterWithDefault(projectKey, defaultProjectID, projectDescription) + projectParam = parameters.NewStringParameterWithDefault(projectKey, defaultProjectID, projectDescription) return projectParam, datasetParam } diff --git a/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go b/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go index 8ba65cbabb..b7b711c06d 100644 --- a/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go +++ b/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go @@ -28,6 +28,8 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "golang.org/x/oauth2" ) @@ -145,11 +147,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } tableRefsDescription += fmt.Sprintf(" The tables must only be from datasets in the following list: %s.", strings.Join(datasetIDs, ", ")) } - userQueryParameter := tools.NewStringParameter("user_query_with_context", "The user's question, potentially including conversation history and system instructions for context.") - tableRefsParameter := tools.NewStringParameter("table_references", tableRefsDescription) + userQueryParameter := parameters.NewStringParameter("user_query_with_context", "The user's question, potentially including conversation history and system instructions for context.") + tableRefsParameter := parameters.NewStringParameter("table_references", tableRefsDescription) - parameters := tools.Parameters{userQueryParameter, tableRefsParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{userQueryParameter, tableRefsParameter} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // Get cloud-platform token source for Gemini Data Analytics API during initialization var bigQueryTokenSourceWithScope oauth2.TokenSource @@ -168,12 +170,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) Kind: kind, Project: s.BigQueryProject(), Location: s.BigQueryLocation(), - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Client: s.BigQueryClient(), UseClientOAuth: s.UseClientAuthorization(), TokenSource: bigQueryTokenSourceWithScope, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, MaxQueryResultRows: s.GetMaxQueryResultRows(), IsDatasetAllowed: s.IsDatasetAllowed, @@ -186,11 +188,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project string Location string @@ -203,7 +205,7 @@ type Tool struct { AllowedDatasets []string } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { var tokenStr string var err error @@ -211,7 +213,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken if t.UseClientOAuth { // Use client-side access token if accessToken == "" { - return nil, fmt.Errorf("tool is configured for client OAuth but no token was provided in the request header: %w", tools.ErrUnauthorized) + return nil, fmt.Errorf("tool is configured for client OAuth but no token was provided in the request header: %w", util.ErrUnauthorized) } tokenStr, err = accessToken.ParseBearerToken() if err != nil { @@ -285,8 +287,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return response, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go b/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go index 14b9a5233f..e74d702737 100644 --- a/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go +++ b/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go @@ -28,6 +28,7 @@ import ( bqutil "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerycommon" "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/orderedmap" + "github.com/googleapis/genai-toolbox/internal/util/parameters" bigqueryrestapi "google.golang.org/api/bigquery/v2" "google.golang.org/api/iterator" ) @@ -123,21 +124,21 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } } - sqlParameter := tools.NewStringParameter("sql", sqlDescriptionBuilder.String()) - dryRunParameter := tools.NewBooleanParameterWithDefault( + sqlParameter := parameters.NewStringParameter("sql", sqlDescriptionBuilder.String()) + dryRunParameter := parameters.NewBooleanParameterWithDefault( "dry_run", false, "If set to true, the query will be validated and information about the execution will be returned "+ "without running the query. Defaults to false.", ) - parameters := tools.Parameters{sqlParameter, dryRunParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{sqlParameter, dryRunParameter} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), ClientCreator: s.BigQueryClientCreator(), @@ -147,7 +148,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) SessionProvider: s.BigQuerySession(), IsDatasetAllowed: s.IsDatasetAllowed, AllowedDatasets: allowedDatasets, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -157,11 +158,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Client *bigqueryapi.Client RestService *bigqueryrestapi.Service @@ -174,7 +175,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -357,8 +358,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return "Query executed successfully and returned no content.", nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go b/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go index e17367566e..f6df651121 100644 --- a/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go +++ b/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" bqutil "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerycommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" bigqueryrestapi "google.golang.org/api/bigquery/v2" "google.golang.org/api/iterator" ) @@ -99,25 +100,25 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) historyDataDescription += fmt.Sprintf(" The query or table must only access datasets from the following list: %s.", strings.Join(datasetIDs, ", ")) } - historyDataParameter := tools.NewStringParameter("history_data", historyDataDescription) - timestampColumnNameParameter := tools.NewStringParameter("timestamp_col", + historyDataParameter := parameters.NewStringParameter("history_data", historyDataDescription) + timestampColumnNameParameter := parameters.NewStringParameter("timestamp_col", "The name of the time series timestamp column.") - dataColumnNameParameter := tools.NewStringParameter("data_col", + dataColumnNameParameter := parameters.NewStringParameter("data_col", "The name of the time series data column.") - idColumnNameParameter := tools.NewArrayParameterWithDefault("id_cols", []any{}, + idColumnNameParameter := parameters.NewArrayParameterWithDefault("id_cols", []any{}, "An array of the time series id column names.", - tools.NewStringParameter("id_col", "The name of time series id column.")) - horizonParameter := tools.NewIntParameterWithDefault("horizon", 10, "The number of forecasting steps.") - parameters := tools.Parameters{historyDataParameter, + parameters.NewStringParameter("id_col", "The name of time series id column.")) + horizonParameter := parameters.NewIntParameterWithDefault("horizon", 10, "The number of forecasting steps.") + params := parameters.Parameters{historyDataParameter, timestampColumnNameParameter, dataColumnNameParameter, idColumnNameParameter, horizonParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), ClientCreator: s.BigQueryClientCreator(), @@ -126,7 +127,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) IsDatasetAllowed: s.IsDatasetAllowed, SessionProvider: s.BigQuerySession(), AllowedDatasets: allowedDatasets, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -136,11 +137,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Client *bigqueryapi.Client RestService *bigqueryrestapi.Service @@ -152,7 +153,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() historyData, ok := paramsMap["history_data"].(string) if !ok { @@ -332,8 +333,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return "The query returned 0 rows.", nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go b/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go index 6d3920c4ac..c92a3a51af 100644 --- a/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go +++ b/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go @@ -24,6 +24,7 @@ import ( bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" bqutil "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerycommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "bigquery-get-dataset-info" @@ -89,29 +90,29 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) defaultProjectID := s.BigQueryProject() projectDescription := "The Google Cloud project ID containing the dataset." datasetDescription := "The dataset to get metadata information. Can be in `project.dataset` format." - var datasetParameter tools.Parameter - var projectParameter tools.Parameter + var datasetParameter parameters.Parameter + var projectParameter parameters.Parameter projectParameter, datasetParameter = bqutil.InitializeDatasetParameters( s.BigQueryAllowedDatasets(), defaultProjectID, projectKey, datasetKey, projectDescription, datasetDescription) - parameters := tools.Parameters{projectParameter, datasetParameter} + params := parameters.Parameters{projectParameter, datasetParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), ClientCreator: s.BigQueryClientCreator(), Client: s.BigQueryClient(), IsDatasetAllowed: s.IsDatasetAllowed, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -121,11 +122,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Client *bigqueryapi.Client ClientCreator bigqueryds.BigqueryClientCreator @@ -135,7 +136,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() projectId, ok := mapParams[projectKey].(string) if !ok { @@ -176,8 +177,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return metadata, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go b/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go index 9788b707ff..0fbbcb1a1b 100644 --- a/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go +++ b/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go @@ -24,6 +24,7 @@ import ( bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" bqutil "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerycommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "bigquery-get-table-info" @@ -90,8 +91,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) defaultProjectID := s.BigQueryProject() projectDescription := "The Google Cloud project ID containing the dataset and table." datasetDescription := "The table's parent dataset." - var datasetParameter tools.Parameter - var projectParameter tools.Parameter + var datasetParameter parameters.Parameter + var projectParameter parameters.Parameter projectParameter, datasetParameter = bqutil.InitializeDatasetParameters( s.BigQueryAllowedDatasets(), @@ -100,22 +101,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) projectDescription, datasetDescription, ) - tableParameter := tools.NewStringParameter(tableKey, "The table to get metadata information.") - parameters := tools.Parameters{projectParameter, datasetParameter, tableParameter} + tableParameter := parameters.NewStringParameter(tableKey, "The table to get metadata information.") + params := parameters.Parameters{projectParameter, datasetParameter, tableParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), ClientCreator: s.BigQueryClientCreator(), Client: s.BigQueryClient(), IsDatasetAllowed: s.IsDatasetAllowed, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -125,11 +126,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Client *bigqueryapi.Client ClientCreator bigqueryds.BigqueryClientCreator @@ -139,7 +140,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() projectId, ok := mapParams[projectKey].(string) if !ok { @@ -186,8 +187,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return metadata, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go b/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go index 4f7757434f..e518c8973a 100644 --- a/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go +++ b/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/iterator" ) @@ -84,7 +85,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - var projectParameter tools.Parameter + var projectParameter parameters.Parameter var projectParameterDescription string allowedDatasets := s.BigQueryAllowedDatasets() @@ -94,23 +95,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) projectParameterDescription = "The Google Cloud project to list dataset ids." } - projectParameter = tools.NewStringParameterWithDefault(projectKey, s.BigQueryProject(), projectParameterDescription) + projectParameter = parameters.NewStringParameterWithDefault(projectKey, s.BigQueryProject(), projectParameterDescription) - parameters := tools.Parameters{projectParameter} + params := parameters.Parameters{projectParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), ClientCreator: s.BigQueryClientCreator(), Client: s.BigQueryClient(), AllowedDatasets: allowedDatasets, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -120,11 +121,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Client *bigqueryapi.Client ClientCreator bigqueryds.BigqueryClientCreator @@ -134,7 +135,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { if len(t.AllowedDatasets) > 0 { return t.AllowedDatasets, nil } @@ -180,8 +181,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return datasetIds, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go b/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go index 71d4254931..2c2c6a2bef 100644 --- a/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go +++ b/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go @@ -24,6 +24,7 @@ import ( bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" bqutil "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerycommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/iterator" ) @@ -90,8 +91,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) defaultProjectID := s.BigQueryProject() projectDescription := "The Google Cloud project ID containing the dataset." datasetDescription := "The dataset to list table ids." - var datasetParameter tools.Parameter - var projectParameter tools.Parameter + var datasetParameter parameters.Parameter + var projectParameter parameters.Parameter projectParameter, datasetParameter = bqutil.InitializeDatasetParameters( s.BigQueryAllowedDatasets(), @@ -100,21 +101,21 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) projectDescription, datasetDescription, ) - parameters := tools.Parameters{projectParameter, datasetParameter} + params := parameters.Parameters{projectParameter, datasetParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), ClientCreator: s.BigQueryClientCreator(), Client: s.BigQueryClient(), IsDatasetAllowed: s.IsDatasetAllowed, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -124,11 +125,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Client *bigqueryapi.Client ClientCreator bigqueryds.BigqueryClientCreator @@ -138,7 +139,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() projectId, ok := mapParams[projectKey].(string) if !ok { @@ -191,8 +192,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return tableIds, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go b/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go index 869a41498c..1de6db8def 100644 --- a/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go +++ b/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/iterator" ) @@ -85,30 +86,30 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // Get the Dataplex client using the method from the source makeCatalogClient := s.MakeDataplexCatalogClient() - prompt := tools.NewStringParameter("prompt", "Prompt representing search intention. Do not rewrite the prompt.") - datasetIds := tools.NewArrayParameterWithDefault("datasetIds", []any{}, "Array of dataset IDs.", tools.NewStringParameter("datasetId", "The IDs of the bigquery dataset.")) - projectIds := tools.NewArrayParameterWithDefault("projectIds", []any{}, "Array of project IDs.", tools.NewStringParameter("projectId", "The IDs of the bigquery project.")) - types := tools.NewArrayParameterWithDefault("types", []any{}, "Array of data types to filter by.", tools.NewStringParameter("type", "The type of the data. Accepted values are: CONNECTION, POLICY, DATASET, MODEL, ROUTINE, TABLE, VIEW.")) - pageSize := tools.NewIntParameterWithDefault("pageSize", 5, "Number of results in the search page.") - parameters := tools.Parameters{prompt, datasetIds, projectIds, types, pageSize} + prompt := parameters.NewStringParameter("prompt", "Prompt representing search intention. Do not rewrite the prompt.") + datasetIds := parameters.NewArrayParameterWithDefault("datasetIds", []any{}, "Array of dataset IDs.", parameters.NewStringParameter("datasetId", "The IDs of the bigquery dataset.")) + projectIds := parameters.NewArrayParameterWithDefault("projectIds", []any{}, "Array of project IDs.", parameters.NewStringParameter("projectId", "The IDs of the bigquery project.")) + types := parameters.NewArrayParameterWithDefault("types", []any{}, "Array of data types to filter by.", parameters.NewStringParameter("type", "The type of the data. Accepted values are: CONNECTION, POLICY, DATASET, MODEL, ROUTINE, TABLE, VIEW.")) + pageSize := parameters.NewIntParameterWithDefault("pageSize", 5, "Number of results in the search page.") + params := parameters.Parameters{prompt, datasetIds, projectIds, types, pageSize} description := "Use this tool to find tables, views, models, routines or connections." if cfg.Description != "" { description = cfg.Description } - mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, params) t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), MakeCatalogClient: makeCatalogClient, ProjectID: s.BigQueryProject(), manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -119,7 +120,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) type Tool struct { Name string Kind string - Parameters tools.Parameters + Parameters parameters.Parameters AuthRequired []string UseClientOAuth bool MakeCatalogClient func() (*dataplexapi.CatalogClient, bigqueryds.DataplexClientCreator, error) @@ -205,21 +206,21 @@ func ExtractType(resourceString string) string { return typeMap[resourceString[lastIndex+1:]] } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() pageSize := int32(paramsMap["pageSize"].(int)) prompt, _ := paramsMap["prompt"].(string) - projectIdSlice, err := tools.ConvertAnySliceToTyped(paramsMap["projectIds"].([]any), "string") + projectIdSlice, err := parameters.ConvertAnySliceToTyped(paramsMap["projectIds"].([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert projectIds to array of strings: %s", err) } projectIds := projectIdSlice.([]string) - datasetIdSlice, err := tools.ConvertAnySliceToTyped(paramsMap["datasetIds"].([]any), "string") + datasetIdSlice, err := parameters.ConvertAnySliceToTyped(paramsMap["datasetIds"].([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert datasetIds to array of strings: %s", err) } datasetIds := datasetIdSlice.([]string) - typesSlice, err := tools.ConvertAnySliceToTyped(paramsMap["types"].([]any), "string") + typesSlice, err := parameters.ConvertAnySliceToTyped(paramsMap["types"].([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert types to array of strings: %s", err) } @@ -272,9 +273,9 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { // Parse parameters from the provided data - return tools.ParseParams(t.Parameters, data, claims) + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerysql/bigquerysql.go b/internal/tools/bigquery/bigquerysql/bigquerysql.go index dc6e5a3026..0ac02eb51c 100644 --- a/internal/tools/bigquery/bigquerysql/bigquerysql.go +++ b/internal/tools/bigquery/bigquerysql/bigquerysql.go @@ -23,6 +23,7 @@ import ( bigqueryapi "cloud.google.com/go/bigquery" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" + "github.com/googleapis/genai-toolbox/internal/util/parameters" bigqueryds "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/tools" @@ -62,14 +63,14 @@ var _ compatibleSource = &bigqueryds.Source{} var compatibleSources = [...]string{bigqueryds.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -92,7 +93,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -124,13 +125,13 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Statement string Client *bigqueryapi.Client @@ -141,12 +142,12 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { highLevelParams := make([]bigqueryapi.QueryParameter, 0, len(t.Parameters)) lowLevelParams := make([]*bigqueryrestapi.QueryParameter, 0, len(t.Parameters)) paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } @@ -156,14 +157,14 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken value := paramsMap[name] // This block for converting []any to typed slices is still necessary and correct. - if arrayParam, ok := p.(*tools.ArrayParameter); ok { + if arrayParam, ok := p.(*parameters.ArrayParameter); ok { arrayParamValue, ok := value.([]any) if !ok { return nil, fmt.Errorf("unable to convert parameter `%s` to []any", name) } itemType := arrayParam.GetItems().GetType() var err error - value, err = tools.ConvertAnySliceToTyped(arrayParamValue, itemType) + value, err = parameters.ConvertAnySliceToTyped(arrayParamValue, itemType) if err != nil { return nil, fmt.Errorf("unable to convert parameter `%s` from []any to typed slice: %w", name, err) } @@ -188,7 +189,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken ParameterValue: &bigqueryrestapi.QueryParameterValue{}, } - if arrayParam, ok := p.(*tools.ArrayParameter); ok { + if arrayParam, ok := p.(*parameters.ArrayParameter); ok { // Handle array types based on their defined item type. lowLevelParam.ParameterType.Type = "ARRAY" itemType, err := bqutil.BQTypeStringFromToolType(arrayParam.GetItems().GetType()) @@ -301,8 +302,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return "Query executed successfully and returned no content.", nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigquery/bigquerysql/bigquerysql_test.go b/internal/tools/bigquery/bigquerysql/bigquerysql_test.go index 86ebfe4a36..967fd418cd 100644 --- a/internal/tools/bigquery/bigquerysql/bigquerysql_test.go +++ b/internal/tools/bigquery/bigquerysql/bigquerysql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerysql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlBigQuery(t *testing.T) { @@ -58,8 +58,8 @@ func TestParseFromYamlBigQuery(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, }, }, @@ -127,12 +127,12 @@ func TestParseFromYamlWithTemplateBigQuery(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/bigtable/bigtable.go b/internal/tools/bigtable/bigtable.go index 44e80c835d..ef0a03e9bd 100644 --- a/internal/tools/bigtable/bigtable.go +++ b/internal/tools/bigtable/bigtable.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" bigtabledb "github.com/googleapis/genai-toolbox/internal/sources/bigtable" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "bigtable-sql" @@ -51,14 +52,14 @@ var _ compatibleSource = &bigtabledb.Source{} var compatibleSources = [...]string{bigtabledb.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -81,7 +82,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -108,12 +109,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Client *bigtable.Client Statement string @@ -138,7 +139,7 @@ func getBigtableType(paramType string) (bigtable.SQLType, error) { } } -func getMapParamsType(tparams tools.Parameters, params tools.ParamValues) (map[string]bigtable.SQLType, error) { +func getMapParamsType(tparams parameters.Parameters, params parameters.ParamValues) (map[string]bigtable.SQLType, error) { btParamTypes := make(map[string]bigtable.SQLType) for _, p := range tparams { if p.GetType() == "array" { @@ -160,14 +161,14 @@ func getMapParamsType(tparams tools.Parameters, params tools.ParamValues) (map[s return btParamTypes, nil } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -213,8 +214,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/bigtable/bigtable_test.go b/internal/tools/bigtable/bigtable_test.go index dad5d2a5e7..6d12b341e2 100644 --- a/internal/tools/bigtable/bigtable_test.go +++ b/internal/tools/bigtable/bigtable_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/bigtable" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlBigtable(t *testing.T) { @@ -58,8 +58,8 @@ func TestParseFromYamlBigtable(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, }, }, @@ -127,12 +127,12 @@ func TestParseFromYamlWithTemplateBigtable(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/cassandra/cassandracql/cassandracql.go b/internal/tools/cassandra/cassandracql/cassandracql.go index 4f8adfea4e..229ef7592d 100644 --- a/internal/tools/cassandra/cassandracql/cassandracql.go +++ b/internal/tools/cassandra/cassandracql/cassandracql.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cassandra" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "cassandra-cql" @@ -50,14 +51,14 @@ var _ compatibleSource = &cassandra.Source{} var compatibleSources = [...]string{cassandra.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // Initialize implements tools.ToolConfig. @@ -74,7 +75,7 @@ func (c Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(c.TemplateParameters, c.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(c.TemplateParameters, c.Parameters) if err != nil { return nil, err } @@ -104,12 +105,12 @@ func (c Config) ToolConfigKind() string { var _ tools.ToolConfig = Config{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Session *gocql.Session Statement string @@ -128,14 +129,14 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } // Invoke implements tools.Tool. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -171,8 +172,8 @@ func (t Tool) McpManifest() tools.McpManifest { } // ParseParams implements tools.Tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } var _ tools.Tool = Tool{} diff --git a/internal/tools/cassandra/cassandracql/cassandracql_test.go b/internal/tools/cassandra/cassandracql/cassandracql_test.go index cf9a729f83..3ed76b33f2 100644 --- a/internal/tools/cassandra/cassandracql/cassandracql_test.go +++ b/internal/tools/cassandra/cassandracql/cassandracql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cassandra/cassandracql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlCassandra(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlCassandra(t *testing.T) { Description: "some description", Statement: "SELECT * FROM CQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -116,14 +116,14 @@ func TestParseFromYamlCassandra(t *testing.T) { Description: "some description", Statement: "SELECT * FROM CQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "some description."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go b/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go index 72c12ec5de..338b418ff6 100644 --- a/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go +++ b/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go @@ -22,6 +22,7 @@ import ( yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) type compatibleSource interface { @@ -71,18 +72,18 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", executeSQLKind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The SQL statement to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The SQL statement to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) t := ExecuteSQLTool{ Name: cfg.Name, Kind: executeSQLKind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.ClickHousePool(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -91,17 +92,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = ExecuteSQLTool{} type ExecuteSQLTool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t ExecuteSQLTool) Invoke(ctx context.Context, params tools.ParamValues, token tools.AccessToken) (any, error) { +func (t ExecuteSQLTool) Invoke(ctx context.Context, params parameters.ParamValues, token tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -166,8 +167,8 @@ func (t ExecuteSQLTool) Invoke(ctx context.Context, params tools.ParamValues, to return out, nil } -func (t ExecuteSQLTool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t ExecuteSQLTool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t ExecuteSQLTool) Manifest() tools.Manifest { diff --git a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go index 5105aa5dea..991edf1d01 100644 --- a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go +++ b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go @@ -22,6 +22,7 @@ import ( yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) type compatibleSource interface { @@ -47,12 +48,12 @@ func newListDatabasesConfig(ctx context.Context, name string, decoder *yaml.Deco } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` } var _ tools.ToolConfig = Config{} @@ -72,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", listDatabasesKind, compatibleSources) } - allParameters, paramManifest, _ := tools.ProcessParameters(nil, cfg.Parameters) + allParameters, paramManifest, _ := parameters.ProcessParameters(nil, cfg.Parameters) mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) t := Tool{ @@ -91,18 +92,18 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, token tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, token tools.AccessToken) (any, error) { // Query to list all databases query := "SHOW DATABASES" @@ -131,8 +132,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, token tools. return databases, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go index 26fcf43b5e..b8dd7782bb 100644 --- a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go +++ b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go @@ -22,7 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestListDatabasesConfigToolConfigKind(t *testing.T) { @@ -95,7 +95,7 @@ func TestParseFromYamlClickHouseListDatabases(t *testing.T) { func TestListDatabasesToolParseParams(t *testing.T) { tool := Tool{ - Parameters: tools.Parameters{}, + Parameters: parameters.Parameters{}, } params, err := tool.ParseParams(map[string]any{}, map[string]map[string]any{}) diff --git a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go index cabbb839e9..6d0d55cc46 100644 --- a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go +++ b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go @@ -22,6 +22,7 @@ import ( yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) type compatibleSource interface { @@ -48,12 +49,12 @@ func newListTablesConfig(ctx context.Context, name string, decoder *yaml.Decoder } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` } var _ tools.ToolConfig = Config{} @@ -73,16 +74,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", listTablesKind, compatibleSources) } - databaseParameter := tools.NewStringParameter(databaseKey, "The database to list tables from.") - parameters := tools.Parameters{databaseParameter} + databaseParameter := parameters.NewStringParameter(databaseKey, "The database to list tables from.") + params := parameters.Parameters{databaseParameter} - allParameters, paramManifest, _ := tools.ProcessParameters(nil, parameters) + allParameters, paramManifest, _ := parameters.ProcessParameters(nil, params) mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) t := Tool{ Name: cfg.Name, Kind: listTablesKind, - Parameters: parameters, + Parameters: params, AllParams: allParameters, AuthRequired: cfg.AuthRequired, Pool: s.ClickHousePool(), @@ -95,18 +96,18 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, token tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, token tools.AccessToken) (any, error) { mapParams := params.AsMap() database, ok := mapParams[databaseKey].(string) if !ok { @@ -142,8 +143,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, token tools. return tables, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go index d4dcaa8700..d2685563f8 100644 --- a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go +++ b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go @@ -22,7 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestListTablesConfigToolConfigKind(t *testing.T) { @@ -94,10 +94,10 @@ func TestParseFromYamlClickHouseListTables(t *testing.T) { } func TestListTablesToolParseParams(t *testing.T) { - databaseParam := tools.NewStringParameter("database", "The database to list tables from.") + databaseParam := parameters.NewStringParameter("database", "The database to list tables from.") tool := Tool{ - Parameters: tools.Parameters{databaseParam}, - AllParams: tools.Parameters{databaseParam}, + Parameters: parameters.Parameters{databaseParam}, + AllParams: parameters.Parameters{databaseParam}, } params, err := tool.ParseParams(map[string]any{"database": "test_db"}, map[string]map[string]any{}) diff --git a/internal/tools/clickhouse/clickhousesql/clickhousesql.go b/internal/tools/clickhouse/clickhousesql/clickhousesql.go index 6a4faeceeb..12c26853d9 100644 --- a/internal/tools/clickhouse/clickhousesql/clickhousesql.go +++ b/internal/tools/clickhouse/clickhousesql/clickhousesql.go @@ -22,6 +22,7 @@ import ( yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) type compatibleSource interface { @@ -47,14 +48,14 @@ func newSQLConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tool } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } var _ tools.ToolConfig = Config{} @@ -74,7 +75,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", sqlKind, compatibleSources) } - allParameters, paramManifest, _ := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, _ := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) t := Tool{ @@ -95,12 +96,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB Statement string @@ -108,14 +109,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, token tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, token tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params: %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params: %w", err) } @@ -181,8 +182,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, token tools. return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go b/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go index 0a1d37e612..346892596c 100644 --- a/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go +++ b/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/clickhouse" "github.com/googleapis/genai-toolbox/internal/testutils" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestConfigToolConfigKind(t *testing.T) { @@ -85,8 +86,8 @@ func TestParseFromYamlClickHouseSQL(t *testing.T) { Source: "test-source", Description: "Test ClickHouse tool", Statement: "SELECT * FROM test_table WHERE id = $1", - Parameters: tools.Parameters{ - tools.NewStringParameter("id", "Test ID"), + Parameters: parameters.Parameters{ + parameters.NewStringParameter("id", "Test ID"), }, AuthRequired: []string{}, }, @@ -116,7 +117,7 @@ func TestSQLConfigInitializeValidSource(t *testing.T) { Source: "test-clickhouse", Description: "Test tool", Statement: "SELECT 1", - Parameters: tools.Parameters{}, + Parameters: parameters.Parameters{}, } // Create a mock ClickHouse source @@ -148,7 +149,7 @@ func TestSQLConfigInitializeMissingSource(t *testing.T) { Source: "missing-source", Description: "Test tool", Statement: "SELECT 1", - Parameters: tools.Parameters{}, + Parameters: parameters.Parameters{}, } sources := map[string]sources.Source{} @@ -178,7 +179,7 @@ func TestSQLConfigInitializeIncompatibleSource(t *testing.T) { Source: "incompatible-source", Description: "Test tool", Statement: "SELECT 1", - Parameters: tools.Parameters{}, + Parameters: parameters.Parameters{}, } mockSource := &mockIncompatibleSource{} @@ -201,7 +202,7 @@ func TestToolManifest(t *testing.T) { tool := Tool{ manifest: tools.Manifest{ Description: "Test description", - Parameters: []tools.ParameterManifest{}, + Parameters: []parameters.ParameterManifest{}, }, } diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go index 74ce19e357..fd850d1767 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" "net/http" @@ -94,15 +95,15 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - urlParameter := tools.NewStringParameter(pageURLKey, "The full URL of the FHIR page to fetch. This would be the value of `Bundle.entry.link.url` field within the response returned from FHIR search or FHIR patient everything operations.") - parameters := tools.Parameters{urlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + urlParameter := parameters.NewStringParameter(pageURLKey, "The full URL of the FHIR page to fetch. This would be the value of `Bundle.entry.link.url` field within the response returned from FHIR search or FHIR patient everything operations.") + params := parameters.Parameters{urlParameter} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -111,7 +112,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -121,11 +122,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -135,7 +136,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { url, ok := params.AsMap()[pageURLKey].(string) if !ok { return nil, fmt.Errorf("invalid or missing '%s' parameter; expected a string", pageURLKey) @@ -185,8 +186,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return jsonMap, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go index bfbfb5fca3..7daf26dac8 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go @@ -26,6 +26,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/googleapi" "google.golang.org/api/healthcare/v1" ) @@ -94,20 +95,20 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - idParameter := tools.NewStringParameter(patientIDKey, "The ID of the patient FHIR resource for which the information is required") - typeFilterParameter := tools.NewArrayParameterWithDefault(typeFilterKey, []any{}, "List of FHIR resource types. If provided, only resources of the specified resource type(s) are returned.", tools.NewStringParameter("resourceType", "A FHIR resource type")) - sinceFilterParameter := tools.NewStringParameterWithDefault(sinceFilterKey, "", "If provided, only resources updated after this time are returned. The time uses the format YYYY-MM-DDThh:mm:ss.sss+zz:zz. The time must be specified to the second and include a time zone. For example, 2015-02-07T13:28:17.239+02:00 or 2017-01-01T00:00:00Z") - parameters := tools.Parameters{idParameter, typeFilterParameter, sinceFilterParameter} + idParameter := parameters.NewStringParameter(patientIDKey, "The ID of the patient FHIR resource for which the information is required") + typeFilterParameter := parameters.NewArrayParameterWithDefault(typeFilterKey, []any{}, "List of FHIR resource types. If provided, only resources of the specified resource type(s) are returned.", parameters.NewStringParameter("resourceType", "A FHIR resource type")) + sinceFilterParameter := parameters.NewStringParameterWithDefault(sinceFilterKey, "", "If provided, only resources updated after this time are returned. The time uses the format YYYY-MM-DDThh:mm:ss.sss+zz:zz. The time must be specified to the second and include a time zone. For example, 2015-02-07T13:28:17.239+02:00 or 2017-01-01T00:00:00Z") + params := parameters.Parameters{idParameter, typeFilterParameter, sinceFilterParameter} if len(s.AllowedFHIRStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The FHIR store ID to retrieve the resource from.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The FHIR store ID to retrieve the resource from.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -116,7 +117,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -126,11 +127,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -140,7 +141,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -170,7 +171,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken if !ok { return nil, fmt.Errorf("invalid '%s' parameter; expected a string array", typeFilterKey) } - typeFilterSlice, err := tools.ConvertAnySliceToTyped(types, "string") + typeFilterSlice, err := parameters.ConvertAnySliceToTyped(types, "string") if err != nil { return nil, fmt.Errorf("can't convert '%s' to array of strings: %s", typeFilterKey, err) } @@ -208,8 +209,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return jsonMap, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go index 8ef67ed96c..bad50aa711 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go @@ -26,6 +26,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/googleapi" "google.golang.org/api/healthcare/v1" ) @@ -110,38 +111,38 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{ - tools.NewStringParameterWithDefault(activeKey, "", "Whether the patient record is active. Use true or false"), - tools.NewStringParameterWithDefault(cityKey, "", "The city of the patient's address"), - tools.NewStringParameterWithDefault(countryKey, "", "The country of the patient's address"), - tools.NewStringParameterWithDefault(postalCodeKey, "", "The postal code of the patient's address"), - tools.NewStringParameterWithDefault(stateKey, "", "The state of the patient's address"), - tools.NewStringParameterWithDefault(addressSubstringKey, "", "A substring to search for in any address field"), - tools.NewStringParameterWithDefault(birthDateRangeKey, "", "A date range for the patient's birthdate in the format YYYY-MM-DD/YYYY-MM-DD. Omit the first or second date to indicate open-ended ranges (e.g. '/2000-01-01' or '1950-01-01/')"), - tools.NewStringParameterWithDefault(deathDateRangeKey, "", "A date range for the patient's death date in the format YYYY-MM-DD/YYYY-MM-DD. Omit the first or second date to indicate open-ended ranges (e.g. '/2000-01-01' or '1950-01-01/')"), - tools.NewStringParameterWithDefault(deceasedKey, "", "Whether the patient is deceased. Use true or false"), - tools.NewStringParameterWithDefault(emailKey, "", "The patient's email address"), - tools.NewStringParameterWithDefault(genderKey, "", "The patient's gender. Must be one of 'male', 'female', 'other', or 'unknown'"), - tools.NewStringParameterWithDefault(addressUseKey, "", "The use of the patient's address. Must be one of 'home', 'work', 'temp', 'old', or 'billing'"), - tools.NewStringParameterWithDefault(nameKey, "", "The patient's name. Can be a family name, given name, or both"), - tools.NewStringParameterWithDefault(givenNameKey, "", "A portion of the given name of the patient"), - tools.NewStringParameterWithDefault(familyNameKey, "", "A portion of the family name of the patient"), - tools.NewStringParameterWithDefault(phoneKey, "", "The patient's phone number"), - tools.NewStringParameterWithDefault(languageKey, "", "The patient's preferred language. Must be a valid BCP-47 code (e.g. 'en-US', 'es')"), - tools.NewStringParameterWithDefault(identifierKey, "", "An identifier for the patient"), - tools.NewBooleanParameterWithDefault(summaryKey, true, "Requests the server to return a subset of the resource. Return a limited subset of elements from the resource. Enabled by default to reduce response size. Use get-fhir-resource tool to get full resource details (preferred) or set to false to disable."), + params := parameters.Parameters{ + parameters.NewStringParameterWithDefault(activeKey, "", "Whether the patient record is active. Use true or false"), + parameters.NewStringParameterWithDefault(cityKey, "", "The city of the patient's address"), + parameters.NewStringParameterWithDefault(countryKey, "", "The country of the patient's address"), + parameters.NewStringParameterWithDefault(postalCodeKey, "", "The postal code of the patient's address"), + parameters.NewStringParameterWithDefault(stateKey, "", "The state of the patient's address"), + parameters.NewStringParameterWithDefault(addressSubstringKey, "", "A substring to search for in any address field"), + parameters.NewStringParameterWithDefault(birthDateRangeKey, "", "A date range for the patient's birthdate in the format YYYY-MM-DD/YYYY-MM-DD. Omit the first or second date to indicate open-ended ranges (e.g. '/2000-01-01' or '1950-01-01/')"), + parameters.NewStringParameterWithDefault(deathDateRangeKey, "", "A date range for the patient's death date in the format YYYY-MM-DD/YYYY-MM-DD. Omit the first or second date to indicate open-ended ranges (e.g. '/2000-01-01' or '1950-01-01/')"), + parameters.NewStringParameterWithDefault(deceasedKey, "", "Whether the patient is deceased. Use true or false"), + parameters.NewStringParameterWithDefault(emailKey, "", "The patient's email address"), + parameters.NewStringParameterWithDefault(genderKey, "", "The patient's gender. Must be one of 'male', 'female', 'other', or 'unknown'"), + parameters.NewStringParameterWithDefault(addressUseKey, "", "The use of the patient's address. Must be one of 'home', 'work', 'temp', 'old', or 'billing'"), + parameters.NewStringParameterWithDefault(nameKey, "", "The patient's name. Can be a family name, given name, or both"), + parameters.NewStringParameterWithDefault(givenNameKey, "", "A portion of the given name of the patient"), + parameters.NewStringParameterWithDefault(familyNameKey, "", "A portion of the family name of the patient"), + parameters.NewStringParameterWithDefault(phoneKey, "", "The patient's phone number"), + parameters.NewStringParameterWithDefault(languageKey, "", "The patient's preferred language. Must be a valid BCP-47 code (e.g. 'en-US', 'es')"), + parameters.NewStringParameterWithDefault(identifierKey, "", "An identifier for the patient"), + parameters.NewBooleanParameterWithDefault(summaryKey, true, "Requests the server to return a subset of the resource. Return a limited subset of elements from the resource. Enabled by default to reduce response size. Use get-fhir-resource tool to get full resource details (preferred) or set to false to disable."), } if len(s.AllowedFHIRStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The FHIR store ID to retrieve the resource from.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The FHIR store ID to retrieve the resource from.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -150,7 +151,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -160,11 +161,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -174,7 +175,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -281,8 +282,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return jsonMap, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go index f8ca992ab0..f4b73dcc26 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -83,14 +84,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -98,7 +99,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -108,11 +109,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string Service *healthcare.Service @@ -121,7 +122,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { svc := t.Service var err error @@ -145,8 +146,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return dataset, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go index 34092759a3..2a013fe6f4 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go @@ -23,6 +23,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -85,17 +86,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} + params := parameters.Parameters{} if len(s.AllowedDICOMStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -104,7 +105,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -114,11 +115,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -128,7 +129,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -155,8 +156,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return store, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go index e21870d1cd..baf16498b4 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go @@ -23,6 +23,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -85,17 +86,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} + params := parameters.Parameters{} if len(s.AllowedDICOMStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The DICOM store ID to get metrics for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The DICOM store ID to get metrics for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -104,7 +105,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -114,11 +115,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -128,7 +129,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -155,8 +156,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return store, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go index 12e6a195f0..8e2236b58a 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go @@ -25,6 +25,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -91,19 +92,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - typeParameter := tools.NewStringParameter(typeKey, "The FHIR resource type to retrieve (e.g., Patient, Observation).") - idParameter := tools.NewStringParameter(idKey, "The ID of the FHIR resource to retrieve.") - parameters := tools.Parameters{typeParameter, idParameter} + typeParameter := parameters.NewStringParameter(typeKey, "The FHIR resource type to retrieve (e.g., Patient, Observation).") + idParameter := parameters.NewStringParameter(idKey, "The ID of the FHIR resource to retrieve.") + params := parameters.Parameters{typeParameter, idParameter} if len(s.AllowedFHIRStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The FHIR store ID to retrieve the resource from.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The FHIR store ID to retrieve the resource from.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -112,7 +113,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -122,11 +123,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -136,7 +137,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -187,8 +188,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return jsonMap, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go index ebd5d8646c..aaf10d5c1f 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go @@ -23,6 +23,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -85,17 +86,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} + params := parameters.Parameters{} if len(s.AllowedFHIRStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The FHIR store ID to get details for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The FHIR store ID to get details for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -104,7 +105,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -114,11 +115,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -128,7 +129,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -155,8 +156,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return store, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go index d8ad394001..3419d3f722 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go @@ -23,6 +23,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -85,17 +86,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} + params := parameters.Parameters{} if len(s.AllowedFHIRStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The FHIR store ID to get metrics for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The FHIR store ID to get metrics for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -104,7 +105,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -114,11 +115,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -128,7 +129,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -155,8 +156,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return store, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go b/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go index 4048e40b63..b3c7c64228 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -85,14 +86,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -101,7 +102,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -111,11 +112,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -125,7 +126,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { svc := t.Service var err error @@ -163,8 +164,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return filtered, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go b/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go index ff7955cd6e..eb93f9e142 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -85,14 +86,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -101,7 +102,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -111,11 +112,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -125,7 +126,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { svc := t.Service var err error @@ -163,8 +164,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return filtered, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go b/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go index 2861410a1d..0b176d66aa 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go +++ b/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go @@ -25,6 +25,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -93,22 +94,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{ - tools.NewStringParameter(studyInstanceUIDKey, "The UID of the DICOM study"), - tools.NewStringParameter(seriesInstanceUIDKey, "The UID of the DICOM series"), - tools.NewStringParameter(sopInstanceUIDKey, "The UID of the SOP instance."), - tools.NewIntParameterWithDefault(frameNumberKey, 1, "The frame number to retrieve (1-based). Only applicable to multi-frame instances."), + params := parameters.Parameters{ + parameters.NewStringParameter(studyInstanceUIDKey, "The UID of the DICOM study"), + parameters.NewStringParameter(seriesInstanceUIDKey, "The UID of the DICOM series"), + parameters.NewStringParameter(sopInstanceUIDKey, "The UID of the SOP instance."), + parameters.NewIntParameterWithDefault(frameNumberKey, 1, "The frame number to retrieve (1-based). Only applicable to multi-frame instances."), } if len(s.AllowedDICOMStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -117,7 +118,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -127,11 +128,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -141,7 +142,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -197,8 +198,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return base64String, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go index f8114c6c80..dc4d5dd1e2 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go @@ -26,6 +26,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/googleapi" "google.golang.org/api/healthcare/v1" ) @@ -100,29 +101,29 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{ - tools.NewStringParameterWithDefault(studyInstanceUIDKey, "", "The UID of the DICOM study"), - tools.NewStringParameterWithDefault(patientNameKey, "", "The name of the patient"), - tools.NewStringParameterWithDefault(patientIDKey, "", "The ID of the patient"), - tools.NewStringParameterWithDefault(accessionNumberKey, "", "The accession number of the series"), - tools.NewStringParameterWithDefault(referringPhysicianNameKey, "", "The name of the referring physician"), - tools.NewStringParameterWithDefault(studyDateKey, "", "The date of the study in the format `YYYYMMDD`. You can also specify a date range in the format `YYYYMMDD-YYYYMMDD`"), - tools.NewStringParameterWithDefault(seriesInstanceUIDKey, "", "The UID of the DICOM series"), - tools.NewStringParameterWithDefault(modalityKey, "", "The modality of the series"), - tools.NewStringParameterWithDefault(sopInstanceUIDKey, "", "The UID of the SOP instance."), - tools.NewBooleanParameterWithDefault(common.EnablePatientNameFuzzyMatchingKey, false, `Whether to enable fuzzy matching for patient names. Fuzzy matching will perform tokenization and normalization of both the value of PatientName in the query and the stored value. It will match if any search token is a prefix of any stored token. For example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match`), - tools.NewArrayParameterWithDefault(common.IncludeAttributesKey, []any{}, "List of attributeIDs, such as DICOM tag IDs or keywords. Set to [\"all\"] to return all available tags.", tools.NewStringParameter("attributeID", "The attributeID to include. Set to 'all' to return all available tags")), + params := parameters.Parameters{ + parameters.NewStringParameterWithDefault(studyInstanceUIDKey, "", "The UID of the DICOM study"), + parameters.NewStringParameterWithDefault(patientNameKey, "", "The name of the patient"), + parameters.NewStringParameterWithDefault(patientIDKey, "", "The ID of the patient"), + parameters.NewStringParameterWithDefault(accessionNumberKey, "", "The accession number of the series"), + parameters.NewStringParameterWithDefault(referringPhysicianNameKey, "", "The name of the referring physician"), + parameters.NewStringParameterWithDefault(studyDateKey, "", "The date of the study in the format `YYYYMMDD`. You can also specify a date range in the format `YYYYMMDD-YYYYMMDD`"), + parameters.NewStringParameterWithDefault(seriesInstanceUIDKey, "", "The UID of the DICOM series"), + parameters.NewStringParameterWithDefault(modalityKey, "", "The modality of the series"), + parameters.NewStringParameterWithDefault(sopInstanceUIDKey, "", "The UID of the SOP instance."), + parameters.NewBooleanParameterWithDefault(common.EnablePatientNameFuzzyMatchingKey, false, `Whether to enable fuzzy matching for patient names. Fuzzy matching will perform tokenization and normalization of both the value of PatientName in the query and the stored value. It will match if any search token is a prefix of any stored token. For example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match`), + parameters.NewArrayParameterWithDefault(common.IncludeAttributesKey, []any{}, "List of attributeIDs, such as DICOM tag IDs or keywords. Set to [\"all\"] to return all available tags.", parameters.NewStringParameter("attributeID", "The attributeID to include. Set to 'all' to return all available tags")), } if len(s.AllowedDICOMStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -131,7 +132,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -141,11 +142,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -155,7 +156,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -227,8 +228,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go index fb55446471..8c31d643ce 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go @@ -25,6 +25,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -97,28 +98,28 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{ - tools.NewStringParameterWithDefault(studyInstanceUIDKey, "", "The UID of the DICOM study"), - tools.NewStringParameterWithDefault(patientNameKey, "", "The name of the patient"), - tools.NewStringParameterWithDefault(patientIDKey, "", "The ID of the patient"), - tools.NewStringParameterWithDefault(accessionNumberKey, "", "The accession number of the series"), - tools.NewStringParameterWithDefault(referringPhysicianNameKey, "", "The name of the referring physician"), - tools.NewStringParameterWithDefault(studyDateKey, "", "The date of the study in the format `YYYYMMDD`. You can also specify a date range in the format `YYYYMMDD-YYYYMMDD`"), - tools.NewStringParameterWithDefault(seriesInstanceUIDKey, "", "The UID of the DICOM series"), - tools.NewStringParameterWithDefault(modalityKey, "", "The modality of the series"), - tools.NewBooleanParameterWithDefault(common.EnablePatientNameFuzzyMatchingKey, false, `Whether to enable fuzzy matching for patient names. Fuzzy matching will perform tokenization and normalization of both the value of PatientName in the query and the stored value. It will match if any search token is a prefix of any stored token. For example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match`), - tools.NewArrayParameterWithDefault(common.IncludeAttributesKey, []any{}, "List of attributeIDs, such as DICOM tag IDs or keywords. Set to [\"all\"] to return all available tags.", tools.NewStringParameter("attributeID", "The attributeID to include. Set to 'all' to return all available tags")), + params := parameters.Parameters{ + parameters.NewStringParameterWithDefault(studyInstanceUIDKey, "", "The UID of the DICOM study"), + parameters.NewStringParameterWithDefault(patientNameKey, "", "The name of the patient"), + parameters.NewStringParameterWithDefault(patientIDKey, "", "The ID of the patient"), + parameters.NewStringParameterWithDefault(accessionNumberKey, "", "The accession number of the series"), + parameters.NewStringParameterWithDefault(referringPhysicianNameKey, "", "The name of the referring physician"), + parameters.NewStringParameterWithDefault(studyDateKey, "", "The date of the study in the format `YYYYMMDD`. You can also specify a date range in the format `YYYYMMDD-YYYYMMDD`"), + parameters.NewStringParameterWithDefault(seriesInstanceUIDKey, "", "The UID of the DICOM series"), + parameters.NewStringParameterWithDefault(modalityKey, "", "The modality of the series"), + parameters.NewBooleanParameterWithDefault(common.EnablePatientNameFuzzyMatchingKey, false, `Whether to enable fuzzy matching for patient names. Fuzzy matching will perform tokenization and normalization of both the value of PatientName in the query and the stored value. It will match if any search token is a prefix of any stored token. For example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match`), + parameters.NewArrayParameterWithDefault(common.IncludeAttributesKey, []any{}, "List of attributeIDs, such as DICOM tag IDs or keywords. Set to [\"all\"] to return all available tags.", parameters.NewStringParameter("attributeID", "The attributeID to include. Set to 'all' to return all available tags")), } if len(s.AllowedDICOMStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -127,7 +128,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -137,11 +138,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -151,7 +152,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -210,8 +211,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go index 310dea2901..0841b33609 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go @@ -25,6 +25,7 @@ import ( healthcareds "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/common" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/healthcare/v1" ) @@ -95,26 +96,26 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{ - tools.NewStringParameterWithDefault(studyInstanceUIDKey, "", "The UID of the DICOM study"), - tools.NewStringParameterWithDefault(patientNameKey, "", "The name of the patient"), - tools.NewStringParameterWithDefault(patientIDKey, "", "The ID of the patient"), - tools.NewStringParameterWithDefault(accessionNumberKey, "", "The accession number of the study"), - tools.NewStringParameterWithDefault(referringPhysicianNameKey, "", "The name of the referring physician"), - tools.NewStringParameterWithDefault(studyDateKey, "", "The date of the study in the format `YYYYMMDD`. You can also specify a date range in the format `YYYYMMDD-YYYYMMDD`"), - tools.NewBooleanParameterWithDefault(common.EnablePatientNameFuzzyMatchingKey, false, `Whether to enable fuzzy matching for patient names. Fuzzy matching will perform tokenization and normalization of both the value of PatientName in the query and the stored value. It will match if any search token is a prefix of any stored token. For example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match`), - tools.NewArrayParameterWithDefault(common.IncludeAttributesKey, []any{}, "List of attributeIDs, such as DICOM tag IDs or keywords. Set to [\"all\"] to return all available tags.", tools.NewStringParameter("attributeID", "The attributeID to include. Set to 'all' to return all available tags")), + params := parameters.Parameters{ + parameters.NewStringParameterWithDefault(studyInstanceUIDKey, "", "The UID of the DICOM study"), + parameters.NewStringParameterWithDefault(patientNameKey, "", "The name of the patient"), + parameters.NewStringParameterWithDefault(patientIDKey, "", "The ID of the patient"), + parameters.NewStringParameterWithDefault(accessionNumberKey, "", "The accession number of the study"), + parameters.NewStringParameterWithDefault(referringPhysicianNameKey, "", "The name of the referring physician"), + parameters.NewStringParameterWithDefault(studyDateKey, "", "The date of the study in the format `YYYYMMDD`. You can also specify a date range in the format `YYYYMMDD-YYYYMMDD`"), + parameters.NewBooleanParameterWithDefault(common.EnablePatientNameFuzzyMatchingKey, false, `Whether to enable fuzzy matching for patient names. Fuzzy matching will perform tokenization and normalization of both the value of PatientName in the query and the stored value. It will match if any search token is a prefix of any stored token. For example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match`), + parameters.NewArrayParameterWithDefault(common.IncludeAttributesKey, []any{}, "List of attributeIDs, such as DICOM tag IDs or keywords. Set to [\"all\"] to return all available tags.", parameters.NewStringParameter("attributeID", "The attributeID to include. Set to 'all' to return all available tags")), } if len(s.AllowedDICOMStores()) != 1 { - parameters = append(parameters, tools.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) + params = append(params, parameters.NewStringParameter(common.StoreKey, "The DICOM store ID to get details for.")) } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Project: s.Project(), Region: s.Region(), @@ -123,7 +124,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) UseClientOAuth: s.UseClientAuthorization(), ServiceCreator: s.ServiceCreator(), Service: s.Service(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -133,11 +134,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project, Region, Dataset string AllowedStores map[string]struct{} @@ -147,7 +148,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { storeID, err := common.ValidateAndFetchStoreID(params, t.AllowedStores) if err != nil { return nil, err @@ -194,8 +195,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudhealthcare/common/util.go b/internal/tools/cloudhealthcare/common/util.go index 481b5cd2f1..6ec9102906 100644 --- a/internal/tools/cloudhealthcare/common/util.go +++ b/internal/tools/cloudhealthcare/common/util.go @@ -19,7 +19,7 @@ import ( "slices" "strings" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/googleapi" ) @@ -37,7 +37,7 @@ const IncludeAttributesKey = "includefield" // ValidateAndFetchStoreID validates the provided storeID against the allowedStores. // If only one store is allowed, it returns that storeID. // If multiple stores are allowed, it checks if the storeID parameter is in the allowed list. -func ValidateAndFetchStoreID(params tools.ParamValues, allowedStores map[string]struct{}) (string, error) { +func ValidateAndFetchStoreID(params parameters.ParamValues, allowedStores map[string]struct{}) (string, error) { if len(allowedStores) == 1 { for k := range allowedStores { return k, nil @@ -58,14 +58,14 @@ func ValidateAndFetchStoreID(params tools.ParamValues, allowedStores map[string] // ParseDICOMSearchParameters extracts the search parameters for various DICOM // search methods. -func ParseDICOMSearchParameters(params tools.ParamValues, paramKeys []string) ([]googleapi.CallOption, error) { +func ParseDICOMSearchParameters(params parameters.ParamValues, paramKeys []string) ([]googleapi.CallOption, error) { var opts []googleapi.CallOption for k, v := range params.AsMap() { if k == IncludeAttributesKey { if _, ok := v.([]any); !ok { return nil, fmt.Errorf("invalid '%s' parameter; expected a string array", k) } - attributeIDsSlice, err := tools.ConvertAnySliceToTyped(v.([]any), "string") + attributeIDsSlice, err := parameters.ConvertAnySliceToTyped(v.([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert '%s' to array of strings: %s", k, err) } diff --git a/internal/tools/cloudmonitoring/cloudmonitoring.go b/internal/tools/cloudmonitoring/cloudmonitoring.go index 5e37059aab..8dd7a9776a 100644 --- a/internal/tools/cloudmonitoring/cloudmonitoring.go +++ b/internal/tools/cloudmonitoring/cloudmonitoring.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" cloudmonitoringsrc "github.com/googleapis/genai-toolbox/internal/sources/cloudmonitoring" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "cloud-monitoring-query-prometheus" @@ -72,9 +73,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } // Define the parameters internally instead of from the config file. - allParameters := tools.Parameters{ - tools.NewStringParameterWithRequired("projectId", "The Id of the Google Cloud project.", true), - tools.NewStringParameterWithRequired("query", "The promql query to execute.", true), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithRequired("projectId", "The Id of the Google Cloud project.", true), + parameters.NewStringParameterWithRequired("query", "The promql query to execute.", true), } mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -96,18 +97,18 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - Description string `yaml:"description"` - AllParams tools.Parameters `yaml:"allParams"` - BaseURL string `yaml:"baseURL"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + Description string `yaml:"description"` + AllParams parameters.Parameters `yaml:"allParams"` + BaseURL string `yaml:"baseURL"` UserAgent string Client *http.Client manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() projectID, ok := paramsMap["projectId"].(string) if !ok { @@ -158,8 +159,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/cloudmonitoring/cloudmonitoring_test.go b/internal/tools/cloudmonitoring/cloudmonitoring_test.go index cbf17697d1..3c059a2a9e 100644 --- a/internal/tools/cloudmonitoring/cloudmonitoring_test.go +++ b/internal/tools/cloudmonitoring/cloudmonitoring_test.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/testutils" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudmonitoring" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // mockIncompatibleSource is a source of a different kind to test error paths. @@ -39,9 +40,9 @@ func TestInitialize(t *testing.T) { "incompatible-source": &mockIncompatibleSource{}, } - wantParams := tools.Parameters{ - tools.NewStringParameterWithRequired("projectId", "The Id of the Google Cloud project.", true), - tools.NewStringParameterWithRequired("query", "The promql query to execute.", true), + wantParams := parameters.Parameters{ + parameters.NewStringParameterWithRequired("projectId", "The Id of the Google Cloud project.", true), + parameters.NewStringParameterWithRequired("query", "The promql query to execute.", true), } testCases := []struct { diff --git a/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go b/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go index 0c918acf82..9683ce1706 100644 --- a/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go +++ b/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" sqladmin "google.golang.org/api/sqladmin/v1" ) @@ -70,17 +71,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("instance", "The ID of the instance where the database will be created."), - tools.NewStringParameter("name", "The name for the new database. Must be unique within the instance."), + parameters.NewStringParameter("instance", "The ID of the instance where the database will be created."), + parameters.NewStringParameter("name", "The name for the new database. Must be unique within the instance."), } paramManifest := allParameters.Manifest() @@ -109,13 +110,13 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *cloudsqladmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -151,8 +152,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go b/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go index 55b2e5d9a1..4e213a33a6 100644 --- a/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go +++ b/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" sqladmin "google.golang.org/api/sqladmin/v1" ) @@ -70,19 +71,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("instance", "The ID of the instance where the user will be created."), - tools.NewStringParameter("name", "The name for the new user. Must be unique within the instance."), - tools.NewStringParameterWithRequired("password", "A secure password for the new user. Not required for IAM users.", false), - tools.NewBooleanParameter("iamUser", "Set to true to create a Cloud IAM user."), + parameters.NewStringParameter("instance", "The ID of the instance where the user will be created."), + parameters.NewStringParameter("name", "The name for the new user. Must be unique within the instance."), + parameters.NewStringParameterWithRequired("password", "A secure password for the new user. Not required for IAM users.", false), + parameters.NewBooleanParameter("iamUser", "Set to true to create a Cloud IAM user."), } paramManifest := allParameters.Manifest() @@ -111,13 +112,13 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *cloudsqladmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -164,8 +165,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go b/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go index 60025bc3d9..c31b1b68dc 100644 --- a/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go +++ b/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "cloud-sql-get-instance" @@ -70,16 +71,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("projectId", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("projectId", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("projectId", "The project ID") + projectParam = parameters.NewStringParameter("projectId", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("instanceId", "The instance ID"), + parameters.NewStringParameter("instanceId", "The instance ID"), } paramManifest := allParameters.Manifest() @@ -108,13 +109,13 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *cloudsqladmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() projectId, ok := paramsMap["projectId"].(string) @@ -140,8 +141,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go b/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go index 453e8b5715..a14964ca64 100644 --- a/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go +++ b/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" cloudsqladminsrc "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "cloud-sql-list-databases" @@ -69,16 +70,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("instance", "The instance ID"), + parameters.NewStringParameter("instance", "The instance ID"), } paramManifest := allParameters.Manifest() @@ -106,14 +107,14 @@ type Tool struct { Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` Source *cloudsqladminsrc.Source manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -158,8 +159,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go b/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go index e7ea6c7505..dd38c7b008 100644 --- a/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go +++ b/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" cloudsqladminsrc "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "cloud-sql-list-instances" @@ -69,14 +70,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, } paramManifest := allParameters.Manifest() @@ -105,14 +106,14 @@ type Tool struct { Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` Source *cloudsqladminsrc.Source manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -151,8 +152,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go b/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go index 80ae4fc71e..c4b30d26c6 100644 --- a/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go +++ b/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go @@ -27,6 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "cloud-sql-wait-for-operation" @@ -123,16 +124,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("operation", "The operation ID"), + parameters.NewStringParameter("operation", "The operation ID"), } paramManifest := allParameters.Manifest() @@ -197,7 +198,7 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *cloudsqladmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` // Polling configuration Delay time.Duration @@ -210,7 +211,7 @@ type Tool struct { } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -287,8 +288,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go b/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go index e738831463..842103d036 100644 --- a/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go +++ b/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" sqladmin "google.golang.org/api/sqladmin/v1" ) @@ -71,19 +72,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("name", "The name of the instance"), - tools.NewStringParameterWithDefault("databaseVersion", "SQLSERVER_2022_STANDARD", "The database version for SQL Server. If not specified, defaults to SQLSERVER_2022_STANDARD."), - tools.NewStringParameter("rootPassword", "The root password for the instance"), - tools.NewStringParameterWithDefault("editionPreset", "Development", "The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`."), + parameters.NewStringParameter("name", "The name of the instance"), + parameters.NewStringParameterWithDefault("databaseVersion", "SQLSERVER_2022_STANDARD", "The database version for SQL Server. If not specified, defaults to SQLSERVER_2022_STANDARD."), + parameters.NewStringParameter("rootPassword", "The root password for the instance"), + parameters.NewStringParameterWithDefault("editionPreset", "Development", "The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`."), } paramManifest := allParameters.Manifest() @@ -112,13 +113,13 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *cloudsqladmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -182,8 +183,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go b/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go index ebacfa19a2..ad1e62893b 100644 --- a/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go +++ b/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" sqladmin "google.golang.org/api/sqladmin/v1" ) @@ -71,19 +72,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("name", "The name of the instance"), - tools.NewStringParameterWithDefault("databaseVersion", "MYSQL_8_4", "The database version for MySQL. If not specified, defaults to the latest available version (e.g., MYSQL_8_4)."), - tools.NewStringParameter("rootPassword", "The root password for the instance"), - tools.NewStringParameterWithDefault("editionPreset", "Development", "The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`."), + parameters.NewStringParameter("name", "The name of the instance"), + parameters.NewStringParameterWithDefault("databaseVersion", "MYSQL_8_4", "The database version for MySQL. If not specified, defaults to the latest available version (e.g., MYSQL_8_4)."), + parameters.NewStringParameter("rootPassword", "The root password for the instance"), + parameters.NewStringParameterWithDefault("editionPreset", "Development", "The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`."), } paramManifest := allParameters.Manifest() @@ -112,13 +113,13 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *cloudsqladmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -182,8 +183,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go b/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go index 1ee95c1bb8..66552fff7d 100644 --- a/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go +++ b/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" sqladmin "google.golang.org/api/sqladmin/v1" ) @@ -71,19 +72,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } project := s.DefaultProject - var projectParam tools.Parameter + var projectParam parameters.Parameter if project != "" { - projectParam = tools.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") + projectParam = parameters.NewStringParameterWithDefault("project", project, "The GCP project ID. This is pre-configured; do not ask for it unless the user explicitly provides a different one.") } else { - projectParam = tools.NewStringParameter("project", "The project ID") + projectParam = parameters.NewStringParameter("project", "The project ID") } - allParameters := tools.Parameters{ + allParameters := parameters.Parameters{ projectParam, - tools.NewStringParameter("name", "The name of the instance"), - tools.NewStringParameterWithDefault("databaseVersion", "POSTGRES_17", "The database version for Postgres. If not specified, defaults to the latest available version (e.g., POSTGRES_17)."), - tools.NewStringParameter("rootPassword", "The root password for the instance"), - tools.NewStringParameterWithDefault("editionPreset", "Development", "The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`."), + parameters.NewStringParameter("name", "The name of the instance"), + parameters.NewStringParameterWithDefault("databaseVersion", "POSTGRES_17", "The database version for Postgres. If not specified, defaults to the latest available version (e.g., POSTGRES_17)."), + parameters.NewStringParameter("rootPassword", "The root password for the instance"), + parameters.NewStringParameterWithDefault("editionPreset", "Development", "The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`."), } paramManifest := allParameters.Manifest() @@ -112,13 +113,13 @@ type Tool struct { AuthRequired []string `yaml:"authRequired"` Source *cloudsqladmin.Source - AllParams tools.Parameters `yaml:"allParams"` + AllParams parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } // Invoke executes the tool's logic. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() project, ok := paramsMap["project"].(string) @@ -182,8 +183,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool's manifest. diff --git a/internal/tools/couchbase/couchbase.go b/internal/tools/couchbase/couchbase.go index 621af9043a..4bdc5fbcc8 100644 --- a/internal/tools/couchbase/couchbase.go +++ b/internal/tools/couchbase/couchbase.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/couchbase" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "couchbase-sql" @@ -53,14 +54,14 @@ var _ compatibleSource = &couchbase.Source{} var compatibleSources = [...]string{couchbase.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -83,7 +84,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -110,12 +111,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` - AuthRequired []string `yaml:"authRequired"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` + AuthRequired []string `yaml:"authRequired"` Scope *gocb.Scope QueryScanConsistency uint @@ -124,14 +125,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { namedParamsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, namedParamsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, namedParamsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, namedParamsMap) + newParams, err := parameters.GetParams(t.Parameters, namedParamsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -155,8 +156,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claimsMap) +func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claimsMap) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/couchbase/couchbase_test.go b/internal/tools/couchbase/couchbase_test.go index 6920625013..6f8f2bc459 100644 --- a/internal/tools/couchbase/couchbase_test.go +++ b/internal/tools/couchbase/couchbase_test.go @@ -18,12 +18,12 @@ import ( "testing" "github.com/googleapis/genai-toolbox/internal/tools/couchbase" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" ) func TestParseFromYamlCouchbase(t *testing.T) { @@ -55,8 +55,8 @@ func TestParseFromYamlCouchbase(t *testing.T) { Source: "my-couchbase-instance", Description: "some tool description", Statement: "select * from hotel WHERE name = $hotel;\n", - Parameters: []tools.Parameter{ - tools.NewStringParameter("hotel", "hotel parameter description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("hotel", "hotel parameter description"), }, }, }, @@ -123,11 +123,11 @@ func TestParseFromYamlWithTemplateMssql(t *testing.T) { Source: "my-couchbase-instance", Description: "some tool description", Statement: "select * from {{.tableName}} WHERE name = $hotel;\n", - Parameters: []tools.Parameter{ - tools.NewStringParameter("hotel", "hotel parameter description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("hotel", "hotel parameter description"), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), }, }, }, diff --git a/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go b/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go index 1a08e25152..ce0379ad46 100644 --- a/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go +++ b/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go @@ -23,6 +23,7 @@ import ( "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "dataform-compile-local" @@ -55,8 +56,8 @@ func (cfg Config) ToolConfigKind() string { } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { - allParameters := tools.Parameters{ - tools.NewStringParameter("project_dir", "The Dataform project directory."), + allParameters := parameters.Parameters{ + parameters.NewStringParameter("project_dir", "The Dataform project directory."), } paramManifest := allParameters.Manifest() mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -76,15 +77,15 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"allParams"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() projectDir, ok := paramsMap["project_dir"].(string) @@ -101,8 +102,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return strings.TrimSpace(string(output)), nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go index 89bef0cda7..2964f42b98 100644 --- a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go +++ b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" dataplexds "github.com/googleapis/genai-toolbox/internal/sources/dataplex" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "dataplex-lookup-entry" @@ -52,12 +53,12 @@ var _ compatibleSource = &dataplexds.Source{} var compatibleSources = [...]string{dataplexds.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` } // validate interface @@ -94,23 +95,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) * 4 (ALL): Return the entry and both required and optional aspects (at most 100 aspects) ` - name := tools.NewStringParameter("name", "The project to which the request should be attributed in the following form: projects/{project}/locations/{location}.") - view := tools.NewIntParameterWithDefault("view", 2, viewDesc) - aspectTypes := tools.NewArrayParameterWithDefault("aspectTypes", []any{}, "Limits the aspects returned to the provided aspect types. It only works when used together with CUSTOM view.", tools.NewStringParameter("aspectType", "The types of aspects to be included in the response in the format `projects/{project}/locations/{location}/aspectTypes/{aspectType}`.")) - entry := tools.NewStringParameter("entry", "The resource name of the Entry in the following form: projects/{project}/locations/{location}/entryGroups/{entryGroup}/entries/{entry}.") - parameters := tools.Parameters{name, view, aspectTypes, entry} + name := parameters.NewStringParameter("name", "The project to which the request should be attributed in the following form: projects/{project}/locations/{location}.") + view := parameters.NewIntParameterWithDefault("view", 2, viewDesc) + aspectTypes := parameters.NewArrayParameterWithDefault("aspectTypes", []any{}, "Limits the aspects returned to the provided aspect types. It only works when used together with CUSTOM view.", parameters.NewStringParameter("aspectType", "The types of aspects to be included in the response in the format `projects/{project}/locations/{location}/aspectTypes/{aspectType}`.")) + entry := parameters.NewStringParameter("entry", "The resource name of the Entry in the following form: projects/{project}/locations/{location}/entryGroups/{entryGroup}/entries/{entry}.") + params := parameters.Parameters{name, view, aspectTypes, entry} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, CatalogClient: s.CatalogClient(), manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -121,14 +122,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) type Tool struct { Name string Kind string - Parameters tools.Parameters + Parameters parameters.Parameters AuthRequired []string CatalogClient *dataplexapi.CatalogClient manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() viewMap := map[int]dataplexpb.EntryView{ 1: dataplexpb.EntryView_BASIC, @@ -139,7 +140,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken name, _ := paramsMap["name"].(string) entry, _ := paramsMap["entry"].(string) view, _ := paramsMap["view"].(int) - aspectTypeSlice, err := tools.ConvertAnySliceToTyped(paramsMap["aspectTypes"].([]any), "string") + aspectTypeSlice, err := parameters.ConvertAnySliceToTyped(paramsMap["aspectTypes"].([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert aspectTypes to array of strings: %s", err) } @@ -159,9 +160,9 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { // Parse parameters from the provided data - return tools.ParseParams(t.Parameters, data, claims) + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go index a1b9cde8ec..8c3d5942c2 100644 --- a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go +++ b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/dataplex/dataplexlookupentry" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlDataplexLookupEntry(t *testing.T) { @@ -88,11 +88,11 @@ func TestParseFromYamlDataplexLookupEntry(t *testing.T) { Source: "my-instance", Description: "some description", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("name", "some name description"), - tools.NewStringParameter("view", "some view description"), - tools.NewArrayParameterWithDefault("aspectTypes", []any{}, "some aspect types description", tools.NewStringParameter("aspectType", "some aspect type description")), - tools.NewStringParameter("entry", "some entry description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("name", "some name description"), + parameters.NewStringParameter("view", "some view description"), + parameters.NewArrayParameterWithDefault("aspectTypes", []any{}, "some aspect types description", parameters.NewStringParameter("aspectType", "some aspect type description")), + parameters.NewStringParameter("entry", "some entry description"), }, }, }, diff --git a/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go b/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go index 1df9d2e08b..4422e54f41 100644 --- a/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go +++ b/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" dataplexds "github.com/googleapis/genai-toolbox/internal/sources/dataplex" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "dataplex-search-aspect-types" @@ -80,23 +81,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - query := tools.NewStringParameter("query", "The query against which aspect type should be matched.") - pageSize := tools.NewIntParameterWithDefault("pageSize", 5, "Number of returned aspect types in the search page.") - orderBy := tools.NewStringParameterWithDefault("orderBy", "relevance", "Specifies the ordering of results. Supported values are: relevance, last_modified_timestamp, last_modified_timestamp asc") - parameters := tools.Parameters{query, pageSize, orderBy} + query := parameters.NewStringParameter("query", "The query against which aspect type should be matched.") + pageSize := parameters.NewIntParameterWithDefault("pageSize", 5, "Number of returned aspect types in the search page.") + orderBy := parameters.NewStringParameterWithDefault("orderBy", "relevance", "Specifies the ordering of results. Supported values are: relevance, last_modified_timestamp, last_modified_timestamp asc") + params := parameters.Parameters{query, pageSize, orderBy} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, CatalogClient: s.CatalogClient(), ProjectID: s.ProjectID(), manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -107,7 +108,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) type Tool struct { Name string Kind string - Parameters tools.Parameters + Parameters parameters.Parameters AuthRequired []string CatalogClient *dataplexapi.CatalogClient ProjectID string @@ -115,7 +116,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { // Invoke the tool with the provided parameters paramsMap := params.AsMap() query, _ := paramsMap["query"].(string) @@ -172,9 +173,9 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { // Parse parameters from the provided data - return tools.ParseParams(t.Parameters, data, claims) + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go b/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go index 8efa9e266e..b5efdb4053 100644 --- a/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go +++ b/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" dataplexds "github.com/googleapis/genai-toolbox/internal/sources/dataplex" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "dataplex-search-entries" @@ -79,23 +80,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - query := tools.NewStringParameter("query", "The query against which entries in scope should be matched.") - pageSize := tools.NewIntParameterWithDefault("pageSize", 5, "Number of results in the search page.") - orderBy := tools.NewStringParameterWithDefault("orderBy", "relevance", "Specifies the ordering of results. Supported values are: relevance, last_modified_timestamp, last_modified_timestamp asc") - parameters := tools.Parameters{query, pageSize, orderBy} + query := parameters.NewStringParameter("query", "The query against which entries in scope should be matched.") + pageSize := parameters.NewIntParameterWithDefault("pageSize", 5, "Number of results in the search page.") + orderBy := parameters.NewStringParameterWithDefault("orderBy", "relevance", "Specifies the ordering of results. Supported values are: relevance, last_modified_timestamp, last_modified_timestamp asc") + params := parameters.Parameters{query, pageSize, orderBy} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, CatalogClient: s.CatalogClient(), ProjectID: s.ProjectID(), manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -106,7 +107,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) type Tool struct { Name string Kind string - Parameters tools.Parameters + Parameters parameters.Parameters AuthRequired []string CatalogClient *dataplexapi.CatalogClient ProjectID string @@ -114,7 +115,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() query, _ := paramsMap["query"].(string) pageSize := int32(paramsMap["pageSize"].(int)) @@ -144,9 +145,9 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { // Parse parameters from the provided data - return tools.ParseParams(t.Parameters, data, claims) + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/dgraph/dgraph.go b/internal/tools/dgraph/dgraph.go index f4dbe4d01d..e242bb06b4 100644 --- a/internal/tools/dgraph/dgraph.go +++ b/internal/tools/dgraph/dgraph.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/dgraph" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "dgraph-dql" @@ -51,15 +52,15 @@ var _ compatibleSource = &dgraph.Source{} var compatibleSources = [...]string{dgraph.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - IsQuery bool `yaml:"isQuery"` - Timeout string `yaml:"timeout"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + IsQuery bool `yaml:"isQuery"` + Timeout string `yaml:"timeout"` + Parameters parameters.Parameters `yaml:"parameters"` } // validate interface @@ -104,10 +105,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - Parameters tools.Parameters `yaml:"parameters"` - AuthRequired []string `yaml:"authRequired"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + Parameters parameters.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` DgraphClient *dgraph.DgraphClient IsQuery bool Timeout string @@ -116,7 +117,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMapWithDollarPrefix() resp, err := t.DgraphClient.ExecuteQuery(t.Statement, paramsMap, t.IsQuery, t.Timeout) @@ -139,8 +140,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result.Data, nil } -func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claimsMap) +func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claimsMap) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go index c8041d8718..faa85a93e7 100644 --- a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go +++ b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go @@ -23,6 +23,7 @@ import ( "github.com/elastic/go-elasticsearch/v8/esapi" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" @@ -47,15 +48,15 @@ var _ compatibleSource = &es.Source{} var compatibleSources = [...]string{es.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Query string `yaml:"query"` - Format string `yaml:"format"` - Timeout int `yaml:"timeout"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Query string `yaml:"query"` + Format string `yaml:"format"` + Timeout int `yaml:"timeout"` + Parameters parameters.Parameters `yaml:"parameters"` } var _ tools.ToolConfig = Config{} @@ -73,13 +74,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - Query string `yaml:"query"` - Format string `yaml:"format" default:"json"` - Timeout int `yaml:"timeout"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + Query string `yaml:"query"` + Format string `yaml:"format" default:"json"` + Timeout int `yaml:"timeout"` manifest tools.Manifest mcpManifest tools.McpManifest @@ -127,7 +128,7 @@ type esqlResult struct { Values [][]any `json:"values"` } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { var cancel context.CancelFunc if t.Timeout > 0 { ctx, cancel = context.WithTimeout(ctx, time.Duration(t.Timeout)*time.Second) @@ -222,8 +223,8 @@ func (t Tool) esqlToMap(result esqlResult) []map[string]any { return output } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go index 36ad57f765..2382483429 100644 --- a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go +++ b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go @@ -22,7 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlElasticsearchEsql(t *testing.T) { @@ -81,8 +81,8 @@ func TestParseFromYamlElasticsearchEsql(t *testing.T) { Source: "my-elasticsearch-instance", Description: "Elasticsearch ES|QL tool with customizable limit", AuthRequired: []string{}, - Parameters: tools.Parameters{ - tools.NewIntParameter("limit", "Limit the number of results"), + Parameters: parameters.Parameters{ + parameters.NewIntParameter("limit", "Limit the number of results"), }, Query: "FROM my-index\n| LIMIT ?limit\n", }, diff --git a/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go b/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go index 36772b9d0c..ad5cb9be58 100644 --- a/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go +++ b/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/firebird" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "firebird-execute-sql" @@ -75,17 +76,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) t := &Tool{ Name: cfg.Name, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Db: s.FirebirdDB(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -94,17 +95,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = &Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Db *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t *Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t *Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -162,8 +163,8 @@ func (t *Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t *Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t *Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t *Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firebird/firebirdsql/firebirdsql.go b/internal/tools/firebird/firebirdsql/firebirdsql.go index 17c39d2373..65ca6a3209 100644 --- a/internal/tools/firebird/firebirdsql/firebirdsql.go +++ b/internal/tools/firebird/firebirdsql/firebirdsql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/firebird" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "firebird-sql" @@ -52,14 +53,14 @@ var _ compatibleSource = &firebird.Source{} var compatibleSources = [...]string{firebird.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -82,7 +83,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -109,12 +110,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = &Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Db *sql.DB Statement string @@ -122,14 +123,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t *Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t *Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - statement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + statement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params: %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params: %w", err) } @@ -193,8 +194,8 @@ func (t *Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t *Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t *Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t *Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firebird/firebirdsql/firebirdsql_test.go b/internal/tools/firebird/firebirdsql/firebirdsql_test.go index f48efd632a..5530699035 100644 --- a/internal/tools/firebird/firebirdsql/firebirdsql_test.go +++ b/internal/tools/firebird/firebirdsql/firebirdsql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firebird/firebirdsql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlFirebird(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlFirebird(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -137,12 +137,12 @@ func TestParseFromYamlWithTemplateParamsFirebird(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("name", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("name", "some description"), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go b/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go index d11d3f8215..8f4afcb26f 100644 --- a/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go +++ b/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go @@ -24,6 +24,7 @@ import ( firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "firestore-add-documents" @@ -83,12 +84,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } // Create parameters - collectionPathParameter := tools.NewStringParameter( + collectionPathParameter := parameters.NewStringParameter( collectionPathKey, "The relative path of the collection where the document will be added to (e.g., 'users' or 'users/userId/posts'). Note: This is a relative path, NOT an absolute path like 'projects/{project_id}/databases/{database_id}/documents/...'", ) - documentDataParameter := tools.NewMapParameter( + documentDataParameter := parameters.NewMapParameter( documentDataKey, `The document data in Firestore's native JSON format. Each field must be wrapped with a type indicator: - Strings: {"stringValue": "text"} @@ -105,28 +106,28 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) "", // Empty string for generic map that accepts any value type ) - returnDataParameter := tools.NewBooleanParameterWithDefault( + returnDataParameter := parameters.NewBooleanParameterWithDefault( returnDocumentDataKey, false, "If set to true the output will have the data of the created document. This flag if set to false will help avoid overloading the context of the agent.", ) - parameters := tools.Parameters{ + params := parameters.Parameters{ collectionPathParameter, documentDataParameter, returnDataParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Client: s.FirestoreClient(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -136,17 +137,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client *firestoreapi.Client manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() // Get collection path @@ -204,8 +205,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return response, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go b/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go index c549f6b114..763f84f473 100644 --- a/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go +++ b/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go @@ -24,6 +24,7 @@ import ( firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "firestore-delete-documents" @@ -80,19 +81,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - documentPathsParameter := tools.NewArrayParameter(documentPathsKey, "Array of relative document paths to delete from Firestore (e.g., 'users/userId' or 'users/userId/posts/postId'). Note: These are relative paths, NOT absolute paths like 'projects/{project_id}/databases/{database_id}/documents/...'", tools.NewStringParameter("item", "Relative document path")) - parameters := tools.Parameters{documentPathsParameter} + documentPathsParameter := parameters.NewArrayParameter(documentPathsKey, "Array of relative document paths to delete from Firestore (e.g., 'users/userId' or 'users/userId/posts/postId'). Note: These are relative paths, NOT absolute paths like 'projects/{project_id}/databases/{database_id}/documents/...'", parameters.NewStringParameter("item", "Relative document path")) + params := parameters.Parameters{documentPathsParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Client: s.FirestoreClient(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -102,17 +103,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client *firestoreapi.Client manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() documentPathsRaw, ok := mapParams[documentPathsKey].([]any) if !ok { @@ -124,7 +125,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // Use ConvertAnySliceToTyped to convert the slice - typedSlice, err := tools.ConvertAnySliceToTyped(documentPathsRaw, "string") + typedSlice, err := parameters.ConvertAnySliceToTyped(documentPathsRaw, "string") if err != nil { return nil, fmt.Errorf("failed to convert document paths: %w", err) } @@ -181,8 +182,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go b/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go index 43134f5dbb..a699866319 100644 --- a/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go +++ b/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go @@ -24,6 +24,7 @@ import ( firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "firestore-get-documents" @@ -80,19 +81,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - documentPathsParameter := tools.NewArrayParameter(documentPathsKey, "Array of relative document paths to retrieve from Firestore (e.g., 'users/userId' or 'users/userId/posts/postId'). Note: These are relative paths, NOT absolute paths like 'projects/{project_id}/databases/{database_id}/documents/...'", tools.NewStringParameter("item", "Relative document path")) - parameters := tools.Parameters{documentPathsParameter} + documentPathsParameter := parameters.NewArrayParameter(documentPathsKey, "Array of relative document paths to retrieve from Firestore (e.g., 'users/userId' or 'users/userId/posts/postId'). Note: These are relative paths, NOT absolute paths like 'projects/{project_id}/databases/{database_id}/documents/...'", parameters.NewStringParameter("item", "Relative document path")) + params := parameters.Parameters{documentPathsParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Client: s.FirestoreClient(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -102,17 +103,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client *firestoreapi.Client manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() documentPathsRaw, ok := mapParams[documentPathsKey].([]any) if !ok { @@ -124,7 +125,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // Use ConvertAnySliceToTyped to convert the slice - typedSlice, err := tools.ConvertAnySliceToTyped(documentPathsRaw, "string") + typedSlice, err := parameters.ConvertAnySliceToTyped(documentPathsRaw, "string") if err != nil { return nil, fmt.Errorf("failed to convert document paths: %w", err) } @@ -173,8 +174,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firestore/firestoregetrules/firestoregetrules.go b/internal/tools/firestore/firestoregetrules/firestoregetrules.go index d68d8e61a3..efaca41c39 100644 --- a/internal/tools/firestore/firestoregetrules/firestoregetrules.go +++ b/internal/tools/firestore/firestoregetrules/firestoregetrules.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/firebaserules/v1" ) @@ -81,20 +82,20 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } // No parameters needed for this tool - parameters := tools.Parameters{} + params := parameters.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, RulesClient: s.FirebaseRulesClient(), ProjectId: s.GetProjectId(), DatabaseId: s.GetDatabaseId(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -104,10 +105,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` RulesClient *firebaserules.Service ProjectId string @@ -116,7 +117,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { // Get the latest release for Firestore releaseName := fmt.Sprintf("projects/%s/releases/cloud.firestore/%s", t.ProjectId, t.DatabaseId) release, err := t.RulesClient.Projects.Releases.Get(releaseName).Context(ctx).Do() @@ -141,8 +142,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return ruleset, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go b/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go index 60b95e2fd5..b8d5152e27 100644 --- a/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go +++ b/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go @@ -24,6 +24,7 @@ import ( firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "firestore-list-collections" @@ -81,19 +82,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } emptyString := "" - parentPathParameter := tools.NewStringParameterWithDefault(parentPathKey, emptyString, "Relative parent document path to list subcollections from (e.g., 'users/userId'). If not provided, lists root collections. Note: This is a relative path, NOT an absolute path like 'projects/{project_id}/databases/{database_id}/documents/...'") - parameters := tools.Parameters{parentPathParameter} + parentPathParameter := parameters.NewStringParameterWithDefault(parentPathKey, emptyString, "Relative parent document path to list subcollections from (e.g., 'users/userId'). If not provided, lists root collections. Note: This is a relative path, NOT an absolute path like 'projects/{project_id}/databases/{database_id}/documents/...'") + params := parameters.Parameters{parentPathParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Client: s.FirestoreClient(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -103,17 +104,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client *firestoreapi.Client manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() var collectionRefs []*firestoreapi.CollectionRef @@ -160,8 +161,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firestore/firestorequery/firestorequery.go b/internal/tools/firestore/firestorequery/firestorequery.go index 78206f5abb..1c652dc7d7 100644 --- a/internal/tools/firestore/firestorequery/firestorequery.go +++ b/internal/tools/firestore/firestorequery/firestorequery.go @@ -27,6 +27,7 @@ import ( firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // Constants for tool configuration @@ -100,7 +101,7 @@ type Config struct { AnalyzeQuery bool `yaml:"analyzeQuery"` // Analyze query (boolean, not parameterizable) // Parameters for template substitution - Parameters tools.Parameters `yaml:"parameters"` + Parameters parameters.Parameters `yaml:"parameters"` } // validate interface @@ -168,7 +169,7 @@ type Tool struct { OrderByTemplate map[string]any LimitTemplate string AnalyzeQuery bool - Parameters tools.Parameters + Parameters parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest @@ -214,11 +215,11 @@ type QueryResponse struct { } // Invoke executes the Firestore query based on the provided parameters -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() // Process collection path with template substitution - collectionPath, err := tools.PopulateTemplate("collectionPath", t.CollectionPathTemplate, paramsMap) + collectionPath, err := parameters.PopulateTemplate("collectionPath", t.CollectionPathTemplate, paramsMap) if err != nil { return nil, fmt.Errorf("failed to process collection path: %w", err) } @@ -241,7 +242,7 @@ func (t Tool) buildQuery(collectionPath string, params map[string]any) (*firesto // Process and apply filters if template is provided if t.FiltersTemplate != "" { // Apply template substitution to filters - filtersJSON, err := tools.PopulateTemplateWithJSON("filters", t.FiltersTemplate, params) + filtersJSON, err := parameters.PopulateTemplateWithJSON("filters", t.FiltersTemplate, params) if err != nil { return nil, fmt.Errorf("failed to process filters template: %w", err) } @@ -352,7 +353,7 @@ func (t Tool) processSelectFields(params map[string]any) ([]string, error) { for _, field := range t.SelectTemplate { // Check if it's a template if strings.Contains(field, "{{") { - processed, err := tools.PopulateTemplate("selectField", field, params) + processed, err := parameters.PopulateTemplate("selectField", field, params) if err != nil { return nil, err } @@ -418,7 +419,7 @@ func (t Tool) getOrderByForKey(key string, params map[string]any) (string, error return "", nil } - processedValue, err := tools.PopulateTemplate(fmt.Sprintf("orderBy%s", key), value, params) + processedValue, err := parameters.PopulateTemplate(fmt.Sprintf("orderBy%s", key), value, params) if err != nil { return "", err } @@ -430,7 +431,7 @@ func (t Tool) getOrderByForKey(key string, params map[string]any) (string, error func (t Tool) getLimit(params map[string]any) (int, error) { limit := defaultLimit if t.LimitTemplate != "" { - processedValue, err := tools.PopulateTemplate("limit", t.LimitTemplate, params) + processedValue, err := parameters.PopulateTemplate("limit", t.LimitTemplate, params) if err != nil { return 0, err } @@ -520,8 +521,8 @@ func (t Tool) getExplainMetrics(docIterator *firestoreapi.DocumentIterator) (map } // ParseParams parses and validates input parameters -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } // Manifest returns the tool manifest diff --git a/internal/tools/firestore/firestorequery/firestorequery_test.go b/internal/tools/firestore/firestorequery/firestorequery_test.go index 542206e7bd..178bbe8071 100644 --- a/internal/tools/firestore/firestorequery/firestorequery_test.go +++ b/internal/tools/firestore/firestorequery/firestorequery_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorequery" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlFirestoreQuery(t *testing.T) { @@ -58,8 +58,8 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { Description: "Query users collection with parameterized path", CollectionPath: "users/{{.userId}}/documents", AuthRequired: []string{}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("userId", "The user ID to query documents for", true), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("userId", "The user ID to query documents for", true), }, }, }, @@ -105,9 +105,9 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { } `, AuthRequired: []string{}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("category", "Product category to filter by", true), - tools.NewFloatParameterWithRequired("maxPrice", "Maximum price for products", true), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("category", "Product category to filter by", true), + parameters.NewFloatParameterWithRequired("maxPrice", "Maximum price for products", true), }, }, }, @@ -149,8 +149,8 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { }, Limit: "50", AuthRequired: []string{}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("sortField", "Field to sort by", true), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("sortField", "Field to sort by", true), }, }, }, @@ -215,10 +215,10 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { `, AnalyzeQuery: true, AuthRequired: []string{"google-auth-service", "api-key-service"}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("collection", "Collection name to query", true), - tools.NewStringParameterWithRequired("status", "Status to filter by", true), - tools.NewIntParameterWithDefault("minPriority", 1, "Minimum priority level"), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("collection", "Collection name to query", true), + parameters.NewStringParameterWithRequired("status", "Status to filter by", true), + parameters.NewIntParameterWithDefault("minPriority", 1, "Minimum priority level"), }, }, }, @@ -294,12 +294,12 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { } `, AuthRequired: []string{}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("continent", "Continent to filter by", true), - tools.NewStringParameterWithRequired("minPopulation", "Minimum population as string", true), - tools.NewFloatParameterWithRequired("minGdp", "Minimum GDP value", true), - tools.NewBooleanParameterWithRequired("isActive", "Filter by active status", true), - tools.NewStringParameterWithRequired("startDate", "Start date in RFC3339 format", true), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("continent", "Continent to filter by", true), + parameters.NewStringParameterWithRequired("minPopulation", "Minimum population as string", true), + parameters.NewFloatParameterWithRequired("minGdp", "Minimum GDP value", true), + parameters.NewBooleanParameterWithRequired("isActive", "Filter by active status", true), + parameters.NewStringParameterWithRequired("startDate", "Start date in RFC3339 format", true), }, }, }, @@ -433,11 +433,11 @@ func TestParseFromYamlMultipleQueryTools(t *testing.T) { }, Limit: "20", AuthRequired: []string{}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("userId", "User ID whose posts to query", true), - tools.NewStringParameterWithRequired("visibility", "Post visibility (public, private, friends)", true), - tools.NewStringParameterWithRequired("startDate", "Start date for posts", true), - tools.NewStringParameterWithDefault("sortOrder", "DESCENDING", "Sort order (ASCENDING or DESCENDING)"), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("userId", "User ID whose posts to query", true), + parameters.NewStringParameterWithRequired("visibility", "Post visibility (public, private, friends)", true), + parameters.NewStringParameterWithRequired("startDate", "Start date for posts", true), + parameters.NewStringParameterWithDefault("sortOrder", "DESCENDING", "Sort order (ASCENDING or DESCENDING)"), }, }, "query_inventory": firestorequery.Config{ @@ -450,9 +450,9 @@ func TestParseFromYamlMultipleQueryTools(t *testing.T) { "field": "quantity", "op": "<", "value": {"integerValue": "{{.threshold}}"}} `, AuthRequired: []string{}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("warehouseId", "Warehouse ID to check inventory", true), - tools.NewIntParameterWithRequired("threshold", "Quantity threshold for low stock", true), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("warehouseId", "Warehouse ID to check inventory", true), + parameters.NewIntParameterWithRequired("threshold", "Quantity threshold for low stock", true), }, }, "query_transactions": firestorequery.Config{ @@ -470,10 +470,10 @@ func TestParseFromYamlMultipleQueryTools(t *testing.T) { `, AnalyzeQuery: true, AuthRequired: []string{"finance-auth"}, - Parameters: tools.Parameters{ - tools.NewStringParameterWithRequired("accountId", "Account ID for transactions", true), - tools.NewStringParameterWithDefault("transactionType", "all", "Type of transaction"), - tools.NewFloatParameterWithDefault("minAmount", 0, "Minimum transaction amount"), + Parameters: parameters.Parameters{ + parameters.NewStringParameterWithRequired("accountId", "Account ID for transactions", true), + parameters.NewStringParameterWithDefault("transactionType", "all", "Type of transaction"), + parameters.NewFloatParameterWithDefault("minAmount", 0, "Minimum transaction amount"), }, }, } diff --git a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go index 4ca6e92b45..9299f63193 100644 --- a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go +++ b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go @@ -26,6 +26,7 @@ import ( firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // Constants for tool configuration @@ -146,8 +147,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } // createParameters creates the parameter definitions for the tool -func createParameters() tools.Parameters { - collectionPathParameter := tools.NewStringParameter( +func createParameters() parameters.Parameters { + collectionPathParameter := parameters.NewStringParameter( collectionPathKey, "The relative path to the Firestore collection to query (e.g., 'users' or 'users/userId/posts'). Note: This is a relative path, NOT an absolute path like 'projects/{project_id}/databases/{database_id}/documents/...'", ) @@ -158,30 +159,30 @@ func createParameters() tools.Parameters { - value: The value to compare against (can be string, number, boolean, or array) Example: {"field": "age", "op": ">", "value": 18}` - filtersParameter := tools.NewArrayParameter( + filtersParameter := parameters.NewArrayParameter( filtersKey, filtersDescription, - tools.NewStringParameter("item", "JSON string representation of a filter object"), + parameters.NewStringParameter("item", "JSON string representation of a filter object"), ) - orderByParameter := tools.NewStringParameter( + orderByParameter := parameters.NewStringParameter( orderByKey, "JSON string specifying the field and direction to order by (e.g., {\"field\": \"name\", \"direction\": \"ASCENDING\"}). Leave empty if not specified", ) - limitParameter := tools.NewIntParameterWithDefault( + limitParameter := parameters.NewIntParameterWithDefault( limitKey, defaultLimit, "The maximum number of documents to return", ) - analyzeQueryParameter := tools.NewBooleanParameterWithDefault( + analyzeQueryParameter := parameters.NewBooleanParameterWithDefault( analyzeQueryKey, defaultAnalyze, "If true, returns query explain metrics including execution statistics", ) - return tools.Parameters{ + return parameters.Parameters{ collectionPathParameter, filtersParameter, orderByParameter, @@ -195,10 +196,10 @@ var _ tools.Tool = Tool{} // Tool represents the Firestore query collection tool type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client *firestoreapi.Client manifest tools.Manifest @@ -264,7 +265,7 @@ type QueryResponse struct { } // Invoke executes the Firestore query based on the provided parameters -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { // Parse parameters queryParams, err := t.parseQueryParameters(params) if err != nil { @@ -291,7 +292,7 @@ type queryParameters struct { } // parseQueryParameters extracts and validates parameters from the input -func (t Tool) parseQueryParameters(params tools.ParamValues) (*queryParameters, error) { +func (t Tool) parseQueryParameters(params parameters.ParamValues) (*queryParameters, error) { mapParams := params.AsMap() // Get collection path @@ -511,8 +512,8 @@ func (t Tool) getExplainMetrics(docIterator *firestoreapi.DocumentIterator) (map } // ParseParams parses and validates input parameters -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } // Manifest returns the tool manifest diff --git a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go index 8a217bec64..0b29fad0d7 100644 --- a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go +++ b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go @@ -25,6 +25,7 @@ import ( firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "firestore-update-document" @@ -85,12 +86,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } // Create parameters - documentPathParameter := tools.NewStringParameter( + documentPathParameter := parameters.NewStringParameter( documentPathKey, "The relative path of the document which needs to be updated (e.g., 'users/userId' or 'users/userId/posts/postId'). Note: This is a relative path, NOT an absolute path like 'projects/{project_id}/databases/{database_id}/documents/...'", ) - documentDataParameter := tools.NewMapParameter( + documentDataParameter := parameters.NewMapParameter( documentDataKey, `The document data in Firestore's native JSON format. Each field must be wrapped with a type indicator: - Strings: {"stringValue": "text"} @@ -107,36 +108,36 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) "", // Empty string for generic map that accepts any value type ) - updateMaskParameter := tools.NewArrayParameterWithRequired( + updateMaskParameter := parameters.NewArrayParameterWithRequired( updateMaskKey, "The selective fields to update. If not provided, all fields in documentData will be updated. When provided, only the specified fields will be updated. Fields referenced in the mask but not present in documentData will be deleted from the document", false, // not required - tools.NewStringParameter("field", "Field path to update or delete. Use dot notation to access nested fields within maps (e.g., 'address.city' to update the city field within an address map, or 'user.profile.name' for deeply nested fields). To delete a field, include it in the mask but omit it from documentData. Note: You cannot update individual array elements; you must update the entire array field"), + parameters.NewStringParameter("field", "Field path to update or delete. Use dot notation to access nested fields within maps (e.g., 'address.city' to update the city field within an address map, or 'user.profile.name' for deeply nested fields). To delete a field, include it in the mask but omit it from documentData. Note: You cannot update individual array elements; you must update the entire array field"), ) - returnDataParameter := tools.NewBooleanParameterWithDefault( + returnDataParameter := parameters.NewBooleanParameterWithDefault( returnDocumentDataKey, false, "If set to true the output will have the data of the updated document. This flag if set to false will help avoid overloading the context of the agent.", ) - parameters := tools.Parameters{ + params := parameters.Parameters{ documentPathParameter, documentDataParameter, updateMaskParameter, returnDataParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Client: s.FirestoreClient(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -146,17 +147,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client *firestoreapi.Client manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() // Get document path @@ -181,7 +182,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken if updateMaskRaw, ok := mapParams[updateMaskKey]; ok && updateMaskRaw != nil { if updateMaskArray, ok := updateMaskRaw.([]any); ok { // Use ConvertAnySliceToTyped to convert the slice - typedSlice, err := tools.ConvertAnySliceToTyped(updateMaskArray, "string") + typedSlice, err := parameters.ConvertAnySliceToTyped(updateMaskArray, "string") if err != nil { return nil, fmt.Errorf("failed to convert update mask: %w", err) } @@ -297,8 +298,8 @@ func getFieldValue(data map[string]interface{}, path string) (interface{}, bool) return nil, false } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go index 6bdd96582d..0d04f1b1d8 100644 --- a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go +++ b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestNewConfig(t *testing.T) { @@ -204,11 +205,11 @@ func TestConfig_Initialize(t *testing.T) { func TestTool_ParseParams(t *testing.T) { tool := Tool{ - Parameters: tools.Parameters{ - tools.NewStringParameter("documentPath", "Document path"), - tools.NewMapParameter("documentData", "Document data", ""), - tools.NewArrayParameterWithRequired("updateMask", "Update mask", false, tools.NewStringParameter("field", "Field")), - tools.NewBooleanParameterWithDefault("returnData", false, "Return data"), + Parameters: parameters.Parameters{ + parameters.NewStringParameter("documentPath", "Document path"), + parameters.NewMapParameter("documentData", "Document data", ""), + parameters.NewArrayParameterWithRequired("updateMask", "Update mask", false, parameters.NewStringParameter("field", "Field")), + parameters.NewBooleanParameterWithDefault("returnData", false, "Return data"), }, } @@ -284,7 +285,7 @@ func TestTool_Manifest(t *testing.T) { tool := Tool{ manifest: tools.Manifest{ Description: "Test description", - Parameters: []tools.ParameterManifest{ + Parameters: []parameters.ParameterManifest{ { Name: "documentPath", Type: "string", @@ -313,9 +314,9 @@ func TestTool_McpManifest(t *testing.T) { mcpManifest: tools.McpManifest{ Name: "test-update-document", Description: "Test description", - InputSchema: tools.McpToolsSchema{ + InputSchema: parameters.McpToolsSchema{ Type: "object", - Properties: map[string]tools.ParameterMcpManifest{ + Properties: map[string]parameters.ParameterMcpManifest{ "documentPath": { Type: "string", Description: "Document path", diff --git a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go index b266c4fdb1..8c27363c8c 100644 --- a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go +++ b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/firebaserules/v1" ) @@ -104,23 +105,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } // createParameters creates the parameter definitions for the tool -func createParameters() tools.Parameters { - sourceParameter := tools.NewStringParameter( +func createParameters() parameters.Parameters { + sourceParameter := parameters.NewStringParameter( sourceKey, "The Firestore Rules source code to validate", ) - return tools.Parameters{sourceParameter} + return parameters.Parameters{sourceParameter} } // validate interface var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` RulesClient *firebaserules.Service ProjectId string @@ -152,7 +153,7 @@ type ValidationResult struct { RawIssues []Issue `json:"rawIssues,omitempty"` } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() // Get source parameter @@ -270,8 +271,8 @@ func (t Tool) formatRulesetIssues(issues []Issue, rulesSource string) string { return strings.Join(formattedOutput, "\n\n") } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/http/http.go b/internal/tools/http/http.go index 9b9f1e8685..27e0b0ad1c 100644 --- a/internal/tools/http/http.go +++ b/internal/tools/http/http.go @@ -31,6 +31,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" httpsrc "github.com/googleapis/genai-toolbox/internal/sources/http" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "http" @@ -50,19 +51,19 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Path string `yaml:"path" validate:"required"` - Method tools.HTTPMethod `yaml:"method" validate:"required"` - Headers map[string]string `yaml:"headers"` - RequestBody string `yaml:"requestBody"` - PathParams tools.Parameters `yaml:"pathParams"` - QueryParams tools.Parameters `yaml:"queryParams"` - BodyParams tools.Parameters `yaml:"bodyParams"` - HeaderParams tools.Parameters `yaml:"headerParams"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Path string `yaml:"path" validate:"required"` + Method tools.HTTPMethod `yaml:"method" validate:"required"` + Headers map[string]string `yaml:"headers"` + RequestBody string `yaml:"requestBody"` + PathParams parameters.Parameters `yaml:"pathParams"` + QueryParams parameters.Parameters `yaml:"queryParams"` + BodyParams parameters.Parameters `yaml:"bodyParams"` + HeaderParams parameters.Parameters `yaml:"headerParams"` } // validate interface @@ -95,7 +96,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) allParameters := slices.Concat(cfg.PathParams, cfg.BodyParams, cfg.HeaderParams, cfg.QueryParams) // Verify no duplicate parameter names - err := tools.CheckDuplicateParameters(allParameters) + err := parameters.CheckDuplicateParameters(allParameters) if err != nil { return nil, err } @@ -104,7 +105,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -147,12 +148,12 @@ type Tool struct { Headers map[string]string `yaml:"headers"` DefaultQueryParams map[string]string `yaml:"defaultQueryParams"` - RequestBody string `yaml:"requestBody"` - PathParams tools.Parameters `yaml:"pathParams"` - QueryParams tools.Parameters `yaml:"queryParams"` - BodyParams tools.Parameters `yaml:"bodyParams"` - HeaderParams tools.Parameters `yaml:"headerParams"` - AllParams tools.Parameters `yaml:"allParams"` + RequestBody string `yaml:"requestBody"` + PathParams parameters.Parameters `yaml:"pathParams"` + QueryParams parameters.Parameters `yaml:"queryParams"` + BodyParams parameters.Parameters `yaml:"bodyParams"` + HeaderParams parameters.Parameters `yaml:"headerParams"` + AllParams parameters.Parameters `yaml:"allParams"` Client *http.Client manifest tools.Manifest @@ -160,14 +161,14 @@ type Tool struct { } // Helper function to generate the HTTP request body upon Tool invocation. -func getRequestBody(bodyParams tools.Parameters, requestBodyPayload string, paramsMap map[string]any) (string, error) { - bodyParamValues, err := tools.GetParams(bodyParams, paramsMap) +func getRequestBody(bodyParams parameters.Parameters, requestBodyPayload string, paramsMap map[string]any) (string, error) { + bodyParamValues, err := parameters.GetParams(bodyParams, paramsMap) if err != nil { return "", err } bodyParamsMap := bodyParamValues.AsMap() - requestBodyStr, err := tools.PopulateTemplateWithJSON("HTTPToolRequestBody", requestBodyPayload, bodyParamsMap) + requestBodyStr, err := parameters.PopulateTemplateWithJSON("HTTPToolRequestBody", requestBodyPayload, bodyParamsMap) if err != nil { return "", err } @@ -175,9 +176,9 @@ func getRequestBody(bodyParams tools.Parameters, requestBodyPayload string, para } // Helper function to generate the HTTP request URL upon Tool invocation. -func getURL(baseURL, path string, pathParams, queryParams tools.Parameters, defaultQueryParams map[string]string, paramsMap map[string]any) (string, error) { +func getURL(baseURL, path string, pathParams, queryParams parameters.Parameters, defaultQueryParams map[string]string, paramsMap map[string]any) (string, error) { // use Go template to replace path params - pathParamValues, err := tools.GetParams(pathParams, paramsMap) + pathParamValues, err := parameters.GetParams(pathParams, paramsMap) if err != nil { return "", err } @@ -227,7 +228,7 @@ func getURL(baseURL, path string, pathParams, queryParams tools.Parameters, defa } // Helper function to generate the HTTP headers upon Tool invocation. -func getHeaders(headerParams tools.Parameters, defaultHeaders map[string]string, paramsMap map[string]any) (map[string]string, error) { +func getHeaders(headerParams parameters.Parameters, defaultHeaders map[string]string, paramsMap map[string]any) (map[string]string, error) { // Populate header params allHeaders := make(map[string]string) maps.Copy(allHeaders, defaultHeaders) @@ -244,7 +245,7 @@ func getHeaders(headerParams tools.Parameters, defaultHeaders map[string]string, return allHeaders, nil } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() // Calculate request body @@ -295,8 +296,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/http/http_test.go b/internal/tools/http/http_test.go index 3074f9352d..62bacbca4d 100644 --- a/internal/tools/http/http_test.go +++ b/internal/tools/http/http_test.go @@ -22,8 +22,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" http "github.com/googleapis/genai-toolbox/internal/tools/http" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlHTTP(t *testing.T) { @@ -115,14 +115,14 @@ func TestParseFromYamlHTTP(t *testing.T) { Path: "{{.pathParam}}?name=alice&pet=cat", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - QueryParams: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + QueryParams: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - PathParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{Name: "pathParam", Type: "string", Desc: "path param"}, + PathParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{Name: "pathParam", Type: "string", Desc: "path param"}, }, }, RequestBody: `{ @@ -131,9 +131,9 @@ func TestParseFromYamlHTTP(t *testing.T) { "food": {{.food}} } `, - BodyParams: []tools.Parameter{tools.NewIntParameter("age", "age num"), tools.NewStringParameter("city", "city string")}, + BodyParams: []parameters.Parameter{parameters.NewIntParameter("age", "age num"), parameters.NewStringParameter("city", "city string")}, Headers: map[string]string{"Authorization": "API_KEY", "Content-Type": "application/json"}, - HeaderParams: []tools.Parameter{tools.NewStringParameter("Language", "language string")}, + HeaderParams: []parameters.Parameter{parameters.NewStringParameter("Language", "language string")}, }, }, }, diff --git a/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go b/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go index 496d24da5d..c4bfa6f02e 100644 --- a/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go +++ b/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,33 +73,33 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := lookercommon.GetQueryParameters() + params := lookercommon.GetQueryParameters() - dashIdParameter := tools.NewStringParameter("dashboard_id", "The id of the dashboard where this tile will exist") - parameters = append(parameters, dashIdParameter) - titleParameter := tools.NewStringParameterWithDefault("title", "", "The title of the Dashboard Element") - parameters = append(parameters, titleParameter) - vizParameter := tools.NewMapParameterWithDefault("vis_config", + dashIdParameter := parameters.NewStringParameter("dashboard_id", "The id of the dashboard where this tile will exist") + params = append(params, dashIdParameter) + titleParameter := parameters.NewStringParameterWithDefault("title", "", "The title of the Dashboard Element") + params = append(params, titleParameter) + vizParameter := parameters.NewMapParameterWithDefault("vis_config", map[string]any{}, "The visualization config for the query", "", ) - parameters = append(parameters, vizParameter) + params = append(params, vizParameter) - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -114,8 +115,8 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } @@ -125,7 +126,7 @@ var ( visType string = "vis" ) -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -187,8 +188,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookercommon/lookercommon.go b/internal/tools/looker/lookercommon/lookercommon.go index 87bc736f43..2e3eb49471 100644 --- a/internal/tools/looker/lookercommon/lookercommon.go +++ b/internal/tools/looker/lookercommon/lookercommon.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" rtl "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" "github.com/thlib/go-timezone-local/tzlocal" @@ -149,38 +150,38 @@ func CheckLookerExploreFields(resp *v4.LookmlModelExplore) error { return nil } -func GetFieldParameters() tools.Parameters { - modelParameter := tools.NewStringParameter("model", "The model containing the explore.") - exploreParameter := tools.NewStringParameter("explore", "The explore containing the fields.") - return tools.Parameters{modelParameter, exploreParameter} +func GetFieldParameters() parameters.Parameters { + modelParameter := parameters.NewStringParameter("model", "The model containing the explore.") + exploreParameter := parameters.NewStringParameter("explore", "The explore containing the fields.") + return parameters.Parameters{modelParameter, exploreParameter} } -func GetQueryParameters() tools.Parameters { - modelParameter := tools.NewStringParameter("model", "The model containing the explore.") - exploreParameter := tools.NewStringParameter("explore", "The explore to be queried.") - fieldsParameter := tools.NewArrayParameter("fields", +func GetQueryParameters() parameters.Parameters { + modelParameter := parameters.NewStringParameter("model", "The model containing the explore.") + exploreParameter := parameters.NewStringParameter("explore", "The explore to be queried.") + fieldsParameter := parameters.NewArrayParameter("fields", "The fields to be retrieved.", - tools.NewStringParameter("field", "A field to be returned in the query"), + parameters.NewStringParameter("field", "A field to be returned in the query"), ) - filtersParameter := tools.NewMapParameterWithDefault("filters", + filtersParameter := parameters.NewMapParameterWithDefault("filters", map[string]any{}, "The filters for the query", "", ) - pivotsParameter := tools.NewArrayParameterWithDefault("pivots", + pivotsParameter := parameters.NewArrayParameterWithDefault("pivots", []any{}, "The query pivots (must be included in fields as well).", - tools.NewStringParameter("pivot_field", "A field to be used as a pivot in the query"), + parameters.NewStringParameter("pivot_field", "A field to be used as a pivot in the query"), ) - sortsParameter := tools.NewArrayParameterWithDefault("sorts", + sortsParameter := parameters.NewArrayParameterWithDefault("sorts", []any{}, "The sorts like \"field.id desc 0\".", - tools.NewStringParameter("sort_field", "A field to be used as a sort in the query"), + parameters.NewStringParameter("sort_field", "A field to be used as a sort in the query"), ) - limitParameter := tools.NewIntParameterWithDefault("limit", 500, "The row limit.") - tzParameter := tools.NewStringParameterWithRequired("tz", "The query timezone.", false) + limitParameter := parameters.NewIntParameterWithDefault("limit", 500, "The row limit.") + tzParameter := parameters.NewStringParameterWithRequired("tz", "The query timezone.", false) - return tools.Parameters{ + return parameters.Parameters{ modelParameter, exploreParameter, fieldsParameter, @@ -192,7 +193,7 @@ func GetQueryParameters() tools.Parameters { } } -func ProcessFieldArgs(ctx context.Context, params tools.ParamValues) (*string, *string, error) { +func ProcessFieldArgs(ctx context.Context, params parameters.ParamValues) (*string, *string, error) { mapParams := params.AsMap() model, ok := mapParams["model"].(string) if !ok { @@ -205,7 +206,7 @@ func ProcessFieldArgs(ctx context.Context, params tools.ParamValues) (*string, * return &model, &explore, nil } -func ProcessQueryArgs(ctx context.Context, params tools.ParamValues) (*v4.WriteQuery, error) { +func ProcessQueryArgs(ctx context.Context, params parameters.ParamValues) (*v4.WriteQuery, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -214,7 +215,7 @@ func ProcessQueryArgs(ctx context.Context, params tools.ParamValues) (*v4.WriteQ logger.DebugContext(ctx, "params = ", params) paramsMap := params.AsMap() - f, err := tools.ConvertAnySliceToTyped(paramsMap["fields"].([]any), "string") + f, err := parameters.ConvertAnySliceToTyped(paramsMap["fields"].([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert fields to array of strings: %s", err) } @@ -227,12 +228,12 @@ func ProcessQueryArgs(ctx context.Context, params tools.ParamValues) (*v4.WriteQ filters[k[1:len(k)-1]] = v } } - p, err := tools.ConvertAnySliceToTyped(paramsMap["pivots"].([]any), "string") + p, err := parameters.ConvertAnySliceToTyped(paramsMap["pivots"].([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert pivots to array of strings: %s", err) } pivots := p.([]string) - s, err := tools.ConvertAnySliceToTyped(paramsMap["sorts"].([]any), "string") + s, err := parameters.ConvertAnySliceToTyped(paramsMap["sorts"].([]any), "string") if err != nil { return nil, fmt.Errorf("can't convert sorts to array of strings: %s", err) } diff --git a/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go b/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go index e6624fa639..c45b94a188 100644 --- a/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go +++ b/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go @@ -29,6 +29,7 @@ import ( lookerds "github.com/googleapis/genai-toolbox/internal/sources/looker" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" "golang.org/x/oauth2" ) @@ -159,21 +160,21 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("project must be defined for source to use with %q tool", kind) } - userQueryParameter := tools.NewStringParameter("user_query_with_context", "The user's question, potentially including conversation history and system instructions for context.") + userQueryParameter := parameters.NewStringParameter("user_query_with_context", "The user's question, potentially including conversation history and system instructions for context.") exploreRefsDescription := `An Array of at least one and up to 5 explore references like [{'model': 'MODEL_NAME', 'explore': 'EXPLORE_NAME'}]` - exploreRefsParameter := tools.NewArrayParameter( + exploreRefsParameter := parameters.NewArrayParameter( "explore_references", exploreRefsDescription, - tools.NewMapParameter( + parameters.NewMapParameter( "explore_reference", "An explore reference like {'model': 'MODEL_NAME', 'explore': 'EXPLORE_NAME'}", "", ), ) - parameters := tools.Parameters{userQueryParameter, exploreRefsParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{userQueryParameter, exploreRefsParameter} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // Get cloud-platform token source for Gemini Data Analytics API during initialization ctx := context.Background() @@ -189,11 +190,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) ApiSettings: s.GetApiSettings(), Project: s.GoogleCloudProject(), Location: s.GoogleCloudLocation(), - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientAuthorization(), TokenSource: ts, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -206,9 +207,9 @@ type Tool struct { Name string `yaml:"name"` Kind string `yaml:"kind"` ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - UseClientOAuth bool `yaml:"useClientOAuth"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + UseClientOAuth bool `yaml:"useClientOAuth"` + Parameters parameters.Parameters `yaml:"parameters"` Project string Location string TokenSource oauth2.TokenSource @@ -216,7 +217,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { var tokenStr string var err error @@ -289,8 +290,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return response, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go b/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go index bfd671b333..3439e3acf4 100644 --- a/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go +++ b/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go @@ -22,6 +22,7 @@ import ( lookersrc "github.com/googleapis/genai-toolbox/internal/sources/looker" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -71,25 +72,25 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - projectIdParameter := tools.NewStringParameter("project_id", "The id of the project containing the files") - filePathParameter := tools.NewStringParameter("file_path", "The path of the file within the project") - fileContentParameter := tools.NewStringParameter("file_content", "The content of the file") - parameters := tools.Parameters{projectIdParameter, filePathParameter, fileContentParameter} + projectIdParameter := parameters.NewStringParameter("project_id", "The id of the project containing the files") + filePathParameter := parameters.NewStringParameter("file_path", "The path of the file within the project") + fileContentParameter := parameters.NewStringParameter("file_content", "The content of the file") + params := parameters.Parameters{projectIdParameter, filePathParameter, fileContentParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -105,13 +106,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sdk, err := lookercommon.GetLookerSDK(t.UseClientOAuth, t.ApiSettings, t.Client, accessToken) if err != nil { return nil, fmt.Errorf("error getting sdk: %w", err) @@ -148,8 +149,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go b/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go index 58c3aeced7..7c8ce3ff1b 100644 --- a/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go +++ b/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go @@ -22,6 +22,7 @@ import ( lookersrc "github.com/googleapis/genai-toolbox/internal/sources/looker" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -71,24 +72,24 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - projectIdParameter := tools.NewStringParameter("project_id", "The id of the project containing the files") - filePathParameter := tools.NewStringParameter("file_path", "The path of the file within the project") - parameters := tools.Parameters{projectIdParameter, filePathParameter} + projectIdParameter := parameters.NewStringParameter("project_id", "The id of the project containing the files") + filePathParameter := parameters.NewStringParameter("file_path", "The path of the file within the project") + params := parameters.Parameters{projectIdParameter, filePathParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -104,13 +105,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sdk, err := lookercommon.GetLookerSDK(t.UseClientOAuth, t.ApiSettings, t.Client, accessToken) if err != nil { return nil, fmt.Errorf("error getting sdk: %w", err) @@ -138,8 +139,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerdevmode/lookerdevmode.go b/internal/tools/looker/lookerdevmode/lookerdevmode.go index 8fd7a0e04c..d54684659e 100644 --- a/internal/tools/looker/lookerdevmode/lookerdevmode.go +++ b/internal/tools/looker/lookerdevmode/lookerdevmode.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,23 +73,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - devModeParameter := tools.NewBooleanParameterWithDefault("devMode", true, "Whether to set Dev Mode.") - parameters := tools.Parameters{devModeParameter} + devModeParameter := parameters.NewBooleanParameterWithDefault("devMode", true, "Whether to set Dev Mode.") + params := parameters.Parameters{devModeParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -105,14 +106,14 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest ShowHiddenExplores bool } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -145,8 +146,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return resp, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go b/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go index 66385fc1ba..495d667af5 100644 --- a/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go +++ b/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -73,9 +74,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - typeParameter := tools.NewStringParameterWithDefault("type", "", "Type of Looker content to embed (ie. dashboards, looks, query-visualization)") - idParameter := tools.NewStringParameterWithDefault("id", "", "The ID of the content to embed.") - parameters := tools.Parameters{ + typeParameter := parameters.NewStringParameterWithDefault("type", "", "Type of Looker content to embed (ie. dashboards, looks, query-visualization)") + idParameter := parameters.NewStringParameterWithDefault("id", "", "The ID of the content to embed.") + parameters := parameters.Parameters{ typeParameter, idParameter, } @@ -111,13 +112,13 @@ type Tool struct { Client *v4.LookerSDK ApiSettings *rtl.ApiSettings AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters + Parameters parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest SessionLength int64 } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -156,8 +157,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return resp, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go b/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go index 6dd3acb79e..880f087abf 100644 --- a/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go +++ b/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go @@ -22,6 +22,7 @@ import ( lookersrc "github.com/googleapis/genai-toolbox/internal/sources/looker" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -71,23 +72,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - connParameter := tools.NewStringParameter("conn", "The connection containing the databases.") - parameters := tools.Parameters{connParameter} + connParameter := parameters.NewStringParameter("conn", "The connection containing the databases.") + params := parameters.Parameters{connParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -103,13 +104,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() conn, ok := mapParams["conn"].(string) if !ok { @@ -129,8 +130,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return resp, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetconnections/lookergetconnections.go b/internal/tools/looker/lookergetconnections/lookergetconnections.go index a5de7bba99..9635e90e34 100644 --- a/internal/tools/looker/lookergetconnections/lookergetconnections.go +++ b/internal/tools/looker/lookergetconnections/lookergetconnections.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,22 +73,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := tools.Parameters{} + params := parameters.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -103,13 +104,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -148,8 +149,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParamValues{}, nil +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParamValues{}, nil } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go b/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go index 948546833c..afa450c3da 100644 --- a/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go +++ b/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go @@ -22,6 +22,7 @@ import ( lookersrc "github.com/googleapis/genai-toolbox/internal/sources/looker" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -71,24 +72,24 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - connParameter := tools.NewStringParameter("conn", "The connection containing the schemas.") - dbParameter := tools.NewStringParameterWithRequired("db", "The optional database to search", false) - parameters := tools.Parameters{connParameter, dbParameter} + connParameter := parameters.NewStringParameter("conn", "The connection containing the schemas.") + dbParameter := parameters.NewStringParameterWithRequired("db", "The optional database to search", false) + params := parameters.Parameters{connParameter, dbParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -104,13 +105,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { mapParams := params.AsMap() conn, ok := mapParams["conn"].(string) if !ok { @@ -135,8 +136,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return resp, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go b/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go index 89e90ac3a0..293a77455f 100644 --- a/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go +++ b/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,26 +73,26 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - connParameter := tools.NewStringParameter("conn", "The connection containing the tables.") - dbParameter := tools.NewStringParameterWithRequired("db", "The optional database to search", false) - schemaParameter := tools.NewStringParameter("schema", "The schema containing the tables.") - tablesParameter := tools.NewStringParameter("tables", "A comma separated list of tables containing the columns.") - parameters := tools.Parameters{connParameter, dbParameter, schemaParameter, tablesParameter} + connParameter := parameters.NewStringParameter("conn", "The connection containing the tables.") + dbParameter := parameters.NewStringParameterWithRequired("db", "The optional database to search", false) + schemaParameter := parameters.NewStringParameter("schema", "The schema containing the tables.") + tablesParameter := parameters.NewStringParameter("tables", "A comma separated list of tables containing the columns.") + params := parameters.Parameters{connParameter, dbParameter, schemaParameter, tablesParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -107,13 +108,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -172,8 +173,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go b/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go index 0ced34f270..14dfe5698d 100644 --- a/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go +++ b/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,25 +73,25 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - connParameter := tools.NewStringParameter("conn", "The connection containing the tables.") - dbParameter := tools.NewStringParameterWithRequired("db", "The optional database to search", false) - schemaParameter := tools.NewStringParameter("schema", "The schema containing the tables.") - parameters := tools.Parameters{connParameter, dbParameter, schemaParameter} + connParameter := parameters.NewStringParameter("conn", "The connection containing the tables.") + dbParameter := parameters.NewStringParameterWithRequired("db", "The optional database to search", false) + schemaParameter := parameters.NewStringParameter("schema", "The schema containing the tables.") + params := parameters.Parameters{connParameter, dbParameter, schemaParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -106,13 +107,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -163,8 +164,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetdashboards/lookergetdashboards.go b/internal/tools/looker/lookergetdashboards/lookergetdashboards.go index a26681f4ce..6231dba830 100644 --- a/internal/tools/looker/lookergetdashboards/lookergetdashboards.go +++ b/internal/tools/looker/lookergetdashboards/lookergetdashboards.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,31 +73,31 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - titleParameter := tools.NewStringParameterWithDefault("title", "", "The title of the dashboard.") - descParameter := tools.NewStringParameterWithDefault("desc", "", "The description of the dashboard.") - limitParameter := tools.NewIntParameterWithDefault("limit", 100, "The number of dashboards to fetch. Default 100") - offsetParameter := tools.NewIntParameterWithDefault("offset", 0, "The number of dashboards to skip before fetching. Default 0") - parameters := tools.Parameters{ + titleParameter := parameters.NewStringParameterWithDefault("title", "", "The title of the dashboard.") + descParameter := parameters.NewStringParameterWithDefault("desc", "", "The description of the dashboard.") + limitParameter := parameters.NewIntParameterWithDefault("limit", 100, "The number of dashboards to fetch. Default 100") + offsetParameter := parameters.NewIntParameterWithDefault("offset", 0, "The number of dashboards to skip before fetching. Default 0") + params := parameters.Parameters{ titleParameter, descParameter, limitParameter, offsetParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -112,13 +113,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -174,8 +175,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetdimensions/lookergetdimensions.go b/internal/tools/looker/lookergetdimensions/lookergetdimensions.go index 6b9260dc41..aa03db7f73 100644 --- a/internal/tools/looker/lookergetdimensions/lookergetdimensions.go +++ b/internal/tools/looker/lookergetdimensions/lookergetdimensions.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,22 +73,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := lookercommon.GetFieldParameters() + params := lookercommon.GetFieldParameters() - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, UseClientOAuth: s.UseClientOAuth, Client: s.Client, AuthRequired: cfg.AuthRequired, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -104,14 +105,14 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest ShowHiddenFields bool } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -149,8 +150,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetexplores/lookergetexplores.go b/internal/tools/looker/lookergetexplores/lookergetexplores.go index 72dae48a42..b0f6053a0b 100644 --- a/internal/tools/looker/lookergetexplores/lookergetexplores.go +++ b/internal/tools/looker/lookergetexplores/lookergetexplores.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,23 +73,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - modelParameter := tools.NewStringParameter("model", "The model containing the explores.") - parameters := tools.Parameters{modelParameter} + modelParameter := parameters.NewStringParameter("model", "The model containing the explores.") + params := parameters.Parameters{modelParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -105,14 +106,14 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest ShowHiddenExplores bool } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -159,8 +160,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetfilters/lookergetfilters.go b/internal/tools/looker/lookergetfilters/lookergetfilters.go index 5177ef416d..9c0bdc6da0 100644 --- a/internal/tools/looker/lookergetfilters/lookergetfilters.go +++ b/internal/tools/looker/lookergetfilters/lookergetfilters.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -104,14 +105,14 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest ShowHiddenFields bool } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -149,8 +150,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetlooks/lookergetlooks.go b/internal/tools/looker/lookergetlooks/lookergetlooks.go index 93d3e3763f..2d9dacb516 100644 --- a/internal/tools/looker/lookergetlooks/lookergetlooks.go +++ b/internal/tools/looker/lookergetlooks/lookergetlooks.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,31 +73,31 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - titleParameter := tools.NewStringParameterWithDefault("title", "", "The title of the look.") - descParameter := tools.NewStringParameterWithDefault("desc", "", "The description of the look.") - limitParameter := tools.NewIntParameterWithDefault("limit", 100, "The number of looks to fetch. Default 100") - offsetParameter := tools.NewIntParameterWithDefault("offset", 0, "The number of looks to skip before fetching. Default 0") - parameters := tools.Parameters{ + titleParameter := parameters.NewStringParameterWithDefault("title", "", "The title of the look.") + descParameter := parameters.NewStringParameterWithDefault("desc", "", "The description of the look.") + limitParameter := parameters.NewIntParameterWithDefault("limit", 100, "The number of looks to fetch. Default 100") + offsetParameter := parameters.NewIntParameterWithDefault("offset", 0, "The number of looks to skip before fetching. Default 0") + params := parameters.Parameters{ titleParameter, descParameter, limitParameter, offsetParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -112,13 +113,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -174,8 +175,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetmeasures/lookergetmeasures.go b/internal/tools/looker/lookergetmeasures/lookergetmeasures.go index 8c5f82695d..1afedeb7b3 100644 --- a/internal/tools/looker/lookergetmeasures/lookergetmeasures.go +++ b/internal/tools/looker/lookergetmeasures/lookergetmeasures.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,22 +73,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := lookercommon.GetFieldParameters() + params := lookercommon.GetFieldParameters() - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -104,14 +105,14 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest ShowHiddenFields bool } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -149,8 +150,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetmodels/lookergetmodels.go b/internal/tools/looker/lookergetmodels/lookergetmodels.go index bd340276e8..d100555948 100644 --- a/internal/tools/looker/lookergetmodels/lookergetmodels.go +++ b/internal/tools/looker/lookergetmodels/lookergetmodels.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,22 +73,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := tools.Parameters{} + params := parameters.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -104,14 +105,14 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest ShowHiddenModels bool } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -151,8 +152,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParamValues{}, nil +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParamValues{}, nil } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetparameters/lookergetparameters.go b/internal/tools/looker/lookergetparameters/lookergetparameters.go index aad2af81a4..edbfdc6306 100644 --- a/internal/tools/looker/lookergetparameters/lookergetparameters.go +++ b/internal/tools/looker/lookergetparameters/lookergetparameters.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -104,14 +105,14 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest ShowHiddenFields bool } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -149,8 +150,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go index c3110a58c3..e9d49488de 100644 --- a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go +++ b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,24 +73,24 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - projectIdParameter := tools.NewStringParameter("project_id", "The id of the project containing the files") - filePathParameter := tools.NewStringParameter("file_path", "The path of the file within the project") - parameters := tools.Parameters{projectIdParameter, filePathParameter} + projectIdParameter := parameters.NewStringParameter("project_id", "The id of the project containing the files") + filePathParameter := parameters.NewStringParameter("file_path", "The path of the file within the project") + params := parameters.Parameters{projectIdParameter, filePathParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -105,13 +106,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -145,8 +146,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go index 0af9999507..05a517c999 100644 --- a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go +++ b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,23 +73,23 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - projectIdParameter := tools.NewStringParameter("project_id", "The id of the project containing the files") - parameters := tools.Parameters{projectIdParameter} + projectIdParameter := parameters.NewStringParameter("project_id", "The id of the project containing the files") + params := parameters.Parameters{projectIdParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -104,13 +105,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -162,8 +163,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookergetprojects/lookergetprojects.go b/internal/tools/looker/lookergetprojects/lookergetprojects.go index 4f803b8524..eeedaa5feb 100644 --- a/internal/tools/looker/lookergetprojects/lookergetprojects.go +++ b/internal/tools/looker/lookergetprojects/lookergetprojects.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,22 +73,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := tools.Parameters{} + params := parameters.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, UseClientOAuth: s.UseClientOAuth, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -103,13 +104,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -139,8 +140,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParamValues{}, nil +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParamValues{}, nil } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go index f2d8da507e..d2c18c94f0 100644 --- a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go +++ b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) @@ -75,14 +76,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - actionParameter := tools.NewStringParameterWithRequired("action", "The analysis to run. Can be 'projects', 'models', or 'explores'.", true) - projectParameter := tools.NewStringParameterWithRequired("project", "The Looker project to analyze (optional).", false) - modelParameter := tools.NewStringParameterWithRequired("model", "The Looker model to analyze (optional).", false) - exploreParameter := tools.NewStringParameterWithRequired("explore", "The Looker explore to analyze (optional).", false) - timeframeParameter := tools.NewIntParameterWithDefault("timeframe", 90, "The timeframe in days to analyze.") - minQueriesParameter := tools.NewIntParameterWithDefault("min_queries", 0, "The minimum number of queries for a model or explore to be considered used.") + actionParameter := parameters.NewStringParameterWithRequired("action", "The analysis to run. Can be 'projects', 'models', or 'explores'.", true) + projectParameter := parameters.NewStringParameterWithRequired("project", "The Looker project to analyze (optional).", false) + modelParameter := parameters.NewStringParameterWithRequired("model", "The Looker model to analyze (optional).", false) + exploreParameter := parameters.NewStringParameterWithRequired("explore", "The Looker explore to analyze (optional).", false) + timeframeParameter := parameters.NewIntParameterWithDefault("timeframe", 90, "The timeframe in days to analyze.") + minQueriesParameter := parameters.NewIntParameterWithDefault("min_queries", 0, "The minimum number of queries for a model or explore to be considered used.") - parameters := tools.Parameters{ + params := parameters.Parameters{ actionParameter, projectParameter, modelParameter, @@ -91,19 +92,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) minQueriesParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -118,13 +119,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters + AuthRequired []string + Parameters parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -187,8 +188,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return nil, fmt.Errorf("unknown action: %s", action) } } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go b/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go index 185c1d3bc0..fd7c925932 100644 --- a/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go +++ b/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -58,7 +59,6 @@ type Config struct { Parameters map[string]any `yaml:"parameters"` } -// validate interface var _ tools.ToolConfig = Config{} func (cfg Config) ToolConfigKind() string { @@ -66,45 +66,42 @@ func (cfg Config) ToolConfigKind() string { } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { - // verify source exists rawS, ok := srcs[cfg.Source] if !ok { return nil, fmt.Errorf("no source named %q configured", cfg.Source) } - // verify the source is compatible s, ok := rawS.(*lookersrc.Source) if !ok { return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - actionParameter := tools.NewStringParameterWithRequired("action", "The health check to run. Can be either: `check_db_connections`, `check_dashboard_performance`,`check_dashboard_errors`,`check_explore_performance`,`check_schedule_failures`, or `check_legacy_features`", true) + actionParameter := parameters.NewStringParameterWithRequired("action", "The health check to run. Can be either: `check_db_connections`, `check_dashboard_performance`,`check_dashboard_errors`,`check_explore_performance`,`check_schedule_failures`, or `check_legacy_features`", true) - parameters := tools.Parameters{ + params := parameters.Parameters{ actionParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, }, nil } -// validate interface var _ tools.Tool = Tool{} type Tool struct { @@ -113,13 +110,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string + Parameters parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -155,8 +152,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go b/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go index 4f2281363c..71bad06d59 100644 --- a/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go +++ b/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) @@ -75,14 +76,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - actionParameter := tools.NewStringParameterWithRequired("action", "The vacuum action to run. Can be 'models', or 'explores'.", true) - projectParameter := tools.NewStringParameterWithDefault("project", "", "The Looker project to vacuum (optional).") - modelParameter := tools.NewStringParameterWithDefault("model", "", "The Looker model to vacuum (optional).") - exploreParameter := tools.NewStringParameterWithDefault("explore", "", "The Looker explore to vacuum (optional).") - timeframeParameter := tools.NewIntParameterWithDefault("timeframe", 90, "The timeframe in days to analyze.") - minQueriesParameter := tools.NewIntParameterWithDefault("min_queries", 1, "The minimum number of queries for a model or explore to be considered used.") + actionParameter := parameters.NewStringParameterWithRequired("action", "The vacuum action to run. Can be 'models', or 'explores'.", true) + projectParameter := parameters.NewStringParameterWithDefault("project", "", "The Looker project to vacuum (optional).") + modelParameter := parameters.NewStringParameterWithDefault("model", "", "The Looker model to vacuum (optional).") + exploreParameter := parameters.NewStringParameterWithDefault("explore", "", "The Looker explore to vacuum (optional).") + timeframeParameter := parameters.NewIntParameterWithDefault("timeframe", 90, "The timeframe in days to analyze.") + minQueriesParameter := parameters.NewIntParameterWithDefault("min_queries", 1, "The minimum number of queries for a model or explore to be considered used.") - parameters := tools.Parameters{ + params := parameters.Parameters{ actionParameter, projectParameter, modelParameter, @@ -91,19 +92,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) minQueriesParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -118,13 +119,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters + AuthRequired []string + Parameters parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sdk, err := lookercommon.GetLookerSDK(t.UseClientOAuth, t.ApiSettings, t.Client, accessToken) if err != nil { return nil, fmt.Errorf("error getting sdk: %w", err) @@ -165,8 +166,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookermakedashboard/lookermakedashboard.go b/internal/tools/looker/lookermakedashboard/lookermakedashboard.go index 2ec02b55ed..04f21b0756 100644 --- a/internal/tools/looker/lookermakedashboard/lookermakedashboard.go +++ b/internal/tools/looker/lookermakedashboard/lookermakedashboard.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -74,27 +75,27 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := tools.Parameters{} + params := parameters.Parameters{} - titleParameter := tools.NewStringParameter("title", "The title of the Dashboard") - parameters = append(parameters, titleParameter) - descParameter := tools.NewStringParameterWithDefault("description", "", "The description of the Dashboard") - parameters = append(parameters, descParameter) + titleParameter := parameters.NewStringParameter("title", "The title of the Dashboard") + params = append(params, titleParameter) + descParameter := parameters.NewStringParameterWithDefault("description", "", "The description of the Dashboard") + params = append(params, descParameter) - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -110,13 +111,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -187,8 +188,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookermakelook/lookermakelook.go b/internal/tools/looker/lookermakelook/lookermakelook.go index 20d038313c..b20fb41490 100644 --- a/internal/tools/looker/lookermakelook/lookermakelook.go +++ b/internal/tools/looker/lookermakelook/lookermakelook.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -74,33 +75,33 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := lookercommon.GetQueryParameters() + params := lookercommon.GetQueryParameters() - titleParameter := tools.NewStringParameter("title", "The title of the Look") - parameters = append(parameters, titleParameter) - descParameter := tools.NewStringParameterWithDefault("description", "", "The description of the Look") - parameters = append(parameters, descParameter) - vizParameter := tools.NewMapParameterWithDefault("vis_config", + titleParameter := parameters.NewStringParameter("title", "The title of the Look") + params = append(params, titleParameter) + descParameter := parameters.NewStringParameterWithDefault("description", "", "The description of the Look") + params = append(params, descParameter) + vizParameter := parameters.NewMapParameterWithDefault("vis_config", map[string]any{}, "The visualization config for the query", "", ) - parameters = append(parameters, vizParameter) + params = append(params, vizParameter) - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -116,13 +117,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -204,8 +205,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerquery/lookerquery.go b/internal/tools/looker/lookerquery/lookerquery.go index b50da0b984..2672ca22a3 100644 --- a/internal/tools/looker/lookerquery/lookerquery.go +++ b/internal/tools/looker/lookerquery/lookerquery.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -73,22 +74,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := lookercommon.GetQueryParameters() + params := lookercommon.GetQueryParameters() - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -104,13 +105,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -141,8 +142,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerquerysql/lookerquerysql.go b/internal/tools/looker/lookerquerysql/lookerquerysql.go index 83bfd180f6..da087e7459 100644 --- a/internal/tools/looker/lookerquerysql/lookerquerysql.go +++ b/internal/tools/looker/lookerquerysql/lookerquerysql.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,22 +73,22 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := lookercommon.GetQueryParameters() + params := lookercommon.GetQueryParameters() - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -103,13 +104,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -131,8 +132,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return resp, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerqueryurl/lookerqueryurl.go b/internal/tools/looker/lookerqueryurl/lookerqueryurl.go index 6b2f74a319..a09c9c940c 100644 --- a/internal/tools/looker/lookerqueryurl/lookerqueryurl.go +++ b/internal/tools/looker/lookerqueryurl/lookerqueryurl.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -72,29 +73,29 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - parameters := lookercommon.GetQueryParameters() + params := lookercommon.GetQueryParameters() - vizParameter := tools.NewMapParameterWithDefault("vis_config", + vizParameter := parameters.NewMapParameterWithDefault("vis_config", map[string]any{}, "The visualization config for the query", "", ) - parameters = append(parameters, vizParameter) + params = append(params, vizParameter) - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -110,13 +111,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -160,8 +161,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerrundashboard/lookerrundashboard.go b/internal/tools/looker/lookerrundashboard/lookerrundashboard.go index bdb5d9e823..9404b4d141 100644 --- a/internal/tools/looker/lookerrundashboard/lookerrundashboard.go +++ b/internal/tools/looker/lookerrundashboard/lookerrundashboard.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -74,26 +75,26 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - dashboardidParameter := tools.NewStringParameter("dashboard_id", "The id of the dashboard to run.") + dashboardidParameter := parameters.NewStringParameter("dashboard_id", "The id of the dashboard to run.") - parameters := tools.Parameters{ + params := parameters.Parameters{ dashboardidParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -109,13 +110,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -157,8 +158,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerrunlook/lookerrunlook.go b/internal/tools/looker/lookerrunlook/lookerrunlook.go index edf172f34b..4c1fc00afa 100644 --- a/internal/tools/looker/lookerrunlook/lookerrunlook.go +++ b/internal/tools/looker/lookerrunlook/lookerrunlook.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -73,28 +74,28 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - lookidParameter := tools.NewStringParameter("look_id", "The id of the look to run.") - limitParameter := tools.NewIntParameterWithDefault("limit", 500, "The row limit. Default 500") + lookidParameter := parameters.NewStringParameter("look_id", "The id of the look to run.") + limitParameter := parameters.NewIntParameterWithDefault("limit", 500, "The row limit. Default 500") - parameters := tools.Parameters{ + params := parameters.Parameters{ lookidParameter, limitParameter, } - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -110,13 +111,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { return nil, fmt.Errorf("unable to get logger from ctx: %s", err) @@ -166,8 +167,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go b/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go index 9b63e70980..4e027f0516 100644 --- a/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go +++ b/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go @@ -22,6 +22,7 @@ import ( lookersrc "github.com/googleapis/genai-toolbox/internal/sources/looker" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/looker-open-source/sdk-codegen/go/rtl" v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" @@ -71,25 +72,25 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `looker`", kind) } - projectIdParameter := tools.NewStringParameter("project_id", "The id of the project containing the files") - filePathParameter := tools.NewStringParameter("file_path", "The path of the file within the project") - fileContentParameter := tools.NewStringParameter("file_content", "The content of the file") - parameters := tools.Parameters{projectIdParameter, filePathParameter, fileContentParameter} + projectIdParameter := parameters.NewStringParameter("project_id", "The id of the project containing the files") + filePathParameter := parameters.NewStringParameter("file_path", "The path of the file within the project") + fileContentParameter := parameters.NewStringParameter("file_content", "The content of the file") + params := parameters.Parameters{projectIdParameter, filePathParameter, fileContentParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup return Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, UseClientOAuth: s.UseClientOAuth, Client: s.Client, ApiSettings: s.ApiSettings, manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -105,13 +106,13 @@ type Tool struct { UseClientOAuth bool Client *v4.LookerSDK ApiSettings *rtl.ApiSettings - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sdk, err := lookercommon.GetLookerSDK(t.UseClientOAuth, t.ApiSettings, t.Client, accessToken) if err != nil { return nil, fmt.Errorf("error getting sdk: %w", err) @@ -148,8 +149,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return data, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go b/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go index 20a46ed232..b0c2adc01d 100644 --- a/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go +++ b/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/mindsdb" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mindsdb-execute-sql" @@ -79,10 +80,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - inputSchema, _ := parameters.McpManifest() + inputSchema, _ := params.McpManifest() mcpManifest := tools.McpManifest{ Name: cfg.Name, Description: cfg.Description, @@ -93,10 +94,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.MindsDBPool(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -106,17 +107,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -176,8 +177,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go b/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go index 766aa71dfa..2f400cf15d 100644 --- a/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go +++ b/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/mindsdb" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mindsdb-sql" @@ -52,14 +53,14 @@ var _ compatibleSource = &mindsdb.Source{} var compatibleSources = [...]string{mindsdb.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -82,7 +83,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -115,12 +116,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB Statement string @@ -128,14 +129,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -196,8 +197,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go b/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go index e0c9de2de2..3493717391 100644 --- a/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go +++ b/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbsql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlmindsdbsql(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlmindsdbsql(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -144,14 +144,14 @@ func TestParseFromYamlWithTemplateParamsmindsdbsql(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go index 6ee51fa9bf..95807d4970 100644 --- a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go +++ b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go @@ -21,6 +21,7 @@ import ( "github.com/goccy/go-yaml" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -45,17 +46,17 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Description string `yaml:"description" validate:"required"` - Database string `yaml:"database" validate:"required"` - Collection string `yaml:"collection" validate:"required"` - PipelinePayload string `yaml:"pipelinePayload" validate:"required"` - PipelineParams tools.Parameters `yaml:"pipelineParams" validate:"required"` - Canonical bool `yaml:"canonical"` - ReadOnly bool `yaml:"readOnly"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Description string `yaml:"description" validate:"required"` + Database string `yaml:"database" validate:"required"` + Collection string `yaml:"collection" validate:"required"` + PipelinePayload string `yaml:"pipelinePayload" validate:"required"` + PipelineParams parameters.Parameters `yaml:"pipelineParams" validate:"required"` + Canonical bool `yaml:"canonical"` + ReadOnly bool `yaml:"readOnly"` } // validate interface @@ -85,7 +86,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -112,26 +113,26 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - Description string `yaml:"description"` - AuthRequired []string `yaml:"authRequired"` - Collection string `yaml:"collection"` - PipelinePayload string `yaml:"pipelinePayload"` - PipelineParams tools.Parameters `yaml:"pipelineParams"` - Canonical bool `yaml:"canonical"` - ReadOnly bool `yaml:"readOnly"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + Description string `yaml:"description"` + AuthRequired []string `yaml:"authRequired"` + Collection string `yaml:"collection"` + PipelinePayload string `yaml:"pipelinePayload"` + PipelineParams parameters.Parameters `yaml:"pipelineParams"` + Canonical bool `yaml:"canonical"` + ReadOnly bool `yaml:"readOnly"` + AllParams parameters.Parameters `yaml:"allParams"` database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - pipelineString, err := tools.PopulateTemplateWithJSON("MongoDBAggregatePipeline", t.PipelinePayload, paramsMap) + pipelineString, err := parameters.PopulateTemplateWithJSON("MongoDBAggregatePipeline", t.PipelinePayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating pipeline: %s", err) } @@ -183,8 +184,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return final, err } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go index cb8d728d2a..266ac5e982 100644 --- a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go +++ b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go @@ -19,12 +19,12 @@ import ( "testing" "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbaggregate" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" ) func TestParseFromYamlMongoQuery(t *testing.T) { @@ -65,9 +65,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { Collection: "test_coll", Description: "some description", PipelinePayload: "[{ $match: { name: {{json .name}} }}]\n", - PipelineParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + PipelineParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", diff --git a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go index 7b6d37fffe..0d94a83e8d 100644 --- a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go +++ b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go @@ -21,6 +21,7 @@ import ( "github.com/goccy/go-yaml" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -46,15 +47,15 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Description string `yaml:"description" validate:"required"` - Database string `yaml:"database" validate:"required"` - Collection string `yaml:"collection" validate:"required"` - FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters `yaml:"filterParams"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Description string `yaml:"description" validate:"required"` + Database string `yaml:"database" validate:"required"` + Collection string `yaml:"collection" validate:"required"` + FilterPayload string `yaml:"filterPayload" validate:"required"` + FilterParams parameters.Parameters `yaml:"filterParams"` } // validate interface @@ -81,7 +82,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) allParameters := slices.Concat(cfg.FilterParams) // Verify no duplicate parameter names - err := tools.CheckDuplicateParameters(allParameters) + err := parameters.CheckDuplicateParameters(allParameters) if err != nil { return nil, err } @@ -90,7 +91,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -115,24 +116,24 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Description string `yaml:"description"` - Collection string `yaml:"collection"` - FilterPayload string `yaml:"filterPayload"` - FilterParams tools.Parameters `yaml:"filterParams"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Description string `yaml:"description"` + Collection string `yaml:"collection"` + FilterPayload string `yaml:"filterPayload"` + FilterParams parameters.Parameters `yaml:"filterParams"` + AllParams parameters.Parameters `yaml:"allParams"` database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - filterString, err := tools.PopulateTemplateWithJSON("MongoDBDeleteManyFilter", t.FilterPayload, paramsMap) + filterString, err := parameters.PopulateTemplateWithJSON("MongoDBDeleteManyFilter", t.FilterPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating filter: %s", err) } @@ -158,8 +159,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return res.DeletedCount, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go index 5140a1daf1..e5861949cf 100644 --- a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go +++ b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go @@ -18,8 +18,8 @@ import ( "strings" "testing" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbdeletemany" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" @@ -64,9 +64,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { Collection: "test_coll", Description: "some description", FilterPayload: "{ name: {{json .name}} }\n", - FilterParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", diff --git a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go index 4a7ef50815..42ea265b4e 100644 --- a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go +++ b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go @@ -20,6 +20,7 @@ import ( "github.com/goccy/go-yaml" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -45,15 +46,15 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Description string `yaml:"description" validate:"required"` - Database string `yaml:"database" validate:"required"` - Collection string `yaml:"collection" validate:"required"` - FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters `yaml:"filterParams"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Description string `yaml:"description" validate:"required"` + Database string `yaml:"database" validate:"required"` + Collection string `yaml:"collection" validate:"required"` + FilterPayload string `yaml:"filterPayload" validate:"required"` + FilterParams parameters.Parameters `yaml:"filterParams"` } // validate interface @@ -80,7 +81,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) allParameters := slices.Concat(cfg.FilterParams) // Verify no duplicate parameter names - err := tools.CheckDuplicateParameters(allParameters) + err := parameters.CheckDuplicateParameters(allParameters) if err != nil { return nil, err } @@ -89,7 +90,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -114,24 +115,24 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Description string `yaml:"description"` - Collection string `yaml:"collection"` - FilterPayload string `yaml:"filterPayload"` - FilterParams tools.Parameters `yaml:"filterParams"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Description string `yaml:"description"` + Collection string `yaml:"collection"` + FilterPayload string `yaml:"filterPayload"` + FilterParams parameters.Parameters `yaml:"filterParams"` + AllParams parameters.Parameters `yaml:"allParams"` database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - filterString, err := tools.PopulateTemplateWithJSON("MongoDBDeleteOneFilter", t.FilterPayload, paramsMap) + filterString, err := parameters.PopulateTemplateWithJSON("MongoDBDeleteOneFilter", t.FilterPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating filter: %s", err) } @@ -153,8 +154,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return res.DeletedCount, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go index 56fefb33e9..4aa99da297 100644 --- a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go +++ b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go @@ -18,8 +18,8 @@ import ( "strings" "testing" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbdeleteone" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" @@ -64,9 +64,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { Collection: "test_coll", Description: "some description", FilterPayload: "{ name: {{json .name}} }\n", - FilterParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", diff --git a/internal/tools/mongodb/mongodbfind/mongodbfind.go b/internal/tools/mongodb/mongodbfind/mongodbfind.go index 6e93a64ff0..4aed31e228 100644 --- a/internal/tools/mongodb/mongodbfind/mongodbfind.go +++ b/internal/tools/mongodb/mongodbfind/mongodbfind.go @@ -22,6 +22,7 @@ import ( "github.com/goccy/go-yaml" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -47,20 +48,20 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Description string `yaml:"description" validate:"required"` - Database string `yaml:"database" validate:"required"` - Collection string `yaml:"collection" validate:"required"` - FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters `yaml:"filterParams"` - ProjectPayload string `yaml:"projectPayload"` - ProjectParams tools.Parameters `yaml:"projectParams"` - SortPayload string `yaml:"sortPayload"` - SortParams tools.Parameters `yaml:"sortParams"` - Limit int64 `yaml:"limit"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Description string `yaml:"description" validate:"required"` + Database string `yaml:"database" validate:"required"` + Collection string `yaml:"collection" validate:"required"` + FilterPayload string `yaml:"filterPayload" validate:"required"` + FilterParams parameters.Parameters `yaml:"filterParams"` + ProjectPayload string `yaml:"projectPayload"` + ProjectParams parameters.Parameters `yaml:"projectParams"` + SortPayload string `yaml:"sortPayload"` + SortParams parameters.Parameters `yaml:"sortParams"` + Limit int64 `yaml:"limit"` } // validate interface @@ -87,7 +88,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) allParameters := slices.Concat(cfg.FilterParams, cfg.ProjectParams, cfg.SortParams) // Verify no duplicate parameter names - err := tools.CheckDuplicateParameters(allParameters) + err := parameters.CheckDuplicateParameters(allParameters) if err != nil { return nil, err } @@ -100,7 +101,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // Create Toolbox manifest paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -130,26 +131,26 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - Description string `yaml:"description"` - AuthRequired []string `yaml:"authRequired"` - Collection string `yaml:"collection"` - FilterPayload string `yaml:"filterPayload"` - FilterParams tools.Parameters `yaml:"filterParams"` - ProjectPayload string `yaml:"projectPayload"` - ProjectParams tools.Parameters `yaml:"projectParams"` - SortPayload string `yaml:"sortPayload"` - SortParams tools.Parameters `yaml:"sortParams"` - Limit int64 `yaml:"limit"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + Description string `yaml:"description"` + AuthRequired []string `yaml:"authRequired"` + Collection string `yaml:"collection"` + FilterPayload string `yaml:"filterPayload"` + FilterParams parameters.Parameters `yaml:"filterParams"` + ProjectPayload string `yaml:"projectPayload"` + ProjectParams parameters.Parameters `yaml:"projectParams"` + SortPayload string `yaml:"sortPayload"` + SortParams parameters.Parameters `yaml:"sortParams"` + Limit int64 `yaml:"limit"` + AllParams parameters.Parameters `yaml:"allParams"` database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func getOptions(ctx context.Context, sortParameters tools.Parameters, projectPayload string, limit int64, paramsMap map[string]any) (*options.FindOptions, error) { +func getOptions(ctx context.Context, sortParameters parameters.Parameters, projectPayload string, limit int64, paramsMap map[string]any) (*options.FindOptions, error) { logger, err := util.LoggerFromContext(ctx) if err != nil { panic(err) @@ -165,7 +166,7 @@ func getOptions(ctx context.Context, sortParameters tools.Parameters, projectPay if len(projectPayload) > 0 { - result, err := tools.PopulateTemplateWithJSON("MongoDBFindProjectString", projectPayload, paramsMap) + result, err := parameters.PopulateTemplateWithJSON("MongoDBFindProjectString", projectPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating project payload: %s", err) @@ -188,10 +189,10 @@ func getOptions(ctx context.Context, sortParameters tools.Parameters, projectPay return opts, nil } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - filterString, err := tools.PopulateTemplateWithJSON("MongoDBFindFilterString", t.FilterPayload, paramsMap) + filterString, err := parameters.PopulateTemplateWithJSON("MongoDBFindFilterString", t.FilterPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating filter: %s", err) @@ -234,8 +235,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return final, err } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbfind/mongodbfind_test.go b/internal/tools/mongodb/mongodbfind/mongodbfind_test.go index 5131ad797c..6b56d9c7c4 100644 --- a/internal/tools/mongodb/mongodbfind/mongodbfind_test.go +++ b/internal/tools/mongodb/mongodbfind/mongodbfind_test.go @@ -18,8 +18,8 @@ import ( "strings" "testing" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbfind" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" @@ -70,9 +70,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { Collection: "test_coll", Description: "some description", FilterPayload: "{ name: {{json .name}} }\n", - FilterParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", @@ -80,9 +80,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { }, }, ProjectPayload: "{ name: 1, age: 1 }\n", - ProjectParams: tools.Parameters{}, + ProjectParams: parameters.Parameters{}, SortPayload: "{ timestamp: -1 }\n", - SortParams: tools.Parameters{}, + SortParams: parameters.Parameters{}, }, }, }, diff --git a/internal/tools/mongodb/mongodbfindone/mongodbfindone.go b/internal/tools/mongodb/mongodbfindone/mongodbfindone.go index d599f5eb41..29cfc009bb 100644 --- a/internal/tools/mongodb/mongodbfindone/mongodbfindone.go +++ b/internal/tools/mongodb/mongodbfindone/mongodbfindone.go @@ -21,6 +21,7 @@ import ( "github.com/goccy/go-yaml" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -46,19 +47,19 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Description string `yaml:"description" validate:"required"` - Database string `yaml:"database" validate:"required"` - Collection string `yaml:"collection" validate:"required"` - FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters `yaml:"filterParams"` - ProjectPayload string `yaml:"projectPayload"` - ProjectParams tools.Parameters `yaml:"projectParams"` - SortPayload string `yaml:"sortPayload"` - SortParams tools.Parameters `yaml:"sortParams"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Description string `yaml:"description" validate:"required"` + Database string `yaml:"database" validate:"required"` + Collection string `yaml:"collection" validate:"required"` + FilterPayload string `yaml:"filterPayload" validate:"required"` + FilterParams parameters.Parameters `yaml:"filterParams"` + ProjectPayload string `yaml:"projectPayload"` + ProjectParams parameters.Parameters `yaml:"projectParams"` + SortPayload string `yaml:"sortPayload"` + SortParams parameters.Parameters `yaml:"sortParams"` } // validate interface @@ -85,7 +86,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) allParameters := slices.Concat(cfg.FilterParams, cfg.ProjectParams, cfg.SortParams) // Verify no duplicate parameter names - err := tools.CheckDuplicateParameters(allParameters) + err := parameters.CheckDuplicateParameters(allParameters) if err != nil { return nil, err } @@ -94,7 +95,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -123,25 +124,25 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Description string `yaml:"description"` - Collection string `yaml:"collection"` - FilterPayload string `yaml:"filterPayload"` - FilterParams tools.Parameters `yaml:"filterParams"` - ProjectPayload string `yaml:"projectPayload"` - ProjectParams tools.Parameters `yaml:"projectParams"` - SortPayload string `yaml:"sortPayload"` - SortParams tools.Parameters `yaml:"sortParams"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Description string `yaml:"description"` + Collection string `yaml:"collection"` + FilterPayload string `yaml:"filterPayload"` + FilterParams parameters.Parameters `yaml:"filterParams"` + ProjectPayload string `yaml:"projectPayload"` + ProjectParams parameters.Parameters `yaml:"projectParams"` + SortPayload string `yaml:"sortPayload"` + SortParams parameters.Parameters `yaml:"sortParams"` + AllParams parameters.Parameters `yaml:"allParams"` database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func getOptions(sortParameters tools.Parameters, projectPayload string, paramsMap map[string]any) (*options.FindOneOptions, error) { +func getOptions(sortParameters parameters.Parameters, projectPayload string, paramsMap map[string]any) (*options.FindOneOptions, error) { opts := options.FindOne() sort := bson.M{} @@ -154,7 +155,7 @@ func getOptions(sortParameters tools.Parameters, projectPayload string, paramsMa return opts, nil } - result, err := tools.PopulateTemplateWithJSON("MongoDBFindOneProjectString", projectPayload, paramsMap) + result, err := parameters.PopulateTemplateWithJSON("MongoDBFindOneProjectString", projectPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating project payload: %s", err) } @@ -169,10 +170,10 @@ func getOptions(sortParameters tools.Parameters, projectPayload string, paramsMa return opts, nil } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - filterString, err := tools.PopulateTemplateWithJSON("MongoDBFindOneFilterString", t.FilterPayload, paramsMap) + filterString, err := parameters.PopulateTemplateWithJSON("MongoDBFindOneFilterString", t.FilterPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating filter: %s", err) @@ -212,8 +213,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return final, err } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go b/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go index e2d0f0a92f..2eccffd835 100644 --- a/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go +++ b/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go @@ -18,8 +18,8 @@ import ( "strings" "testing" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbfindone" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" @@ -70,9 +70,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { Collection: "test_coll", Description: "some description", FilterPayload: "{ name: {{json .name}} }\n", - FilterParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", @@ -80,9 +80,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { }, }, ProjectPayload: "{ name: 1, age: 1 }\n", - ProjectParams: tools.Parameters{}, + ProjectParams: parameters.Parameters{}, SortPayload: "{ timestamp: -1 }\n", - SortParams: tools.Parameters{}, + SortParams: parameters.Parameters{}, }, }, }, diff --git a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go index 86b0718b1f..f41d10f7db 100644 --- a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go +++ b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -76,15 +77,15 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `mongodb`", kind) } - dataParam := tools.NewStringParameterWithRequired(paramDataKey, "the JSON payload to insert, should be a JSON array of documents", true) + dataParam := parameters.NewStringParameterWithRequired(paramDataKey, "the JSON payload to insert, should be a JSON array of documents", true) - allParameters := tools.Parameters{dataParam} + allParameters := parameters.Parameters{dataParam} // Create Toolbox manifest paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -113,14 +114,14 @@ type Tool struct { Description string `yaml:"description"` Collection string `yaml:"collection"` Canonical bool `yaml:"canonical" validation:"required"` //i want to force the user to choose - PayloadParams tools.Parameters + PayloadParams parameters.Parameters database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { if len(params) == 0 { return nil, errors.New("no input found") } @@ -146,8 +147,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return res.InsertedIDs, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.PayloadParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.PayloadParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go index fd814b4391..2102e8a0b8 100644 --- a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go +++ b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -76,15 +77,15 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be `mongodb`", kind) } - payloadParams := tools.NewStringParameterWithRequired(dataParamsKey, "the JSON payload to insert, should be a JSON object", true) + payloadParams := parameters.NewStringParameterWithRequired(dataParamsKey, "the JSON payload to insert, should be a JSON object", true) - allParameters := tools.Parameters{payloadParams} + allParameters := parameters.Parameters{payloadParams} // Create Toolbox manifest paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -108,20 +109,20 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Description string `yaml:"description"` - Collection string `yaml:"collection"` - Canonical bool `yaml:"canonical" validation:"required"` - PayloadParams tools.Parameters `yaml:"payloadParams" validate:"required"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Description string `yaml:"description"` + Collection string `yaml:"collection"` + Canonical bool `yaml:"canonical" validation:"required"` + PayloadParams parameters.Parameters `yaml:"payloadParams" validate:"required"` database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { if len(params) == 0 { return nil, errors.New("no input found") } @@ -145,8 +146,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return res.InsertedID, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.PayloadParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.PayloadParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go index e74f6329a0..5b05f0fcf2 100644 --- a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go +++ b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -44,19 +45,19 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Description string `yaml:"description" validate:"required"` - Database string `yaml:"database" validate:"required"` - Collection string `yaml:"collection" validate:"required"` - FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters `yaml:"filterParams"` - UpdatePayload string `yaml:"updatePayload" validate:"required"` - UpdateParams tools.Parameters `yaml:"updateParams" validate:"required"` - Canonical bool `yaml:"canonical" validate:"required"` - Upsert bool `yaml:"upsert"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Description string `yaml:"description" validate:"required"` + Database string `yaml:"database" validate:"required"` + Collection string `yaml:"collection" validate:"required"` + FilterPayload string `yaml:"filterPayload" validate:"required"` + FilterParams parameters.Parameters `yaml:"filterParams"` + UpdatePayload string `yaml:"updatePayload" validate:"required"` + UpdateParams parameters.Parameters `yaml:"updateParams" validate:"required"` + Canonical bool `yaml:"canonical" validate:"required"` + Upsert bool `yaml:"upsert"` } // validate interface @@ -83,7 +84,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) allParameters := slices.Concat(cfg.FilterParams, cfg.UpdateParams) // Verify no duplicate parameter names - err := tools.CheckDuplicateParameters(allParameters) + err := parameters.CheckDuplicateParameters(allParameters) if err != nil { return nil, err } @@ -92,7 +93,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -121,28 +122,28 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Description string `yaml:"description"` - Collection string `yaml:"collection"` - FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters `yaml:"filterParams"` - UpdatePayload string `yaml:"updatePayload" validate:"required"` - UpdateParams tools.Parameters `yaml:"updateParams" validate:"required"` - AllParams tools.Parameters `yaml:"allParams"` - Canonical bool `yaml:"canonical" validation:"required"` - Upsert bool `yaml:"upsert"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Description string `yaml:"description"` + Collection string `yaml:"collection"` + FilterPayload string `yaml:"filterPayload" validate:"required"` + FilterParams parameters.Parameters `yaml:"filterParams"` + UpdatePayload string `yaml:"updatePayload" validate:"required"` + UpdateParams parameters.Parameters `yaml:"updateParams" validate:"required"` + AllParams parameters.Parameters `yaml:"allParams"` + Canonical bool `yaml:"canonical" validation:"required"` + Upsert bool `yaml:"upsert"` database *mongo.Database manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - filterString, err := tools.PopulateTemplateWithJSON("MongoDBUpdateManyFilter", t.FilterPayload, paramsMap) + filterString, err := parameters.PopulateTemplateWithJSON("MongoDBUpdateManyFilter", t.FilterPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating filter: %s", err) } @@ -153,7 +154,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return nil, fmt.Errorf("unable to unmarshal filter string: %w", err) } - updateString, err := tools.PopulateTemplateWithJSON("MongoDBUpdateMany", t.UpdatePayload, paramsMap) + updateString, err := parameters.PopulateTemplateWithJSON("MongoDBUpdateMany", t.UpdatePayload, paramsMap) if err != nil { return nil, fmt.Errorf("unable to get update: %w", err) } @@ -172,8 +173,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return []any{res.ModifiedCount, res.UpsertedCount, res.MatchedCount}, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go index 8be3e4c7ca..209fffc565 100644 --- a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go +++ b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go @@ -18,8 +18,8 @@ import ( "strings" "testing" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbupdatemany" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" @@ -70,9 +70,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { Database: "test_db", Collection: "test_coll", FilterPayload: "{ name: {{json .name}} }\n", - FilterParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", @@ -80,9 +80,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { }, }, UpdatePayload: "{ $set: { name: {{json .name}} } }\n", - UpdateParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + UpdateParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", diff --git a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go index 09a5e2f6bf..8c2025ad9d 100644 --- a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go +++ b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" mongosrc "github.com/googleapis/genai-toolbox/internal/sources/mongodb" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -44,17 +45,17 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T } type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - AuthRequired []string `yaml:"authRequired" validate:"required"` - Description string `yaml:"description" validate:"required"` - Database string `yaml:"database" validate:"required"` - Collection string `yaml:"collection" validate:"required"` - FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters `yaml:"filterParams"` - UpdatePayload string `yaml:"updatePayload" validate:"required"` - UpdateParams tools.Parameters `yaml:"updateParams" validate:"required"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + AuthRequired []string `yaml:"authRequired" validate:"required"` + Description string `yaml:"description" validate:"required"` + Database string `yaml:"database" validate:"required"` + Collection string `yaml:"collection" validate:"required"` + FilterPayload string `yaml:"filterPayload" validate:"required"` + FilterParams parameters.Parameters `yaml:"filterParams"` + UpdatePayload string `yaml:"updatePayload" validate:"required"` + UpdateParams parameters.Parameters `yaml:"updateParams" validate:"required"` Canonical bool `yaml:"canonical" validate:"required"` Upsert bool `yaml:"upsert"` @@ -84,7 +85,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) allParameters := slices.Concat(cfg.FilterParams, cfg.UpdateParams) // Verify no duplicate parameter names - err := tools.CheckDuplicateParameters(allParameters) + err := parameters.CheckDuplicateParameters(allParameters) if err != nil { return nil, err } @@ -93,7 +94,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) paramManifest := allParameters.Manifest() if paramManifest == nil { - paramManifest = make([]tools.ParameterManifest, 0) + paramManifest = make([]parameters.ParameterManifest, 0) } // Create MCP manifest @@ -128,10 +129,10 @@ type Tool struct { Description string `yaml:"description"` Collection string `yaml:"collection"` FilterPayload string `yaml:"filterPayload" validate:"required"` - FilterParams tools.Parameters + FilterParams parameters.Parameters UpdatePayload string `yaml:"updatePayload" validate:"required"` - UpdateParams tools.Parameters - AllParams tools.Parameters + UpdateParams parameters.Parameters + AllParams parameters.Parameters Canonical bool `yaml:"canonical" validation:"required"` Upsert bool `yaml:"upsert"` @@ -140,10 +141,10 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - filterString, err := tools.PopulateTemplateWithJSON("MongoDBUpdateOneFilter", t.FilterPayload, paramsMap) + filterString, err := parameters.PopulateTemplateWithJSON("MongoDBUpdateOneFilter", t.FilterPayload, paramsMap) if err != nil { return nil, fmt.Errorf("error populating filter: %s", err) } @@ -154,7 +155,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return nil, fmt.Errorf("unable to unmarshal filter string: %w", err) } - updateString, err := tools.PopulateTemplateWithJSON("MongoDBUpdateOne", t.UpdatePayload, paramsMap) + updateString, err := parameters.PopulateTemplateWithJSON("MongoDBUpdateOne", t.UpdatePayload, paramsMap) if err != nil { return nil, fmt.Errorf("unable to get update: %w", err) } @@ -173,8 +174,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return res.ModifiedCount, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go index 8b1a4627f4..4f0398bd1e 100644 --- a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go +++ b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go @@ -18,8 +18,8 @@ import ( "strings" "testing" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbupdateone" + "github.com/googleapis/genai-toolbox/internal/util/parameters" yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" @@ -72,9 +72,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { Collection: "test_coll", Canonical: true, FilterPayload: "{ name: {{json .name}} }\n", - FilterParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + FilterParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "name", Type: "string", Desc: "small description", @@ -82,9 +82,9 @@ func TestParseFromYamlMongoQuery(t *testing.T) { }, }, UpdatePayload: "{ $set : { item: {{json .item}} } }\n", - UpdateParams: tools.Parameters{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{ + UpdateParams: parameters.Parameters{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{ Name: "item", Type: "string", Desc: "small description", diff --git a/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go b/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go index 77ab281f10..0dc1d22a2c 100644 --- a/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go +++ b/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/orderedmap" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mssql-execute-sql" @@ -82,19 +83,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.MSSQLDB(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -104,17 +105,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -170,8 +171,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mssql/mssqllisttables/mssqllisttables.go b/internal/tools/mssql/mssqllisttables/mssqllisttables.go index 98e37cb6dc..8e32ec3a81 100644 --- a/internal/tools/mssql/mssqllisttables/mssqllisttables.go +++ b/internal/tools/mssql/mssqllisttables/mssqllisttables.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql" "github.com/googleapis/genai-toolbox/internal/sources/mssql" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mssql-list-tables" @@ -329,9 +330,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("table_names", "", "Optional: A comma-separated list of table names. If empty, details for all tables will be listed."), - tools.NewStringParameterWithDefault("output_format", "detailed", "Optional: Use 'simple' for names only or 'detailed' for full info."), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("table_names", "", "Optional: A comma-separated list of table names. If empty, details for all tables will be listed."), + parameters.NewStringParameterWithDefault("output_format", "detailed", "Optional: Use 'simple' for names only or 'detailed' for full info."), } paramManifest := allParameters.Manifest() mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -353,17 +354,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + AllParams parameters.Parameters `yaml:"allParams"` Db *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() outputFormat, _ := paramsMap["output_format"].(string) @@ -415,8 +416,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mssql/mssqlsql/mssqlsql.go b/internal/tools/mssql/mssqlsql/mssqlsql.go index e4518f518e..90f9cd6286 100644 --- a/internal/tools/mssql/mssqlsql/mssqlsql.go +++ b/internal/tools/mssql/mssqlsql/mssqlsql.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql" "github.com/googleapis/genai-toolbox/internal/sources/mssql" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mssql-sql" @@ -54,14 +55,14 @@ var _ compatibleSource = &mssql.Source{} var compatibleSources = [...]string{cloudsqlmssql.SourceKind, mssql.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -84,7 +85,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -111,12 +112,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Db *sql.DB Statement string @@ -124,14 +125,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -191,8 +192,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mssql/mssqlsql/mssqlsql_test.go b/internal/tools/mssql/mssqlsql/mssqlsql_test.go index 7d47a790c5..3fb9b44d8c 100644 --- a/internal/tools/mssql/mssqlsql/mssqlsql_test.go +++ b/internal/tools/mssql/mssqlsql/mssqlsql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mssql/mssqlsql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlMssql(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlMssql(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -144,14 +144,14 @@ func TestParseFromYamlWithTemplateMssql(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go b/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go index 81fc6ba743..abdbd2d1de 100644 --- a/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go +++ b/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go @@ -28,6 +28,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/orderedmap" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mysql-execute-sql" @@ -85,19 +86,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.MySQLPool(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -107,17 +108,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -184,8 +185,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go b/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go index 4dd36e5dc3..34350c7ae9 100644 --- a/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go +++ b/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mysql-list-active-queries" @@ -144,9 +145,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewIntParameterWithDefault("min_duration_secs", 0, "Optional: Only show queries running for at least this long in seconds"), - tools.NewIntParameterWithDefault("limit", 100, "Optional: The maximum number of rows to return."), + allParameters := parameters.Parameters{ + parameters.NewIntParameterWithDefault("min_duration_secs", 0, "Optional: Only show queries running for at least this long in seconds"), + parameters.NewIntParameterWithDefault("limit", 100, "Optional: The maximum number of rows to return."), } mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -179,17 +180,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest statement string } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() duration, ok := paramsMap["min_duration_secs"].(int) @@ -260,8 +261,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go b/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go index d844a22b2f..1f85330b37 100644 --- a/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go +++ b/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mysql-list-table-fragmentation" @@ -104,11 +105,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("table_schema", "", "(Optional) The database where fragmentation check is to be executed. Check all tables visible to the current user if not specified"), - tools.NewStringParameterWithDefault("table_name", "", "(Optional) Name of the table to be checked. Check all tables visible to the current user if not specified."), - tools.NewIntParameterWithDefault("data_free_threshold_bytes", 1, "(Optional) Only show tables with at least this much free space in bytes. Default is 1"), - tools.NewIntParameterWithDefault("limit", 10, "(Optional) Max rows to return, default is 10"), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("table_schema", "", "(Optional) The database where fragmentation check is to be executed. Check all tables visible to the current user if not specified"), + parameters.NewStringParameterWithDefault("table_name", "", "(Optional) Name of the table to be checked. Check all tables visible to the current user if not specified."), + parameters.NewIntParameterWithDefault("data_free_threshold_bytes", 1, "(Optional) Only show tables with at least this much free space in bytes. Default is 1"), + parameters.NewIntParameterWithDefault("limit", 10, "(Optional) Max rows to return, default is 10"), } mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -129,16 +130,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() table_schema, ok := paramsMap["table_schema"].(string) @@ -217,8 +218,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mysql/mysqllisttables/mysqllisttables.go b/internal/tools/mysql/mysqllisttables/mysqllisttables.go index c2f003e044..0b8c1ef84a 100644 --- a/internal/tools/mysql/mysqllisttables/mysqllisttables.go +++ b/internal/tools/mysql/mysqllisttables/mysqllisttables.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/mysql" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mysql-list-tables" @@ -234,9 +235,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("table_names", "", "Optional: A comma-separated list of table names. If empty, details for all tables will be listed."), - tools.NewStringParameterWithDefault("output_format", "detailed", "Optional: Use 'simple' for names only or 'detailed' for full info."), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("table_names", "", "Optional: A comma-separated list of table names. If empty, details for all tables will be listed."), + parameters.NewStringParameterWithDefault("output_format", "detailed", "Optional: Use 'simple' for names only or 'detailed' for full info."), } paramManifest := allParameters.Manifest() mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -258,17 +259,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() tableNames, ok := paramsMap["table_names"].(string) @@ -332,8 +333,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go b/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go index 60220d7c2c..f7ed89f748 100644 --- a/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go +++ b/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mysql-list-tables-missing-unique-indexes" @@ -105,9 +106,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("table_schema", "", "(Optional) The database where the check is to be performed. Check all tables visible to the current user if not specified"), - tools.NewIntParameterWithDefault("limit", 50, "(Optional) Max rows to return, default is 50"), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("table_schema", "", "(Optional) The database where the check is to be performed. Check all tables visible to the current user if not specified"), + parameters.NewIntParameterWithDefault("limit", 50, "(Optional) Max rows to return, default is 50"), } mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -128,16 +129,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() table_schema, ok := paramsMap["table_schema"].(string) @@ -208,8 +209,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mysql/mysqlsql/mysqlsql.go b/internal/tools/mysql/mysqlsql/mysqlsql.go index 6967d86695..970dd918eb 100644 --- a/internal/tools/mysql/mysqlsql/mysqlsql.go +++ b/internal/tools/mysql/mysqlsql/mysqlsql.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/mysql" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "mysql-sql" @@ -56,14 +57,14 @@ var _ compatibleSource = &mindsdb.Source{} var compatibleSources = [...]string{cloudsqlmysql.SourceKind, mysql.SourceKind, mindsdb.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -86,7 +87,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -113,12 +114,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB Statement string @@ -126,14 +127,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -191,8 +192,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/mysql/mysqlsql/mysqlsql_test.go b/internal/tools/mysql/mysqlsql/mysqlsql_test.go index 48c3ffded0..5863477f0b 100644 --- a/internal/tools/mysql/mysqlsql/mysqlsql_test.go +++ b/internal/tools/mysql/mysqlsql/mysqlsql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlsql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlMySQL(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlMySQL(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -144,14 +144,14 @@ func TestParseFromYamlWithTemplateParamsMySQL(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/neo4j/neo4jcypher/neo4jcypher.go b/internal/tools/neo4j/neo4jcypher/neo4jcypher.go index 78a14cb5ea..72a5480897 100644 --- a/internal/tools/neo4j/neo4jcypher/neo4jcypher.go +++ b/internal/tools/neo4j/neo4jcypher/neo4jcypher.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "neo4j-cypher" @@ -54,13 +55,13 @@ var _ compatibleSource = &neo4jsc.Source{} var compatibleSources = [...]string{neo4jsc.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` } // validate interface @@ -104,10 +105,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - Parameters tools.Parameters `yaml:"parameters"` - AuthRequired []string `yaml:"authRequired"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + Parameters parameters.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` Driver neo4j.DriverWithContext Database string @@ -116,7 +117,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() config := neo4j.ExecuteQueryWithDatabase(t.Database) @@ -140,8 +141,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claimsMap) +func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claimsMap) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go b/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go index 0984080745..898583f961 100644 --- a/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go +++ b/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go @@ -21,7 +21,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlNeo4j(t *testing.T) { @@ -60,8 +60,8 @@ func TestParseFromYamlNeo4j(t *testing.T) { Description: "some tool description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, Statement: "MATCH (c:Country) WHERE c.name = $country RETURN c.id as id;\n", - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "country parameter description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "country parameter description"), }, }, }, diff --git a/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go b/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go index 33c474d509..ca32468449 100644 --- a/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go +++ b/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jexecutecypher/classifier" "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jschema/helpers" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/neo4j/neo4j-go-driver/v5/neo4j" ) @@ -83,28 +84,28 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - cypherParameter := tools.NewStringParameter("cypher", "The cypher to execute.") - dryRunParameter := tools.NewBooleanParameterWithDefault( + cypherParameter := parameters.NewStringParameter("cypher", "The cypher to execute.") + dryRunParameter := parameters.NewBooleanParameterWithDefault( "dry_run", false, "If set to true, the query will be validated and information about the execution "+ "will be returned without running the query. Defaults to false.", ) - parameters := tools.Parameters{cypherParameter, dryRunParameter} + params := parameters.Parameters{cypherParameter, dryRunParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, ReadOnly: cfg.ReadOnly, Driver: s.Neo4jDriver(), Database: s.Neo4jDatabase(), classifier: classifier.NewQueryClassifier(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -114,11 +115,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - Parameters tools.Parameters `yaml:"parameters"` - AuthRequired []string `yaml:"authRequired"` - ReadOnly bool `yaml:"readOnly"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + Parameters parameters.Parameters `yaml:"parameters"` + AuthRequired []string `yaml:"authRequired"` + ReadOnly bool `yaml:"readOnly"` Database string Driver neo4j.DriverWithContext classifier *classifier.QueryClassifier @@ -126,7 +127,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() cypherStr, ok := paramsMap["cypher"].(string) if !ok { @@ -197,8 +198,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claimsMap) +func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claimsMap) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/neo4j/neo4jschema/neo4jschema.go b/internal/tools/neo4j/neo4jschema/neo4jschema.go index 23adfd7f11..786a1dae9a 100644 --- a/internal/tools/neo4j/neo4jschema/neo4jschema.go +++ b/internal/tools/neo4j/neo4jschema/neo4jschema.go @@ -27,6 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jschema/cache" "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jschema/helpers" "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jschema/types" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/neo4j/neo4j-go-driver/v5/neo4j" ) @@ -96,8 +97,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // Set a default cache expiration if not provided in the configuration. if cfg.CacheExpireMinutes == nil { @@ -114,7 +115,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) Database: s.Neo4jDatabase(), cache: cache.NewCache(), cacheExpireMinutes: cfg.CacheExpireMinutes, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -139,7 +140,7 @@ type Tool struct { // Invoke executes the tool's main logic: fetching the Neo4j schema. // It first checks the cache for a valid schema before extracting it from the database. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { // Check if a valid schema is already in the cache. if cachedSchema, ok := t.cache.Get("schema"); ok { if schema, ok := cachedSchema.(*types.SchemaInfo); ok { @@ -161,8 +162,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams is a placeholder as this tool does not require input parameters. -func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParamValues{}, nil +func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParamValues{}, nil } // Manifest returns the tool's manifest, which describes its purpose and parameters. diff --git a/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go b/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go index d75e764821..25e7ccf3f9 100644 --- a/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go +++ b/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/oceanbase" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "oceanbase-execute-sql" @@ -79,19 +80,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.OceanBasePool(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -101,10 +102,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest @@ -112,7 +113,7 @@ type Tool struct { } // Invoke executes the SQL statement provided in the parameters. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() sqlStr, ok := sliceParams[0].(string) if !ok { @@ -173,8 +174,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the input parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } // Manifest returns the tool manifest. diff --git a/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go b/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go index 53c2ffe03a..66de214b7d 100644 --- a/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go +++ b/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/oceanbase" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "oceanbase-sql" @@ -44,14 +45,14 @@ var _ compatibleSource = &oceanbase.Source{} var compatibleSources = [...]string{oceanbase.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -82,7 +83,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, fmt.Errorf("unable to process parameters: %w", err) } @@ -109,12 +110,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB Statement string @@ -123,14 +124,14 @@ type Tool struct { } // Invoke executes the SQL statement with the provided parameters. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -190,8 +191,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // ParseParams parses the input parameters for the tool. -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } // Manifest returns the tool manifest. diff --git a/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go b/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go index 3bcd81813e..0b1806dd84 100644 --- a/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go +++ b/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/oceanbase/oceanbasesql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // Test parsing OceanBase SQL tool config from YAML. @@ -58,8 +58,8 @@ func TestParseFromYamlOceanBaseSql(t *testing.T) { Description: "some description", Statement: "select * from t where id = ?", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("id", "id param"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("id", "id param"), }, }, }, diff --git a/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go b/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go index a320529913..ff861d87a0 100644 --- a/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go +++ b/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go @@ -14,6 +14,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/oracle" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "oracle-execute-sql" @@ -69,19 +70,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The SQL to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The SQL to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.OracleDB(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -91,17 +92,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sqlParam, ok := paramsMap["sql"].(string) if !ok { @@ -217,8 +218,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/oracle/oraclesql/oraclesql.go b/internal/tools/oracle/oraclesql/oraclesql.go index b51e552ece..ebd1879a1a 100644 --- a/internal/tools/oracle/oraclesql/oraclesql.go +++ b/internal/tools/oracle/oraclesql/oraclesql.go @@ -13,6 +13,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/oracle" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "oracle-sql" @@ -41,14 +42,14 @@ var _ compatibleSource = &oracle.Source{} var compatibleSources = [...]string{oracle.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -71,7 +72,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, fmt.Errorf("error processing parameters: %w", err) } @@ -98,12 +99,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` DB *sql.DB Statement string @@ -111,14 +112,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -223,8 +224,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go b/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go index fbd07003eb..6c4c5c8ee7 100644 --- a/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go +++ b/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -96,7 +97,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{} + allParameters := parameters.Parameters{} description := cfg.Description if description == "" { description = "Fetches the current state of the PostgreSQL server, returning the version, whether it's a replica, uptime duration, maximum connection limit, number of current connections, number of active connections, and the percentage of connections in use." @@ -123,16 +124,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - name string `yaml:"name"` - kind string `yaml:"kind"` - authRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"allParams"` + name string `yaml:"name"` + kind string `yaml:"kind"` + authRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"allParams"` pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() results, err := t.pool.Query(ctx, databaseOverviewStatement, sliceParams...) @@ -159,8 +160,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go b/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go index 6f281e77e9..73e086846c 100644 --- a/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go +++ b/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/orderedmap" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -84,19 +85,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.PostgresPool(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -106,17 +107,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -157,8 +158,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go b/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go index 2bf57b015d..5f32d75cf9 100644 --- a/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go +++ b/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -105,10 +106,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("min_duration", "1 minute", "Optional: Only show queries running at least this long (e.g., '1 minute', '1 second', '2 seconds')."), - tools.NewStringParameterWithDefault("exclude_application_names", "", "Optional: A comma-separated list of application names to exclude from the query results. This is useful for filtering out queries from specific applications (e.g., 'psql', 'pgAdmin', 'DBeaver'). The match is case-sensitive. Whitespace around commas and names is automatically handled. If this parameter is omitted, no applications are excluded."), - tools.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("min_duration", "1 minute", "Optional: Only show queries running at least this long (e.g., '1 minute', '1 second', '2 seconds')."), + parameters.NewStringParameterWithDefault("exclude_application_names", "", "Optional: A comma-separated list of application names to exclude from the query results. This is useful for filtering out queries from specific applications (e.g., 'psql', 'pgAdmin', 'DBeaver'). The match is case-sensitive. Whitespace around commas and names is automatically handled. If this parameter is omitted, no applications are excluded."), + parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."), } paramManifest := allParameters.Manifest() mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -134,19 +135,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - name string `yaml:"name"` - kind string `yaml:"kind"` - authRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"allParams"` + name string `yaml:"name"` + kind string `yaml:"kind"` + authRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"allParams"` pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newParams, err := tools.GetParams(t.allParams, paramsMap) + newParams, err := parameters.GetParams(t.allParams, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -176,8 +177,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go b/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go index 216f6eef50..ac02133482 100644 --- a/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go +++ b/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -92,8 +93,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ @@ -103,7 +104,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) Pool: s.PostgresPool(), manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -123,7 +124,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { results, err := t.Pool.Query(ctx, listAvailableExtensionsQuery) if err != nil { return nil, fmt.Errorf("unable to execute query: %w", err) @@ -147,8 +148,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParamValues{}, nil +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParamValues{}, nil } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go b/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go index 9effa0d865..ae13f90a0e 100644 --- a/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go +++ b/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -126,11 +127,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("schema_name", "", "Optional: a text to filter results by schema name. The input is used within a LIKE clause."), - tools.NewStringParameterWithDefault("table_name", "", "Optional: a text to filter results by table name. The input is used within a LIKE clause."), - tools.NewStringParameterWithDefault("index_name", "", "Optional: a text to filter results by index name. The input is used within a LIKE clause."), - tools.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return. Default is 50"), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("schema_name", "", "Optional: a text to filter results by schema name. The input is used within a LIKE clause."), + parameters.NewStringParameterWithDefault("table_name", "", "Optional: a text to filter results by table name. The input is used within a LIKE clause."), + parameters.NewStringParameterWithDefault("index_name", "", "Optional: a text to filter results by index name. The input is used within a LIKE clause."), + parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return. Default is 50"), } description := cfg.Description if description == "" { @@ -158,16 +159,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - name string `yaml:"name"` - kind string `yaml:"kind"` - authRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"allParams"` + name string `yaml:"name"` + kind string `yaml:"kind"` + authRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"allParams"` pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() results, err := t.pool.Query(ctx, listIndexesStatement, sliceParams...) @@ -194,8 +195,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go b/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go index 772532b512..898f6feb06 100644 --- a/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go +++ b/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -103,8 +104,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - parameters := tools.Parameters{} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + params := parameters.Parameters{} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ @@ -114,7 +115,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) Pool: s.PostgresPool(), manifest: tools.Manifest{ Description: cfg.Description, - Parameters: parameters.Manifest(), + Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired, }, mcpManifest: mcpManifest, @@ -134,7 +135,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { results, err := t.Pool.Query(ctx, listAvailableExtensionsQuery) if err != nil { return nil, fmt.Errorf("unable to execute query: %w", err) @@ -158,8 +159,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParamValues{}, nil +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParamValues{}, nil } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go b/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go index f501a5118a..d4226b4e3d 100644 --- a/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go +++ b/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -133,8 +134,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("schema_name", "", "Optional: A specific schema name pattern to search for."), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("schema_name", "", "Optional: A specific schema name pattern to search for."), } description := cfg.Description if description == "" { @@ -162,16 +163,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - name string `yaml:"name"` - kind string `yaml:"kind"` - authRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"allParams"` + name string `yaml:"name"` + kind string `yaml:"kind"` + authRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"allParams"` pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() results, err := t.pool.Query(ctx, listSchemasStatement, sliceParams...) @@ -198,8 +199,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go b/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go index 33a57427f0..a2a030e58a 100644 --- a/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go +++ b/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -102,10 +103,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("schemaname", "", "Optional: A specific schema name pattern to search for."), - tools.NewStringParameterWithDefault("sequencename", "", "Optional: A specific sequence name pattern to search for."), - tools.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return. Default is 50"), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("schemaname", "", "Optional: A specific schema name pattern to search for."), + parameters.NewStringParameterWithDefault("sequencename", "", "Optional: A specific sequence name pattern to search for."), + parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return. Default is 50"), } description := cfg.Description if description == "" { @@ -133,16 +134,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - name string `yaml:"name"` - kind string `yaml:"kind"` - authRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"allParams"` + name string `yaml:"name"` + kind string `yaml:"kind"` + authRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"allParams"` pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() results, err := t.pool.Query(ctx, listSequencesStatement, sliceParams...) @@ -169,8 +170,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslisttables/postgreslisttables.go b/internal/tools/postgres/postgreslisttables/postgreslisttables.go index f97b89b6ee..f3036c4412 100644 --- a/internal/tools/postgres/postgreslisttables/postgreslisttables.go +++ b/internal/tools/postgres/postgreslisttables/postgreslisttables.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -160,9 +161,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("table_names", "", "Optional: A comma-separated list of table names. If empty, details for all tables will be listed."), - tools.NewStringParameterWithDefault("output_format", "detailed", "Optional: Use 'simple' for names only or 'detailed' for full info."), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("table_names", "", "Optional: A comma-separated list of table names. If empty, details for all tables will be listed."), + parameters.NewStringParameterWithDefault("output_format", "detailed", "Optional: Use 'simple' for names only or 'detailed' for full info."), } paramManifest := allParameters.Manifest() mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters) @@ -184,17 +185,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() tableNames, ok := paramsMap["table_names"].(string) @@ -234,8 +235,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go b/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go index c1dca9750a..277ade0d40 100644 --- a/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go +++ b/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -128,11 +129,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("trigger_name", "", "Optional: A specific trigger name pattern to search for."), - tools.NewStringParameterWithDefault("schema_name", "", "Optional: A specific schema name pattern to search for."), - tools.NewStringParameterWithDefault("table_name", "", "Optional: A specific table name pattern to search for."), - tools.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("trigger_name", "", "Optional: A specific trigger name pattern to search for."), + parameters.NewStringParameterWithDefault("schema_name", "", "Optional: A specific schema name pattern to search for."), + parameters.NewStringParameterWithDefault("table_name", "", "Optional: A specific table name pattern to search for."), + parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."), } description := cfg.Description if description == "" { @@ -160,16 +161,16 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - name string `yaml:"name"` - kind string `yaml:"kind"` - authRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"allParams"` + name string `yaml:"name"` + kind string `yaml:"kind"` + authRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"allParams"` pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() results, err := t.pool.Query(ctx, listTriggersStatement, sliceParams...) @@ -196,8 +197,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgreslistviews/postgreslistviews.go b/internal/tools/postgres/postgreslistviews/postgreslistviews.go index b48cc6ad18..c613d82ddf 100644 --- a/internal/tools/postgres/postgreslistviews/postgreslistviews.go +++ b/internal/tools/postgres/postgreslistviews/postgreslistviews.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -92,9 +93,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault("viewname", "", "Optional: A specific view name to search for."), - tools.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault("viewname", "", "Optional: A specific view name to search for."), + parameters.NewIntParameterWithDefault("limit", 50, "Optional: The maximum number of rows to return."), } paramManifest := allParameters.Manifest() description := cfg.Description @@ -123,19 +124,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - name string `yaml:"name"` - kind string `yaml:"kind"` - authRequired []string `yaml:"authRequired"` - allParams tools.Parameters `yaml:"allParams"` + name string `yaml:"name"` + kind string `yaml:"kind"` + authRequired []string `yaml:"authRequired"` + allParams parameters.Parameters `yaml:"allParams"` pool *pgxpool.Pool manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newParams, err := tools.GetParams(t.allParams, paramsMap) + newParams, err := parameters.GetParams(t.allParams, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -165,8 +166,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.allParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.allParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgressql/postgressql.go b/internal/tools/postgres/postgressql/postgressql.go index 9a685c5542..6a05e380c5 100644 --- a/internal/tools/postgres/postgressql/postgressql.go +++ b/internal/tools/postgres/postgressql/postgressql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -55,14 +56,14 @@ var _ compatibleSource = &postgres.Source{} var compatibleSources = [...]string{alloydbpg.SourceKind, cloudsqlpg.SourceKind, postgres.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -85,7 +86,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -112,12 +113,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *pgxpool.Pool Statement string @@ -125,14 +126,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -160,8 +161,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/postgres/postgressql/postgressql_test.go b/internal/tools/postgres/postgressql/postgressql_test.go index 40249b9559..c29152ad9b 100644 --- a/internal/tools/postgres/postgressql/postgressql_test.go +++ b/internal/tools/postgres/postgressql/postgressql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgressql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlPostgres(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlPostgres(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -137,12 +137,12 @@ func TestParseFromYamlWithTemplateParamsPostgres(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("name", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("name", "some description"), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/redis/redis.go b/internal/tools/redis/redis.go index 6c47d54089..e14bdb16a4 100644 --- a/internal/tools/redis/redis.go +++ b/internal/tools/redis/redis.go @@ -21,6 +21,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" redissrc "github.com/googleapis/genai-toolbox/internal/sources/redis" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" jsoniter "github.com/json-iterator/go" "github.com/redis/go-redis/v9" ) @@ -51,13 +52,13 @@ var _ compatibleSource = &redissrc.Source{} var compatibleSources = [...]string{redissrc.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Commands [][]string `yaml:"commands" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Commands [][]string `yaml:"commands" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` } // validate interface @@ -100,10 +101,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client redissrc.RedisClient Commands [][]string @@ -111,7 +112,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { cmds, err := replaceCommandsParams(t.Commands, t.Parameters, params) if err != nil { return nil, fmt.Errorf("error replacing commands' parameters: %s", err) @@ -156,8 +157,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { @@ -178,7 +179,7 @@ func (t Tool) RequiresClientAuthorization() bool { // replaceCommandsParams is a helper function to replace parameters in the commands -func replaceCommandsParams(commands [][]string, params tools.Parameters, paramValues tools.ParamValues) ([][]any, error) { +func replaceCommandsParams(commands [][]string, params parameters.Parameters, paramValues parameters.ParamValues) ([][]any, error) { paramMap := paramValues.AsMapWithDollarPrefix() typeMap := make(map[string]string, len(params)) for _, p := range params { diff --git a/internal/tools/redis/redis_test.go b/internal/tools/redis/redis_test.go index bd80e9dd20..5ee4ce3841 100644 --- a/internal/tools/redis/redis_test.go +++ b/internal/tools/redis/redis_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/redis" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlRedis(t *testing.T) { @@ -59,8 +59,8 @@ func TestParseFromYamlRedis(t *testing.T) { Description: "some description", AuthRequired: []string{}, Commands: [][]string{{"SET", "greeting", "hello, {{.name}}"}, {"GET", "id"}}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("name", "user name"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("name", "user name"), }, }, }, diff --git a/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go b/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go index 36a0be4095..d976ddf515 100644 --- a/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go +++ b/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/serverlessspark" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind = "serverless-spark-cancel-batch" @@ -75,8 +76,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) desc = "Cancels a running Serverless Spark (aka Dataproc Serverless) batch operation. Note that the batch state will not change immediately after the tool returns; it can take a minute or so for the cancellation to be reflected." } - allParameters := tools.Parameters{ - tools.NewStringParameter("operation", "The name of the operation to cancel, e.g. for \"projects/my-project/locations/us-central1/operations/my-operation\", pass \"my-operation\""), + allParameters := parameters.Parameters{ + parameters.NewStringParameter("operation", "The name of the operation to cancel, e.g. for \"projects/my-project/locations/us-central1/operations/my-operation\", pass \"my-operation\""), } inputSchema, _ := allParameters.McpManifest() @@ -108,11 +109,11 @@ type Tool struct { manifest tools.Manifest mcpManifest tools.McpManifest - Parameters tools.Parameters + Parameters parameters.Parameters } // Invoke executes the tool's operation. -func (t *Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t *Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { client, err := t.Source.GetOperationsClient(ctx) if err != nil { return nil, fmt.Errorf("failed to get operations client: %w", err) @@ -140,8 +141,8 @@ func (t *Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return fmt.Sprintf("Cancelled [%s].", operation), nil } -func (t *Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t *Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t *Tool) Manifest() tools.Manifest { diff --git a/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go b/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go index 0087a43127..a4d0f33881 100644 --- a/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go +++ b/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/serverlessspark" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/protobuf/encoding/protojson" ) @@ -77,8 +78,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) desc = "Gets a Serverless Spark (aka Dataproc Serverless) batch" } - allParameters := tools.Parameters{ - tools.NewStringParameter("name", "The short name of the batch, e.g. for \"projects/my-project/locations/us-central1/batches/my-batch\", pass \"my-batch\" (the project and location are inherited from the source)"), + allParameters := parameters.Parameters{ + parameters.NewStringParameter("name", "The short name of the batch, e.g. for \"projects/my-project/locations/us-central1/batches/my-batch\", pass \"my-batch\" (the project and location are inherited from the source)"), } inputSchema, _ := allParameters.McpManifest() @@ -110,11 +111,11 @@ type Tool struct { manifest tools.Manifest mcpManifest tools.McpManifest - Parameters tools.Parameters + Parameters parameters.Parameters } // Invoke executes the tool's operation. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { client := t.Source.GetBatchControllerClient() paramMap := params.AsMap() @@ -149,8 +150,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return result, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go b/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go index a45e504a9b..f3bd03f16c 100644 --- a/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go +++ b/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/serverlessspark" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/iterator" ) @@ -76,10 +77,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) desc = "Lists available Serverless Spark (aka Dataproc Serverless) batches" } - allParameters := tools.Parameters{ - tools.NewStringParameterWithRequired("filter", `Filter expression to limit the batches. Filters are case sensitive, and may contain multiple clauses combined with logical operators (AND/OR, case sensitive). Supported fields are batch_id, batch_uuid, state, create_time, and labels. e.g. state = RUNNING AND create_time < "2023-01-01T00:00:00Z" filters for batches in state RUNNING that were created before 2023-01-01. state = RUNNING AND labels.environment=production filters for batches in state in a RUNNING state that have a production environment label. Valid states are STATE_UNSPECIFIED, PENDING, RUNNING, CANCELLING, CANCELLED, SUCCEEDED, FAILED. Valid operators are < > <= >= = !=, and : as "has" for labels, meaning any non-empty value)`, false), - tools.NewIntParameterWithDefault("pageSize", 20, "The maximum number of batches to return in a single page (default 20)"), - tools.NewStringParameterWithRequired("pageToken", "A page token, received from a previous `ListBatches` call", false), + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithRequired("filter", `Filter expression to limit the batches. Filters are case sensitive, and may contain multiple clauses combined with logical operators (AND/OR, case sensitive). Supported fields are batch_id, batch_uuid, state, create_time, and labels. e.g. state = RUNNING AND create_time < "2023-01-01T00:00:00Z" filters for batches in state RUNNING that were created before 2023-01-01. state = RUNNING AND labels.environment=production filters for batches in state in a RUNNING state that have a production environment label. Valid states are STATE_UNSPECIFIED, PENDING, RUNNING, CANCELLING, CANCELLED, SUCCEEDED, FAILED. Valid operators are < > <= >= = !=, and : as "has" for labels, meaning any non-empty value)`, false), + parameters.NewIntParameterWithDefault("pageSize", 20, "The maximum number of batches to return in a single page (default 20)"), + parameters.NewStringParameterWithRequired("pageToken", "A page token, received from a previous `ListBatches` call", false), } inputSchema, _ := allParameters.McpManifest() @@ -111,7 +112,7 @@ type Tool struct { manifest tools.Manifest mcpManifest tools.McpManifest - Parameters tools.Parameters + Parameters parameters.Parameters } // ListBatchesResponse is the response from the list batches API. @@ -131,7 +132,7 @@ type Batch struct { } // Invoke executes the tool's operation. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { client := t.Source.GetBatchControllerClient() parent := fmt.Sprintf("projects/%s/locations/%s", t.Source.Project, t.Source.Location) @@ -185,8 +186,8 @@ func ToBatches(batchPbs []*dataprocpb.Batch) []Batch { return batches } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go b/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go index 5271964bc9..fc98a2c753 100644 --- a/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go +++ b/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "singlestore-execute-sql" @@ -83,19 +84,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.SingleStorePool(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -106,10 +107,10 @@ var _ tools.Tool = Tool{} // Tool represents a tool for executing SQL queries on a SingleStore database. type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest @@ -117,7 +118,7 @@ type Tool struct { } // Invoke executes the provided SQL query using the tool's database connection and returns the results. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -183,8 +184,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/singlestore/singlestoresql/singlestoresql.go b/internal/tools/singlestore/singlestoresql/singlestoresql.go index 59b7f2fc8f..b3a3fbda50 100644 --- a/internal/tools/singlestore/singlestoresql/singlestoresql.go +++ b/internal/tools/singlestore/singlestoresql/singlestoresql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/singlestore" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "singlestore-sql" @@ -53,14 +54,14 @@ var compatibleSources = [...]string{singlestore.SourceKind} // Config defines the configuration for a SingleStore SQL tool. type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -96,7 +97,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -124,12 +125,12 @@ var _ tools.Tool = Tool{} // Tool represents a SingleStore SQL tool instance with its configuration, parameters, and database connection. type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB Statement string @@ -151,14 +152,14 @@ type Tool struct { // Returns: // - A slice of maps, where each map represents a row with column names as keys. // - An error if template resolution, parameter extraction, query execution, or result processing fails. -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -216,8 +217,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/singlestore/singlestoresql/singlestoresql_test.go b/internal/tools/singlestore/singlestoresql/singlestoresql_test.go index d69eaf5cd0..a4c7559cf4 100644 --- a/internal/tools/singlestore/singlestoresql/singlestoresql_test.go +++ b/internal/tools/singlestore/singlestoresql/singlestoresql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/singlestore/singlestoresql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlSingleStore(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlSingleStore(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -144,14 +144,14 @@ func TestParseFromYamlWithTemplateParamsSingleStore(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go b/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go index 891bded786..73c15e6fb5 100644 --- a/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go +++ b/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go @@ -25,6 +25,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/orderedmap" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/iterator" ) @@ -83,21 +84,21 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, ReadOnly: cfg.ReadOnly, Client: s.SpannerClient(), dialect: s.DatabaseDialect(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -107,11 +108,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - ReadOnly bool `yaml:"readOnly"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + ReadOnly bool `yaml:"readOnly"` Client *spanner.Client dialect string manifest tools.Manifest @@ -142,7 +143,7 @@ func processRows(iter *spanner.RowIterator) ([]any, error) { return out, nil } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -182,8 +183,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/spanner/spannerlisttables/spannerlisttables.go b/internal/tools/spanner/spannerlisttables/spannerlisttables.go index d5a91ccb50..263defd8f5 100644 --- a/internal/tools/spanner/spannerlisttables/spannerlisttables.go +++ b/internal/tools/spanner/spannerlisttables/spannerlisttables.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" spannerdb "github.com/googleapis/genai-toolbox/internal/sources/spanner" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/iterator" ) @@ -82,13 +83,13 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } // Define parameters for the tool - allParameters := tools.Parameters{ - tools.NewStringParameterWithDefault( + allParameters := parameters.Parameters{ + parameters.NewStringParameterWithDefault( "table_names", "", "Optional: A comma-separated list of table names. If empty, details for all tables in user-accessible schemas will be listed.", ), - tools.NewStringParameterWithDefault( + parameters.NewStringParameterWithDefault( "output_format", "detailed", "Optional: Use 'simple' to return table names only or use 'detailed' to return the full information schema.", @@ -119,10 +120,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + AllParams parameters.Parameters `yaml:"allParams"` Client *spanner.Client dialect string manifest tools.Manifest @@ -165,7 +166,7 @@ func (t Tool) getStatement() string { } } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() // Get the appropriate SQL statement based on dialect @@ -213,8 +214,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/spanner/spannersql/spanner_test.go b/internal/tools/spanner/spannersql/spanner_test.go index 463d6ed09c..5f86bcae6f 100644 --- a/internal/tools/spanner/spannersql/spanner_test.go +++ b/internal/tools/spanner/spannersql/spanner_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannersql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlSpanner(t *testing.T) { @@ -58,8 +58,8 @@ func TestParseFromYamlSpanner(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, }, }, @@ -89,8 +89,8 @@ func TestParseFromYamlSpanner(t *testing.T) { Statement: "SELECT * FROM SQL_STATEMENT;\n", ReadOnly: true, AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, }, }, @@ -158,12 +158,12 @@ func TestParseFromYamlWithTemplateParamsSpanner(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, @@ -193,8 +193,8 @@ func TestParseFromYamlWithTemplateParamsSpanner(t *testing.T) { Statement: "SELECT * FROM SQL_STATEMENT;\n", ReadOnly: true, AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("country", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), }, }, }, diff --git a/internal/tools/spanner/spannersql/spannersql.go b/internal/tools/spanner/spannersql/spannersql.go index 44e5efd648..78da53d184 100644 --- a/internal/tools/spanner/spannersql/spannersql.go +++ b/internal/tools/spanner/spannersql/spannersql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" spannerdb "github.com/googleapis/genai-toolbox/internal/sources/spanner" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/iterator" ) @@ -54,15 +55,15 @@ var _ compatibleSource = &spannerdb.Source{} var compatibleSources = [...]string{spannerdb.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - ReadOnly bool `yaml:"readOnly"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + ReadOnly bool `yaml:"readOnly"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -85,7 +86,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -114,13 +115,13 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` - ReadOnly bool `yaml:"readOnly"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` + ReadOnly bool `yaml:"readOnly"` Client *spanner.Client dialect string Statement string @@ -128,7 +129,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func getMapParams(params tools.ParamValues, dialect string) (map[string]interface{}, error) { +func getMapParams(params parameters.ParamValues, dialect string) (map[string]interface{}, error) { switch strings.ToLower(dialect) { case "googlesql": return params.AsMap(), nil @@ -163,14 +164,14 @@ func processRows(iter *spanner.RowIterator) ([]any, error) { return out, nil } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -183,19 +184,19 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken // This checks if the param is an array. // If yes, convert []any to typed slice (e.g []string, []int) switch arrayParam := p.(type) { - case *tools.ArrayParameter: + case *parameters.ArrayParameter: arrayParamValue, ok := value.([]any) if !ok { return nil, fmt.Errorf("unable to convert parameter `%s` to []any %w", name, err) } itemType := arrayParam.GetItems().GetType() var err error - value, err = tools.ConvertAnySliceToTyped(arrayParamValue, itemType) + value, err = parameters.ConvertAnySliceToTyped(arrayParamValue, itemType) if err != nil { return nil, fmt.Errorf("unable to convert parameter `%s` from []any to typed slice: %w", name, err) } } - newParams[i] = tools.ParamValue{Name: name, Value: value} + newParams[i] = parameters.ParamValue{Name: name, Value: value} } mapParams, err := getMapParams(newParams, t.dialect) @@ -231,8 +232,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return results, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go index ff369338db..5c57c53a01 100644 --- a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go +++ b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/orderedmap" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "sqlite-execute-sql" @@ -81,18 +82,18 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, DB: s.SQLiteDB(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -102,17 +103,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` DB *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sql, ok := params.AsMap()["sql"].(string) if !ok { return nil, fmt.Errorf("missing or invalid 'sql' parameter") @@ -188,8 +189,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go index b9cbe170a6..f7d103e740 100644 --- a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go +++ b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go @@ -27,6 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqliteexecutesql" "github.com/googleapis/genai-toolbox/internal/util/orderedmap" + "github.com/googleapis/genai-toolbox/internal/util/parameters" _ "modernc.org/sqlite" ) @@ -99,12 +100,12 @@ func TestTool_Invoke(t *testing.T) { Name string Kind string AuthRequired []string - Parameters tools.Parameters + Parameters parameters.Parameters DB *sql.DB } type args struct { ctx context.Context - params tools.ParamValues + params parameters.ParamValues accessToken tools.AccessToken } tests := []struct { @@ -121,7 +122,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)"}, }, }, @@ -135,7 +136,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER); INSERT INTO users (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25)"}, }, }, @@ -155,7 +156,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: "SELECT * FROM users"}, }, }, @@ -190,7 +191,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: "DROP TABLE users"}, }, }, @@ -204,7 +205,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: "SELECT * FROM non_existent_table"}, }, }, @@ -218,7 +219,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: ""}, }, }, @@ -241,7 +242,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: "SELECT * FROM data_types"}, }, }, @@ -278,7 +279,7 @@ func TestTool_Invoke(t *testing.T) { }, args: args{ ctx: ctx, - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "sql", Value: "SELECT u.name, o.item FROM users u JOIN orders o ON u.id = o.user_id"}, }, }, diff --git a/internal/tools/sqlite/sqlitesql/sqlitesql.go b/internal/tools/sqlite/sqlitesql/sqlitesql.go index eec112af03..12ca95eedc 100644 --- a/internal/tools/sqlite/sqlitesql/sqlitesql.go +++ b/internal/tools/sqlite/sqlitesql/sqlitesql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/sqlite" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "sqlite-sql" @@ -52,14 +53,14 @@ var _ compatibleSource = &sqlite.Source{} var compatibleSources = [...]string{sqlite.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -82,7 +83,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -109,12 +110,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Db *sql.DB Statement string `yaml:"statement"` @@ -122,14 +123,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -193,8 +194,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/sqlite/sqlitesql/sqlitesql_test.go b/internal/tools/sqlite/sqlitesql/sqlitesql_test.go index d2b0af044a..8afc3b23c7 100644 --- a/internal/tools/sqlite/sqlitesql/sqlitesql_test.go +++ b/internal/tools/sqlite/sqlitesql/sqlitesql_test.go @@ -26,6 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/testutils" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqlitesql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" _ "modernc.org/sqlite" ) @@ -70,9 +71,9 @@ func TestParseFromYamlSQLite(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -149,14 +150,14 @@ func TestParseFromYamlWithTemplateSqlite(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, @@ -211,15 +212,15 @@ func TestTool_Invoke(t *testing.T) { Name string Kind string AuthRequired []string - Parameters tools.Parameters - TemplateParameters tools.Parameters - AllParams tools.Parameters + Parameters parameters.Parameters + TemplateParameters parameters.Parameters + AllParams parameters.Parameters Db *sql.DB Statement string } type args struct { ctx context.Context - params tools.ParamValues + params parameters.ParamValues accessToken tools.AccessToken } tests := []struct { @@ -249,13 +250,13 @@ func TestTool_Invoke(t *testing.T) { fields: fields{ Db: setupTestDB(t), Statement: "SELECT * FROM users WHERE name = ?", - Parameters: []tools.Parameter{ - tools.NewStringParameter("name", "user name"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("name", "user name"), }, }, args: args{ ctx: context.Background(), - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "name", Value: "Alice"}, }, }, @@ -269,13 +270,13 @@ func TestTool_Invoke(t *testing.T) { fields: fields{ Db: setupTestDB(t), Statement: "SELECT * FROM {{.tableName}}", - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "table name"), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "table name"), }, }, args: args{ ctx: context.Background(), - params: []tools.ParamValue{ + params: []parameters.ParamValue{ {Name: "tableName", Value: "users"}, }, }, diff --git a/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go b/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go index f6a53058a6..fcffae9665 100644 --- a/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go +++ b/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources/tidb" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "tidb-execute-sql" @@ -79,19 +80,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The sql to execute.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The sql to execute.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Pool: s.TiDBPool(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -101,17 +102,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Pool *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() sql, ok := paramsMap["sql"].(string) if !ok { @@ -181,8 +182,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/tidb/tidbsql/tidbsql.go b/internal/tools/tidb/tidbsql/tidbsql.go index a33321ccb8..0795ed7120 100644 --- a/internal/tools/tidb/tidbsql/tidbsql.go +++ b/internal/tools/tidb/tidbsql/tidbsql.go @@ -24,6 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/tidb" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "tidb-sql" @@ -52,14 +53,14 @@ var _ compatibleSource = &tidb.Source{} var compatibleSources = [...]string{tidb.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -82,7 +83,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -109,12 +110,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *sql.DB Statement string @@ -122,14 +123,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -199,8 +200,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/tidb/tidbsql/tidbsql_test.go b/internal/tools/tidb/tidbsql/tidbsql_test.go index b30ca19a9f..4a5c425d03 100644 --- a/internal/tools/tidb/tidbsql/tidbsql_test.go +++ b/internal/tools/tidb/tidbsql/tidbsql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/tidb/tidbsql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlTiDB(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlTiDB(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -144,14 +144,14 @@ func TestParseFromYamlWithTemplateParamsTiDB(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/tools.go b/internal/tools/tools.go index 08cd458900..6d7bb79959 100644 --- a/internal/tools/tools.go +++ b/internal/tools/tools.go @@ -16,13 +16,14 @@ package tools import ( "context" - "errors" "fmt" "slices" "strings" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" + "github.com/googleapis/genai-toolbox/internal/util" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) // ToolConfigFactory defines the signature for a function that creates and @@ -70,14 +71,14 @@ type AccessToken string func (token AccessToken) ParseBearerToken() (string, error) { headerParts := strings.Split(string(token), " ") if len(headerParts) != 2 || strings.ToLower(headerParts[0]) != "bearer" { - return "", fmt.Errorf("authorization header must be in the format 'Bearer ': %w", ErrUnauthorized) + return "", fmt.Errorf("authorization header must be in the format 'Bearer ': %w", util.ErrUnauthorized) } return headerParts[1], nil } type Tool interface { - Invoke(context.Context, ParamValues, AccessToken) (any, error) - ParseParams(map[string]any, map[string]map[string]any) (ParamValues, error) + Invoke(context.Context, parameters.ParamValues, AccessToken) (any, error) + ParseParams(map[string]any, map[string]map[string]any) (parameters.ParamValues, error) Manifest() Manifest McpManifest() McpManifest Authorized([]string) bool @@ -86,9 +87,9 @@ type Tool interface { // Manifest is the representation of tools sent to Client SDKs. type Manifest struct { - Description string `json:"description"` - Parameters []ParameterManifest `json:"parameters"` - AuthRequired []string `json:"authRequired"` + Description string `json:"description"` + Parameters []parameters.ParameterManifest `json:"parameters"` + AuthRequired []string `json:"authRequired"` } // Definition for a tool the MCP client can call. @@ -98,11 +99,11 @@ type McpManifest struct { // A human-readable description of the tool. Description string `json:"description,omitempty"` // A JSON Schema object defining the expected parameters for the tool. - InputSchema McpToolsSchema `json:"inputSchema,omitempty"` - Metadata map[string]any `json:"_meta,omitempty"` + InputSchema parameters.McpToolsSchema `json:"inputSchema,omitempty"` + Metadata map[string]any `json:"_meta,omitempty"` } -func GetMcpManifest(name, desc string, authInvoke []string, params Parameters) McpManifest { +func GetMcpManifest(name, desc string, authInvoke []string, params parameters.Parameters) McpManifest { inputSchema, authParams := params.McpManifest() mcpManifest := McpManifest{ Name: name, @@ -124,8 +125,6 @@ func GetMcpManifest(name, desc string, authInvoke []string, params Parameters) M return mcpManifest } -var ErrUnauthorized = errors.New("unauthorized") - // Helper function that returns if a tool invocation request is authorized func IsAuthorized(authRequiredSources []string, verifiedAuthServices []string) bool { if len(authRequiredSources) == 0 { diff --git a/internal/tools/tools_test.go b/internal/tools/tools_test.go index 50f56cd38e..1b357d2292 100644 --- a/internal/tools/tools_test.go +++ b/internal/tools/tools_test.go @@ -19,10 +19,11 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestGetMcpManifestMetadata(t *testing.T) { - authServices := []tools.ParamAuthService{ + authServices := []parameters.ParamAuthService{ { Name: "my-google-auth-service", Field: "auth_field", @@ -36,7 +37,7 @@ func TestGetMcpManifestMetadata(t *testing.T) { name string description string authInvoke []string - params tools.Parameters + params parameters.Parameters wantMetadata map[string]any }{ { @@ -44,7 +45,7 @@ func TestGetMcpManifestMetadata(t *testing.T) { name: "basic", description: "foo bar", authInvoke: []string{}, - params: tools.Parameters{tools.NewStringParameter("string-param", "string parameter")}, + params: parameters.Parameters{parameters.NewStringParameter("string-param", "string parameter")}, wantMetadata: nil, }, { @@ -52,7 +53,7 @@ func TestGetMcpManifestMetadata(t *testing.T) { name: "basic", description: "foo bar", authInvoke: []string{"auth1", "auth2"}, - params: tools.Parameters{tools.NewStringParameter("string-param", "string parameter")}, + params: parameters.Parameters{parameters.NewStringParameter("string-param", "string parameter")}, wantMetadata: map[string]any{"toolbox/authInvoke": []string{"auth1", "auth2"}}, }, { @@ -60,7 +61,7 @@ func TestGetMcpManifestMetadata(t *testing.T) { name: "basic", description: "foo bar", authInvoke: []string{}, - params: tools.Parameters{tools.NewStringParameterWithAuth("string-param", "string parameter", authServices)}, + params: parameters.Parameters{parameters.NewStringParameterWithAuth("string-param", "string parameter", authServices)}, wantMetadata: map[string]any{ "toolbox/authParam": map[string][]string{ "string-param": []string{"my-google-auth-service", "other-auth-service"}, @@ -72,7 +73,7 @@ func TestGetMcpManifestMetadata(t *testing.T) { name: "basic", description: "foo bar", authInvoke: []string{"auth1", "auth2"}, - params: tools.Parameters{tools.NewStringParameterWithAuth("string-param", "string parameter", authServices)}, + params: parameters.Parameters{parameters.NewStringParameterWithAuth("string-param", "string parameter", authServices)}, wantMetadata: map[string]any{ "toolbox/authInvoke": []string{"auth1", "auth2"}, "toolbox/authParam": map[string][]string{ diff --git a/internal/tools/toolsets.go b/internal/tools/toolsets.go index a304481370..403cff00b4 100644 --- a/internal/tools/toolsets.go +++ b/internal/tools/toolsets.go @@ -16,6 +16,7 @@ package tools import ( "fmt" + "regexp" ) type ToolsetConfig struct { @@ -60,3 +61,9 @@ func (t ToolsetConfig) Initialize(serverVersion string, toolsMap map[string]Tool return toolset, nil } + +var validName = regexp.MustCompile(`^[a-zA-Z0-9_-]*$`) + +func IsValidName(s string) bool { + return validName.MatchString(s) +} diff --git a/internal/tools/trino/trinoexecutesql/trinoexecutesql.go b/internal/tools/trino/trinoexecutesql/trinoexecutesql.go index ac471f8a3a..f368d2379f 100644 --- a/internal/tools/trino/trinoexecutesql/trinoexecutesql.go +++ b/internal/tools/trino/trinoexecutesql/trinoexecutesql.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/trino" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "trino-execute-sql" @@ -78,19 +79,19 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - sqlParameter := tools.NewStringParameter("sql", "The SQL query to execute against the Trino database.") - parameters := tools.Parameters{sqlParameter} + sqlParameter := parameters.NewStringParameter("sql", "The SQL query to execute against the Trino database.") + params := parameters.Parameters{sqlParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) // finish tool setup t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, + Parameters: params, AuthRequired: cfg.AuthRequired, Db: s.TrinoDB(), - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -100,17 +101,17 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Db *sql.DB manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { sliceParams := params.AsSlice() sql, ok := sliceParams[0].(string) if !ok { @@ -166,8 +167,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/trino/trinosql/trinosql.go b/internal/tools/trino/trinosql/trinosql.go index 17befdcbc8..8ef2cba221 100644 --- a/internal/tools/trino/trinosql/trinosql.go +++ b/internal/tools/trino/trinosql/trinosql.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/trino" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "trino-sql" @@ -51,14 +52,14 @@ var _ compatibleSource = &trino.Source{} var compatibleSources = [...]string{trino.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -81,7 +82,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, fmt.Errorf("unable to process parameters: %w", err) } @@ -108,12 +109,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Statement string Db *sql.DB @@ -121,13 +122,13 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -181,8 +182,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/trino/trinosql/trinosql_test.go b/internal/tools/trino/trinosql/trinosql_test.go index 40426beebb..2974e0dd04 100644 --- a/internal/tools/trino/trinosql/trinosql_test.go +++ b/internal/tools/trino/trinosql/trinosql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/trino/trinosql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlTrino(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlTrino(t *testing.T) { Description: "some description", Statement: "SELECT * FROM catalog.schema.table WHERE id = ?;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("id", "ID to filter by", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("id", "ID to filter by", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, }, @@ -150,16 +150,16 @@ func TestParseFromYamlWithTemplateParamsTrino(t *testing.T) { Description: "some description", Statement: "SELECT * FROM {{ .catalog }}.{{ .schema }}.{{ .tableName }} WHERE country = ?;\n", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("country", "some description", - []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("country", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}}), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("catalog", "The catalog to query from."), - tools.NewStringParameter("schema", "The schema to query from."), - tools.NewStringParameter("tableName", "The table to select data from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("catalog", "The catalog to query from."), + parameters.NewStringParameter("schema", "The schema to query from."), + parameters.NewStringParameter("tableName", "The table to select data from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/utility/wait/wait.go b/internal/tools/utility/wait/wait.go index b8d0adfab9..217260a5fc 100644 --- a/internal/tools/utility/wait/wait.go +++ b/internal/tools/utility/wait/wait.go @@ -22,6 +22,7 @@ import ( yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) const kind string = "wait" @@ -55,16 +56,16 @@ func (cfg Config) ToolConfigKind() string { } func (cfg Config) Initialize(_ map[string]sources.Source) (tools.Tool, error) { - durationParameter := tools.NewStringParameter("duration", "The duration to wait for, specified as a string (e.g., '10s', '2m', '1h').") - parameters := tools.Parameters{durationParameter} + durationParameter := parameters.NewStringParameter("duration", "The duration to wait for, specified as a string (e.g., '10s', '2m', '1h').") + params := parameters.Parameters{durationParameter} - mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters) + mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params) t := Tool{ Name: cfg.Name, Kind: kind, - Parameters: parameters, - manifest: tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired}, + Parameters: params, + manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, mcpManifest: mcpManifest, } return t, nil @@ -76,12 +77,12 @@ var _ tools.Tool = Tool{} type Tool struct { Name string Kind string - Parameters tools.Parameters + Parameters parameters.Parameters manifest tools.Manifest mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() durationStr, ok := paramsMap["duration"].(string) @@ -99,8 +100,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return fmt.Sprintf("Wait for %v completed successfully.", totalDuration), nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/valkey/valkey.go b/internal/tools/valkey/valkey.go index 49f9f4ade8..be90db1218 100644 --- a/internal/tools/valkey/valkey.go +++ b/internal/tools/valkey/valkey.go @@ -21,6 +21,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" valkeysrc "github.com/googleapis/genai-toolbox/internal/sources/valkey" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/valkey-io/valkey-go" ) @@ -50,13 +51,13 @@ var _ compatibleSource = &valkeysrc.Source{} var compatibleSources = [...]string{valkeysrc.SourceKind, valkeysrc.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Commands [][]string `yaml:"commands" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Commands [][]string `yaml:"commands" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` } // validate interface @@ -99,10 +100,10 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` Client valkey.Client Commands [][]string @@ -110,7 +111,7 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { // Replace parameters commands, err := replaceCommandsParams(t.Commands, t.Parameters, params) if err != nil { @@ -151,7 +152,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken } // replaceCommandsParams is a helper function to replace parameters in the commands -func replaceCommandsParams(commands [][]string, params tools.Parameters, paramValues tools.ParamValues) ([][]string, error) { +func replaceCommandsParams(commands [][]string, params parameters.Parameters, paramValues parameters.ParamValues) ([][]string, error) { paramMap := paramValues.AsMapWithDollarPrefix() typeMap := make(map[string]string, len(params)) for _, p := range params { @@ -184,8 +185,8 @@ func replaceCommandsParams(commands [][]string, params tools.Parameters, paramVa return newCommands, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.Parameters, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.Parameters, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/valkey/valkey_test.go b/internal/tools/valkey/valkey_test.go index 23bb2b7346..8b99471806 100644 --- a/internal/tools/valkey/valkey_test.go +++ b/internal/tools/valkey/valkey_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/valkey" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlvalkey(t *testing.T) { @@ -59,8 +59,8 @@ func TestParseFromYamlvalkey(t *testing.T) { Description: "some description", AuthRequired: []string{}, Commands: [][]string{{"SET", "greeting", "hello, {{.name}}"}, {"GET", "id"}}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("name", "user name"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("name", "user name"), }, }, }, diff --git a/internal/tools/yugabytedbsql/yugabytedbsql.go b/internal/tools/yugabytedbsql/yugabytedbsql.go index ce8c9f2105..e94b5584e3 100644 --- a/internal/tools/yugabytedbsql/yugabytedbsql.go +++ b/internal/tools/yugabytedbsql/yugabytedbsql.go @@ -22,6 +22,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/yugabytedb" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/yugabyte/pgx/v5/pgxpool" ) @@ -48,14 +49,14 @@ type compatibleSource interface { var compatibleSources = [...]string{yugabytedb.SourceKind} type Config struct { - Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` - Source string `yaml:"source" validate:"required"` - Description string `yaml:"description" validate:"required"` - Statement string `yaml:"statement" validate:"required"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` + Name string `yaml:"name" validate:"required"` + Kind string `yaml:"kind" validate:"required"` + Source string `yaml:"source" validate:"required"` + Description string `yaml:"description" validate:"required"` + Statement string `yaml:"statement" validate:"required"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` } // validate interface @@ -78,7 +79,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) } - allParameters, paramManifest, err := tools.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) + allParameters, paramManifest, err := parameters.ProcessParameters(cfg.TemplateParameters, cfg.Parameters) if err != nil { return nil, err } @@ -105,12 +106,12 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) var _ tools.Tool = Tool{} type Tool struct { - Name string `yaml:"name"` - Kind string `yaml:"kind"` - AuthRequired []string `yaml:"authRequired"` - Parameters tools.Parameters `yaml:"parameters"` - TemplateParameters tools.Parameters `yaml:"templateParameters"` - AllParams tools.Parameters `yaml:"allParams"` + Name string `yaml:"name"` + Kind string `yaml:"kind"` + AuthRequired []string `yaml:"authRequired"` + Parameters parameters.Parameters `yaml:"parameters"` + TemplateParameters parameters.Parameters `yaml:"templateParameters"` + AllParams parameters.Parameters `yaml:"allParams"` Pool *pgxpool.Pool Statement string @@ -118,14 +119,14 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { paramsMap := params.AsMap() - newStatement, err := tools.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) + newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract template params %w", err) } - newParams, err := tools.GetParams(t.Parameters, paramsMap) + newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { return nil, fmt.Errorf("unable to extract standard params %w", err) } @@ -153,8 +154,8 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken return out, nil } -func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) { - return tools.ParseParams(t.AllParams, data, claims) +func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { + return parameters.ParseParams(t.AllParams, data, claims) } func (t Tool) Manifest() tools.Manifest { diff --git a/internal/tools/yugabytedbsql/yugabytedbsql_test.go b/internal/tools/yugabytedbsql/yugabytedbsql_test.go index b1e79aa417..e0a9cd1d04 100644 --- a/internal/tools/yugabytedbsql/yugabytedbsql_test.go +++ b/internal/tools/yugabytedbsql/yugabytedbsql_test.go @@ -21,8 +21,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/yugabytedbsql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParseFromYamlYugabyteDBSQL(t *testing.T) { @@ -66,9 +66,9 @@ func TestParseFromYamlYugabyteDBSQL(t *testing.T) { Description: "search hotels by city", Statement: "SELECT * FROM hotels WHERE city = $1;\n", AuthRequired: []string{"auth-service-a", "auth-service-b"}, - Parameters: []tools.Parameter{ - tools.NewStringParameterWithAuth("city", "city name", - []tools.ParamAuthService{ + Parameters: []parameters.Parameter{ + parameters.NewStringParameterWithAuth("city", "city name", + []parameters.ParamAuthService{ {Name: "auth-service-a", Field: "user_id"}, {Name: "auth-service-b", Field: "user_id"}, }, @@ -184,12 +184,12 @@ func TestParseFromYamlWithTemplateParamsYugabyteDB(t *testing.T) { Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", AuthRequired: []string{}, - Parameters: []tools.Parameter{ - tools.NewStringParameter("name", "some description"), + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("name", "some description"), }, - TemplateParameters: []tools.Parameter{ - tools.NewStringParameter("tableName", "The table to select hotels from."), - tools.NewArrayParameter("fieldArray", "The columns to return for the query.", tools.NewStringParameter("column", "A column name that will be returned from the query.")), + TemplateParameters: []parameters.Parameter{ + parameters.NewStringParameter("tableName", "The table to select hotels from."), + parameters.NewArrayParameter("fieldArray", "The columns to return for the query.", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), }, }, }, diff --git a/internal/tools/common.go b/internal/util/parameters/common.go similarity index 96% rename from internal/tools/common.go rename to internal/util/parameters/common.go index 7d57d147bf..e3f6a03736 100644 --- a/internal/tools/common.go +++ b/internal/util/parameters/common.go @@ -12,22 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tools +package parameters import ( "bytes" "encoding/json" "fmt" - "regexp" "text/template" ) -var validName = regexp.MustCompile(`^[a-zA-Z0-9_-]*$`) - -func IsValidName(s string) bool { - return validName.MatchString(s) -} - // ConvertAnySliceToTyped a []any to typed slice ([]string, []int, []float etc.) func ConvertAnySliceToTyped(s []any, itemType string) (any, error) { var typedSlice any diff --git a/internal/tools/common_test.go b/internal/util/parameters/common_test.go similarity index 95% rename from internal/tools/common_test.go rename to internal/util/parameters/common_test.go index 9d677fe950..b2da9d7040 100644 --- a/internal/tools/common_test.go +++ b/internal/util/parameters/common_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tools_test +package parameters_test import ( "strings" @@ -20,7 +20,7 @@ import ( "text/template" "github.com/google/go-cmp/cmp" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestPopulateTemplate(t *testing.T) { @@ -92,7 +92,7 @@ func TestPopulateTemplate(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got, err := tools.PopulateTemplate(tc.templateName, tc.templateString, tc.data) + got, err := parameters.PopulateTemplate(tc.templateName, tc.templateString, tc.data) if tc.wantErr { if err == nil { t.Fatalf("expected error, got nil") @@ -185,7 +185,7 @@ func TestPopulateTemplateWithFunc(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got, err := tools.PopulateTemplateWithFunc(tc.templateName, tc.templateString, tc.data, tc.funcMap) + got, err := parameters.PopulateTemplateWithFunc(tc.templateName, tc.templateString, tc.data, tc.funcMap) if tc.wantErr { if err == nil { t.Fatalf("expected error, got nil") @@ -279,7 +279,7 @@ func TestPopulateTemplateWithJSON(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got, err := tools.PopulateTemplateWithJSON(tc.templateName, tc.templateString, tc.data) + got, err := parameters.PopulateTemplateWithJSON(tc.templateName, tc.templateString, tc.data) if tc.wantErr { if err == nil { t.Fatalf("expected error, got nil") diff --git a/internal/tools/parameters.go b/internal/util/parameters/parameters.go similarity index 99% rename from internal/tools/parameters.go rename to internal/util/parameters/parameters.go index e193f4e5ab..fe4d7817be 100644 --- a/internal/tools/parameters.go +++ b/internal/util/parameters/parameters.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tools +package parameters import ( "bytes" @@ -117,7 +117,7 @@ func parseFromAuthService(paramAuthServices []ParamAuthService, claimsMap map[st } return v, nil } - return nil, fmt.Errorf("missing or invalid authentication header: %w", ErrUnauthorized) + return nil, fmt.Errorf("missing or invalid authentication header: %w", util.ErrUnauthorized) } // CheckParamRequired checks if a parameter is required based on the required and default field. diff --git a/internal/tools/parameters_test.go b/internal/util/parameters/parameters_test.go similarity index 57% rename from internal/tools/parameters_test.go rename to internal/util/parameters/parameters_test.go index 9f33e74cc7..7ee2423789 100644 --- a/internal/tools/parameters_test.go +++ b/internal/util/parameters/parameters_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package tools_test +package parameters_test import ( "bytes" @@ -26,7 +26,7 @@ import ( "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestParametersMarshal(t *testing.T) { @@ -37,7 +37,7 @@ func TestParametersMarshal(t *testing.T) { tcs := []struct { name string in []map[string]any - want tools.Parameters + want parameters.Parameters }{ { name: "string", @@ -48,8 +48,8 @@ func TestParametersMarshal(t *testing.T) { "description": "this param is a string", }, }, - want: tools.Parameters{ - tools.NewStringParameter("my_string", "this param is a string"), + want: parameters.Parameters{ + parameters.NewStringParameter("my_string", "this param is a string"), }, }, { @@ -62,8 +62,8 @@ func TestParametersMarshal(t *testing.T) { "required": false, }, }, - want: tools.Parameters{ - tools.NewStringParameterWithRequired("my_string", "this param is a string", false), + want: parameters.Parameters{ + parameters.NewStringParameterWithRequired("my_string", "this param is a string", false), }, }, { @@ -75,8 +75,8 @@ func TestParametersMarshal(t *testing.T) { "description": "this param is an int", }, }, - want: tools.Parameters{ - tools.NewIntParameter("my_integer", "this param is an int"), + want: parameters.Parameters{ + parameters.NewIntParameter("my_integer", "this param is an int"), }, }, { @@ -89,8 +89,8 @@ func TestParametersMarshal(t *testing.T) { "required": false, }, }, - want: tools.Parameters{ - tools.NewIntParameterWithRequired("my_integer", "this param is an int", false), + want: parameters.Parameters{ + parameters.NewIntParameterWithRequired("my_integer", "this param is an int", false), }, }, { @@ -102,8 +102,8 @@ func TestParametersMarshal(t *testing.T) { "description": "my param is a float", }, }, - want: tools.Parameters{ - tools.NewFloatParameter("my_float", "my param is a float"), + want: parameters.Parameters{ + parameters.NewFloatParameter("my_float", "my param is a float"), }, }, { @@ -116,8 +116,8 @@ func TestParametersMarshal(t *testing.T) { "required": false, }, }, - want: tools.Parameters{ - tools.NewFloatParameterWithRequired("my_float", "my param is a float", false), + want: parameters.Parameters{ + parameters.NewFloatParameterWithRequired("my_float", "my param is a float", false), }, }, { @@ -129,8 +129,8 @@ func TestParametersMarshal(t *testing.T) { "description": "this param is a boolean", }, }, - want: tools.Parameters{ - tools.NewBooleanParameter("my_bool", "this param is a boolean"), + want: parameters.Parameters{ + parameters.NewBooleanParameter("my_bool", "this param is a boolean"), }, }, { @@ -143,8 +143,8 @@ func TestParametersMarshal(t *testing.T) { "required": false, }, }, - want: tools.Parameters{ - tools.NewBooleanParameterWithRequired("my_bool", "this param is a boolean", false), + want: parameters.Parameters{ + parameters.NewBooleanParameterWithRequired("my_bool", "this param is a boolean", false), }, }, { @@ -161,8 +161,8 @@ func TestParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameter("my_array", "this param is an array of strings", tools.NewStringParameter("my_string", "string item")), + want: parameters.Parameters{ + parameters.NewArrayParameter("my_array", "this param is an array of strings", parameters.NewStringParameter("my_string", "string item")), }, }, { @@ -180,8 +180,8 @@ func TestParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameterWithRequired("my_array", "this param is an array of strings", false, tools.NewStringParameter("my_string", "string item")), + want: parameters.Parameters{ + parameters.NewArrayParameterWithRequired("my_array", "this param is an array of strings", false, parameters.NewStringParameter("my_string", "string item")), }, }, { @@ -198,8 +198,8 @@ func TestParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameter("my_array", "this param is an array of floats", tools.NewFloatParameter("my_float", "float item")), + want: parameters.Parameters{ + parameters.NewArrayParameter("my_array", "this param is an array of floats", parameters.NewFloatParameter("my_float", "float item")), }, }, { @@ -212,8 +212,8 @@ func TestParametersMarshal(t *testing.T) { "description": "this param is a string", }, }, - want: tools.Parameters{ - tools.NewStringParameterWithDefault("my_string", "foo", "this param is a string"), + want: parameters.Parameters{ + parameters.NewStringParameterWithDefault("my_string", "foo", "this param is a string"), }, }, { @@ -226,8 +226,8 @@ func TestParametersMarshal(t *testing.T) { "description": "this param is an int", }, }, - want: tools.Parameters{ - tools.NewIntParameterWithDefault("my_integer", 5, "this param is an int"), + want: parameters.Parameters{ + parameters.NewIntParameterWithDefault("my_integer", 5, "this param is an int"), }, }, { @@ -240,8 +240,8 @@ func TestParametersMarshal(t *testing.T) { "description": "my param is a float", }, }, - want: tools.Parameters{ - tools.NewFloatParameterWithDefault("my_float", 1.1, "my param is a float"), + want: parameters.Parameters{ + parameters.NewFloatParameterWithDefault("my_float", 1.1, "my param is a float"), }, }, { @@ -254,8 +254,8 @@ func TestParametersMarshal(t *testing.T) { "description": "this param is a boolean", }, }, - want: tools.Parameters{ - tools.NewBooleanParameterWithDefault("my_bool", true, "this param is a boolean"), + want: parameters.Parameters{ + parameters.NewBooleanParameterWithDefault("my_bool", true, "this param is a boolean"), }, }, { @@ -273,8 +273,8 @@ func TestParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameterWithDefault("my_array", []any{"foo", "bar"}, "this param is an array of strings", tools.NewStringParameter("my_string", "string item")), + want: parameters.Parameters{ + parameters.NewArrayParameterWithDefault("my_array", []any{"foo", "bar"}, "this param is an array of strings", parameters.NewStringParameter("my_string", "string item")), }, }, { @@ -292,8 +292,8 @@ func TestParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameterWithDefault("my_array", []any{1.0, 1.1}, "this param is an array of floats", tools.NewFloatParameter("my_float", "float item")), + want: parameters.Parameters{ + parameters.NewArrayParameterWithDefault("my_array", []any{1.0, 1.1}, "this param is an array of floats", parameters.NewFloatParameter("my_float", "float item")), }, }, { @@ -306,8 +306,8 @@ func TestParametersMarshal(t *testing.T) { "valueType": "string", }, }, - want: tools.Parameters{ - tools.NewMapParameter("my_map", "this param is a map of strings", "string"), + want: parameters.Parameters{ + parameters.NewMapParameter("my_map", "this param is a map of strings", "string"), }, }, { @@ -321,8 +321,8 @@ func TestParametersMarshal(t *testing.T) { "valueType": "string", }, }, - want: tools.Parameters{ - tools.NewMapParameterWithRequired("my_map", "this param is a map of strings", false, "string"), + want: parameters.Parameters{ + parameters.NewMapParameterWithRequired("my_map", "this param is a map of strings", false, "string"), }, }, { @@ -336,8 +336,8 @@ func TestParametersMarshal(t *testing.T) { "valueType": "string", }, }, - want: tools.Parameters{ - tools.NewMapParameterWithDefault("my_map", map[string]any{"key1": "val1"}, "this param is a map of strings", "string"), + want: parameters.Parameters{ + parameters.NewMapParameterWithDefault("my_map", map[string]any{"key1": "val1"}, "this param is a map of strings", "string"), }, }, { @@ -349,14 +349,14 @@ func TestParametersMarshal(t *testing.T) { "description": "this param is a generic map", }, }, - want: tools.Parameters{ - tools.NewMapParameter("my_generic_map", "this param is a generic map", ""), + want: parameters.Parameters{ + parameters.NewMapParameter("my_generic_map", "this param is a generic map", ""), }, }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - var got tools.Parameters + var got parameters.Parameters // parse map to bytes data, err := yaml.Marshal(tc.in) if err != nil { @@ -379,11 +379,11 @@ func TestAuthParametersMarshal(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %s", err) } - authServices := []tools.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}} + authServices := []parameters.ParamAuthService{{Name: "my-google-auth-service", Field: "user_id"}, {Name: "other-auth-service", Field: "user_id"}} tcs := []struct { name string in []map[string]any - want tools.Parameters + want parameters.Parameters }{ { name: "string", @@ -404,8 +404,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewStringParameterWithAuth("my_string", "this param is a string", authServices), + want: parameters.Parameters{ + parameters.NewStringParameterWithAuth("my_string", "this param is a string", authServices), }, }, { @@ -427,8 +427,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewStringParameterWithAuth("my_string", "this param is a string", authServices), + want: parameters.Parameters{ + parameters.NewStringParameterWithAuth("my_string", "this param is a string", authServices), }, }, { @@ -450,8 +450,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewIntParameterWithAuth("my_integer", "this param is an int", authServices), + want: parameters.Parameters{ + parameters.NewIntParameterWithAuth("my_integer", "this param is an int", authServices), }, }, { @@ -473,8 +473,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewIntParameterWithAuth("my_integer", "this param is an int", authServices), + want: parameters.Parameters{ + parameters.NewIntParameterWithAuth("my_integer", "this param is an int", authServices), }, }, { @@ -496,8 +496,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewFloatParameterWithAuth("my_float", "my param is a float", authServices), + want: parameters.Parameters{ + parameters.NewFloatParameterWithAuth("my_float", "my param is a float", authServices), }, }, { @@ -519,8 +519,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewFloatParameterWithAuth("my_float", "my param is a float", authServices), + want: parameters.Parameters{ + parameters.NewFloatParameterWithAuth("my_float", "my param is a float", authServices), }, }, { @@ -542,8 +542,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewBooleanParameterWithAuth("my_bool", "this param is a boolean", authServices), + want: parameters.Parameters{ + parameters.NewBooleanParameterWithAuth("my_bool", "this param is a boolean", authServices), }, }, { @@ -565,8 +565,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewBooleanParameterWithAuth("my_bool", "this param is a boolean", authServices), + want: parameters.Parameters{ + parameters.NewBooleanParameterWithAuth("my_bool", "this param is a boolean", authServices), }, }, { @@ -593,8 +593,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameterWithAuth("my_array", "this param is an array of strings", tools.NewStringParameter("my_string", "string item"), authServices), + want: parameters.Parameters{ + parameters.NewArrayParameterWithAuth("my_array", "this param is an array of strings", parameters.NewStringParameter("my_string", "string item"), authServices), }, }, { @@ -621,8 +621,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameterWithAuth("my_array", "this param is an array of strings", tools.NewStringParameter("my_string", "string item"), authServices), + want: parameters.Parameters{ + parameters.NewArrayParameterWithAuth("my_array", "this param is an array of strings", parameters.NewStringParameter("my_string", "string item"), authServices), }, }, { @@ -649,8 +649,8 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewArrayParameterWithAuth("my_array", "this param is an array of floats", tools.NewFloatParameter("my_float", "float item"), authServices), + want: parameters.Parameters{ + parameters.NewArrayParameterWithAuth("my_array", "this param is an array of floats", parameters.NewFloatParameter("my_float", "float item"), authServices), }, }, { @@ -667,14 +667,14 @@ func TestAuthParametersMarshal(t *testing.T) { }, }, }, - want: tools.Parameters{ - tools.NewMapParameterWithAuth("my_map", "this param is a map of strings", "string", authServices), + want: parameters.Parameters{ + parameters.NewMapParameterWithAuth("my_map", "this param is a map of strings", "string", authServices), }, }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - var got tools.Parameters + var got parameters.Parameters // parse map to bytes data, err := yaml.Marshal(tc.in) if err != nil { @@ -697,25 +697,25 @@ func TestParametersParse(t *testing.T) { floatValue := 1.5 tcs := []struct { name string - params tools.Parameters + params parameters.Parameters in map[string]any - want tools.ParamValues + want parameters.ParamValues }{ // ... (primitive type tests are unchanged) { name: "string", - params: tools.Parameters{ - tools.NewStringParameter("my_string", "this param is a string"), + params: parameters.Parameters{ + parameters.NewStringParameter("my_string", "this param is a string"), }, in: map[string]any{ "my_string": "hello world", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "hello world"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "hello world"}}, }, { name: "not string", - params: tools.Parameters{ - tools.NewStringParameter("my_string", "this param is a string"), + params: parameters.Parameters{ + parameters.NewStringParameter("my_string", "this param is a string"), }, in: map[string]any{ "my_string": 4, @@ -723,28 +723,28 @@ func TestParametersParse(t *testing.T) { }, { name: "string allowed", - params: tools.Parameters{ - tools.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"foo"}), + params: parameters.Parameters{ + parameters.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"foo"}), }, in: map[string]any{ "my_string": "foo", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "foo"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "foo"}}, }, { name: "string allowed regex", - params: tools.Parameters{ - tools.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"^f.*"}), + params: parameters.Parameters{ + parameters.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"^f.*"}), }, in: map[string]any{ "my_string": "foo", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "foo"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "foo"}}, }, { name: "string not allowed", - params: tools.Parameters{ - tools.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"foo"}), + params: parameters.Parameters{ + parameters.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"foo"}), }, in: map[string]any{ "my_string": "bar", @@ -752,8 +752,8 @@ func TestParametersParse(t *testing.T) { }, { name: "string not allowed regex", - params: tools.Parameters{ - tools.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"^f.*"}), + params: parameters.Parameters{ + parameters.NewStringParameterWithAllowedValues("my_string", "this param is a string", []any{"^f.*"}), }, in: map[string]any{ "my_string": "bar", @@ -761,8 +761,8 @@ func TestParametersParse(t *testing.T) { }, { name: "string excluded", - params: tools.Parameters{ - tools.NewStringParameterWithExcludedValues("my_string", "this param is a string", []any{"foo"}), + params: parameters.Parameters{ + parameters.NewStringParameterWithExcludedValues("my_string", "this param is a string", []any{"foo"}), }, in: map[string]any{ "my_string": "foo", @@ -770,8 +770,8 @@ func TestParametersParse(t *testing.T) { }, { name: "string excluded regex", - params: tools.Parameters{ - tools.NewStringParameterWithExcludedValues("my_string", "this param is a string", []any{"^f.*"}), + params: parameters.Parameters{ + parameters.NewStringParameterWithExcludedValues("my_string", "this param is a string", []any{"^f.*"}), }, in: map[string]any{ "my_string": "foo", @@ -779,68 +779,68 @@ func TestParametersParse(t *testing.T) { }, { name: "string not excluded", - params: tools.Parameters{ - tools.NewStringParameterWithExcludedValues("my_string", "this param is a string", []any{"foo"}), + params: parameters.Parameters{ + parameters.NewStringParameterWithExcludedValues("my_string", "this param is a string", []any{"foo"}), }, in: map[string]any{ "my_string": "bar", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "bar"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "bar"}}, }, { name: "string with escape backticks", - params: tools.Parameters{ - tools.NewStringParameterWithEscape("my_string", "this param is a string", "backticks"), + params: parameters.Parameters{ + parameters.NewStringParameterWithEscape("my_string", "this param is a string", "backticks"), }, in: map[string]any{ "my_string": "foo", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "`foo`"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "`foo`"}}, }, { name: "string with escape double quotes", - params: tools.Parameters{ - tools.NewStringParameterWithEscape("my_string", "this param is a string", "double-quotes"), + params: parameters.Parameters{ + parameters.NewStringParameterWithEscape("my_string", "this param is a string", "double-quotes"), }, in: map[string]any{ "my_string": "foo", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: `"foo"`}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: `"foo"`}}, }, { name: "string with escape single quotes", - params: tools.Parameters{ - tools.NewStringParameterWithEscape("my_string", "this param is a string", "single-quotes"), + params: parameters.Parameters{ + parameters.NewStringParameterWithEscape("my_string", "this param is a string", "single-quotes"), }, in: map[string]any{ "my_string": "foo", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: `'foo'`}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: `'foo'`}}, }, { name: "string with escape square brackets", - params: tools.Parameters{ - tools.NewStringParameterWithEscape("my_string", "this param is a string", "square-brackets"), + params: parameters.Parameters{ + parameters.NewStringParameterWithEscape("my_string", "this param is a string", "square-brackets"), }, in: map[string]any{ "my_string": "foo", }, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "[foo]"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "[foo]"}}, }, { name: "int", - params: tools.Parameters{ - tools.NewIntParameter("my_int", "this param is an int"), + params: parameters.Parameters{ + parameters.NewIntParameter("my_int", "this param is an int"), }, in: map[string]any{ "my_int": 100, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 100}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 100}}, }, { name: "not int", - params: tools.Parameters{ - tools.NewIntParameter("my_int", "this param is an int"), + params: parameters.Parameters{ + parameters.NewIntParameter("my_int", "this param is an int"), }, in: map[string]any{ "my_int": 14.5, @@ -848,38 +848,38 @@ func TestParametersParse(t *testing.T) { }, { name: "not int (big)", - params: tools.Parameters{ - tools.NewIntParameter("my_int", "this param is an int"), + params: parameters.Parameters{ + parameters.NewIntParameter("my_int", "this param is an int"), }, in: map[string]any{ "my_int": math.MaxInt64, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: math.MaxInt64}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: math.MaxInt64}}, }, { name: "int allowed", - params: tools.Parameters{ - tools.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{1}), + params: parameters.Parameters{ + parameters.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{1}), }, in: map[string]any{ "my_int": 1, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 1}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 1}}, }, { name: "int allowed regex", - params: tools.Parameters{ - tools.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), + params: parameters.Parameters{ + parameters.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), }, in: map[string]any{ "my_int": 10, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 10}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 10}}, }, { name: "int not allowed", - params: tools.Parameters{ - tools.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{1}), + params: parameters.Parameters{ + parameters.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{1}), }, in: map[string]any{ "my_int": 2, @@ -887,8 +887,8 @@ func TestParametersParse(t *testing.T) { }, { name: "int not allowed regex", - params: tools.Parameters{ - tools.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), + params: parameters.Parameters{ + parameters.NewIntParameterWithAllowedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), }, in: map[string]any{ "my_int": 100, @@ -896,8 +896,8 @@ func TestParametersParse(t *testing.T) { }, { name: "int excluded", - params: tools.Parameters{ - tools.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{1}), + params: parameters.Parameters{ + parameters.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{1}), }, in: map[string]any{ "my_int": 1, @@ -905,8 +905,8 @@ func TestParametersParse(t *testing.T) { }, { name: "int excluded regex", - params: tools.Parameters{ - tools.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), + params: parameters.Parameters{ + parameters.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), }, in: map[string]any{ "my_int": 10, @@ -914,38 +914,38 @@ func TestParametersParse(t *testing.T) { }, { name: "int not excluded", - params: tools.Parameters{ - tools.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{1}), + params: parameters.Parameters{ + parameters.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{1}), }, in: map[string]any{ "my_int": 2, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 2}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 2}}, }, { name: "int not excluded regex", - params: tools.Parameters{ - tools.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), + params: parameters.Parameters{ + parameters.NewIntParameterWithExcludedValues("my_int", "this param is an int", []any{"^\\d{2}$"}), }, in: map[string]any{ "my_int": 2, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 2}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 2}}, }, { name: "int minValue", - params: tools.Parameters{ - tools.NewIntParameterWithRange("my_int", "this param is an int", &intValue, nil), + params: parameters.Parameters{ + parameters.NewIntParameterWithRange("my_int", "this param is an int", &intValue, nil), }, in: map[string]any{ "my_int": 3, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 3}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 3}}, }, { name: "int minValue disallow", - params: tools.Parameters{ - tools.NewIntParameterWithRange("my_int", "this param is an int", &intValue, nil), + params: parameters.Parameters{ + parameters.NewIntParameterWithRange("my_int", "this param is an int", &intValue, nil), }, in: map[string]any{ "my_int": 1, @@ -953,18 +953,18 @@ func TestParametersParse(t *testing.T) { }, { name: "int maxValue", - params: tools.Parameters{ - tools.NewIntParameterWithRange("my_int", "this param is an int", nil, &intValue), + params: parameters.Parameters{ + parameters.NewIntParameterWithRange("my_int", "this param is an int", nil, &intValue), }, in: map[string]any{ "my_int": 1, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 1}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 1}}, }, { name: "int maxValue disallow", - params: tools.Parameters{ - tools.NewIntParameterWithRange("my_int", "this param is an int", nil, &intValue), + params: parameters.Parameters{ + parameters.NewIntParameterWithRange("my_int", "this param is an int", nil, &intValue), }, in: map[string]any{ "my_int": 3, @@ -972,18 +972,18 @@ func TestParametersParse(t *testing.T) { }, { name: "float", - params: tools.Parameters{ - tools.NewFloatParameter("my_float", "this param is a float"), + params: parameters.Parameters{ + parameters.NewFloatParameter("my_float", "this param is a float"), }, in: map[string]any{ "my_float": 1.5, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 1.5}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 1.5}}, }, { name: "not float", - params: tools.Parameters{ - tools.NewFloatParameter("my_float", "this param is a float"), + params: parameters.Parameters{ + parameters.NewFloatParameter("my_float", "this param is a float"), }, in: map[string]any{ "my_float": true, @@ -991,28 +991,28 @@ func TestParametersParse(t *testing.T) { }, { name: "float allowed", - params: tools.Parameters{ - tools.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{1.1}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{1.1}), }, in: map[string]any{ "my_float": 1.1, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 1.1}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 1.1}}, }, { name: "float allowed regex", - params: tools.Parameters{ - tools.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), }, in: map[string]any{ "my_float": 0.99, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 0.99}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 0.99}}, }, { name: "float not allowed", - params: tools.Parameters{ - tools.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{1.1}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{1.1}), }, in: map[string]any{ "my_float": 1.2, @@ -1020,8 +1020,8 @@ func TestParametersParse(t *testing.T) { }, { name: "float not allowed regex", - params: tools.Parameters{ - tools.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithAllowedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), }, in: map[string]any{ "my_float": 1.99, @@ -1029,8 +1029,8 @@ func TestParametersParse(t *testing.T) { }, { name: "float excluded", - params: tools.Parameters{ - tools.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{1.1}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{1.1}), }, in: map[string]any{ "my_float": 1.1, @@ -1038,8 +1038,8 @@ func TestParametersParse(t *testing.T) { }, { name: "float excluded regex", - params: tools.Parameters{ - tools.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), }, in: map[string]any{ "my_float": 0.99, @@ -1047,39 +1047,39 @@ func TestParametersParse(t *testing.T) { }, { name: "float not excluded", - params: tools.Parameters{ - tools.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{1.1}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{1.1}), }, in: map[string]any{ "my_float": 1.2, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 1.2}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 1.2}}, }, { name: "float not excluded regex", - params: tools.Parameters{ - tools.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), + params: parameters.Parameters{ + parameters.NewFloatParameterWithExcludedValues("my_float", "this param is a float", []any{"^0\\.\\d+$"}), }, in: map[string]any{ "my_float": 1.99, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 1.99}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 1.99}}, }, { name: "float minValue", - params: tools.Parameters{ - tools.NewFloatParameterWithRange("my_float", "this param is a float", &floatValue, nil), + params: parameters.Parameters{ + parameters.NewFloatParameterWithRange("my_float", "this param is a float", &floatValue, nil), }, in: map[string]any{ "my_float": 1.8, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 1.8}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 1.8}}, }, { name: "float minValue disallow", - params: tools.Parameters{ - tools.NewFloatParameterWithRange("my_float", "this param is a float", &floatValue, nil), + params: parameters.Parameters{ + parameters.NewFloatParameterWithRange("my_float", "this param is a float", &floatValue, nil), }, in: map[string]any{ "my_float": 1.2, @@ -1087,18 +1087,18 @@ func TestParametersParse(t *testing.T) { }, { name: "float maxValue", - params: tools.Parameters{ - tools.NewFloatParameterWithRange("my_float", "this param is a float", nil, &floatValue), + params: parameters.Parameters{ + parameters.NewFloatParameterWithRange("my_float", "this param is a float", nil, &floatValue), }, in: map[string]any{ "my_float": 1.2, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 1.2}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 1.2}}, }, { name: "float maxValue disallow", - params: tools.Parameters{ - tools.NewFloatParameterWithRange("my_float", "this param is a float", nil, &floatValue), + params: parameters.Parameters{ + parameters.NewFloatParameterWithRange("my_float", "this param is a float", nil, &floatValue), }, in: map[string]any{ "my_float": 1.8, @@ -1106,18 +1106,18 @@ func TestParametersParse(t *testing.T) { }, { name: "bool", - params: tools.Parameters{ - tools.NewBooleanParameter("my_bool", "this param is a bool"), + params: parameters.Parameters{ + parameters.NewBooleanParameter("my_bool", "this param is a bool"), }, in: map[string]any{ "my_bool": true, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_bool", Value: true}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_bool", Value: true}}, }, { name: "not bool", - params: tools.Parameters{ - tools.NewBooleanParameter("my_bool", "this param is a bool"), + params: parameters.Parameters{ + parameters.NewBooleanParameter("my_bool", "this param is a bool"), }, in: map[string]any{ "my_bool": 1.5, @@ -1125,18 +1125,18 @@ func TestParametersParse(t *testing.T) { }, { name: "bool allowed", - params: tools.Parameters{ - tools.NewBooleanParameterWithAllowedValues("my_bool", "this param is a bool", []any{false}), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithAllowedValues("my_bool", "this param is a bool", []any{false}), }, in: map[string]any{ "my_bool": false, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_bool", Value: false}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_bool", Value: false}}, }, { name: "bool not allowed", - params: tools.Parameters{ - tools.NewBooleanParameterWithAllowedValues("my_bool", "this param is a bool", []any{false}), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithAllowedValues("my_bool", "this param is a bool", []any{false}), }, in: map[string]any{ "my_bool": true, @@ -1144,8 +1144,8 @@ func TestParametersParse(t *testing.T) { }, { name: "bool excluded", - params: tools.Parameters{ - tools.NewBooleanParameterWithExcludedValues("my_bool", "this param is a bool", []any{true}), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithExcludedValues("my_bool", "this param is a bool", []any{true}), }, in: map[string]any{ "my_bool": true, @@ -1153,120 +1153,120 @@ func TestParametersParse(t *testing.T) { }, { name: "bool not excluded", - params: tools.Parameters{ - tools.NewBooleanParameterWithExcludedValues("my_bool", "this param is a bool", []any{false}), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithExcludedValues("my_bool", "this param is a bool", []any{false}), }, in: map[string]any{ "my_bool": true, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_bool", Value: true}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_bool", Value: true}}, }, { name: "string default", - params: tools.Parameters{ - tools.NewStringParameterWithDefault("my_string", "foo", "this param is a string"), + params: parameters.Parameters{ + parameters.NewStringParameterWithDefault("my_string", "foo", "this param is a string"), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "foo"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "foo"}}, }, { name: "int default", - params: tools.Parameters{ - tools.NewIntParameterWithDefault("my_int", 100, "this param is an int"), + params: parameters.Parameters{ + parameters.NewIntParameterWithDefault("my_int", 100, "this param is an int"), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 100}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 100}}, }, { name: "int (big)", - params: tools.Parameters{ - tools.NewIntParameterWithDefault("my_big_int", math.MaxInt64, "this param is an int"), + params: parameters.Parameters{ + parameters.NewIntParameterWithDefault("my_big_int", math.MaxInt64, "this param is an int"), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_big_int", Value: math.MaxInt64}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_big_int", Value: math.MaxInt64}}, }, { name: "float default", - params: tools.Parameters{ - tools.NewFloatParameterWithDefault("my_float", 1.1, "this param is a float"), + params: parameters.Parameters{ + parameters.NewFloatParameterWithDefault("my_float", 1.1, "this param is a float"), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 1.1}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 1.1}}, }, { name: "bool default", - params: tools.Parameters{ - tools.NewBooleanParameterWithDefault("my_bool", true, "this param is a bool"), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithDefault("my_bool", true, "this param is a bool"), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_bool", Value: true}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_bool", Value: true}}, }, { name: "string not required", - params: tools.Parameters{ - tools.NewStringParameterWithRequired("my_string", "this param is a string", false), + params: parameters.Parameters{ + parameters.NewStringParameterWithRequired("my_string", "this param is a string", false), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: nil}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: nil}}, }, { name: "int not required", - params: tools.Parameters{ - tools.NewIntParameterWithRequired("my_int", "this param is an int", false), + params: parameters.Parameters{ + parameters.NewIntParameterWithRequired("my_int", "this param is an int", false), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: nil}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: nil}}, }, { name: "float not required", - params: tools.Parameters{ - tools.NewFloatParameterWithRequired("my_float", "this param is a float", false), + params: parameters.Parameters{ + parameters.NewFloatParameterWithRequired("my_float", "this param is a float", false), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: nil}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: nil}}, }, { name: "bool not required", - params: tools.Parameters{ - tools.NewBooleanParameterWithRequired("my_bool", "this param is a bool", false), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithRequired("my_bool", "this param is a bool", false), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_bool", Value: nil}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_bool", Value: nil}}, }, { name: "array with string escape", - params: tools.Parameters{ - tools.NewArrayParameter("my_array", "an array", tools.NewStringParameterWithEscape("my_string", "string item", "backticks")), + params: parameters.Parameters{ + parameters.NewArrayParameter("my_array", "an array", parameters.NewStringParameterWithEscape("my_string", "string item", "backticks")), }, in: map[string]any{ "my_array": []string{"val1", "val2"}, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_array", Value: []any{string("`val1`"), string("`val2`")}}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_array", Value: []any{string("`val1`"), string("`val2`")}}}, }, { name: "map", - params: tools.Parameters{ - tools.NewMapParameter("my_map", "a map", "string"), + params: parameters.Parameters{ + parameters.NewMapParameter("my_map", "a map", "string"), }, in: map[string]any{ "my_map": map[string]any{"key1": "val1", "key2": "val2"}, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_map", Value: map[string]any{"key1": "val1", "key2": "val2"}}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_map", Value: map[string]any{"key1": "val1", "key2": "val2"}}}, }, { name: "generic map", - params: tools.Parameters{ - tools.NewMapParameter("my_map_generic_type", "a generic map", ""), + params: parameters.Parameters{ + parameters.NewMapParameter("my_map_generic_type", "a generic map", ""), }, in: map[string]any{ "my_map_generic_type": map[string]any{"key1": "val1", "key2": 123, "key3": true}, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_map_generic_type", Value: map[string]any{"key1": "val1", "key2": int64(123), "key3": true}}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_map_generic_type", Value: map[string]any{"key1": "val1", "key2": int64(123), "key3": true}}}, }, { name: "not map (value type mismatch)", - params: tools.Parameters{ - tools.NewMapParameter("my_map", "a map", "string"), + params: parameters.Parameters{ + parameters.NewMapParameter("my_map", "a map", "string"), }, in: map[string]any{ "my_map": map[string]any{"key1": 123}, @@ -1274,34 +1274,34 @@ func TestParametersParse(t *testing.T) { }, { name: "map default", - params: tools.Parameters{ - tools.NewMapParameterWithDefault("my_map_default", map[string]any{"default_key": "default_val"}, "a map", "string"), + params: parameters.Parameters{ + parameters.NewMapParameterWithDefault("my_map_default", map[string]any{"default_key": "default_val"}, "a map", "string"), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_map_default", Value: map[string]any{"default_key": "default_val"}}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_map_default", Value: map[string]any{"default_key": "default_val"}}}, }, { name: "map not required", - params: tools.Parameters{ - tools.NewMapParameterWithRequired("my_map_not_required", "a map", false, "string"), + params: parameters.Parameters{ + parameters.NewMapParameterWithRequired("my_map_not_required", "a map", false, "string"), }, in: map[string]any{}, - want: tools.ParamValues{tools.ParamValue{Name: "my_map_not_required", Value: nil}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_map_not_required", Value: nil}}, }, { name: "map allowed", - params: tools.Parameters{ - tools.NewMapParameterWithAllowedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), + params: parameters.Parameters{ + parameters.NewMapParameterWithAllowedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), }, in: map[string]any{ "my_map": map[string]any{"key1": "val1"}, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_map", Value: map[string]any{"key1": "val1"}}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_map", Value: map[string]any{"key1": "val1"}}}, }, { name: "map not allowed", - params: tools.Parameters{ - tools.NewMapParameterWithAllowedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), + params: parameters.Parameters{ + parameters.NewMapParameterWithAllowedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), }, in: map[string]any{ "my_map": map[string]any{"key1": "val2"}, @@ -1309,8 +1309,8 @@ func TestParametersParse(t *testing.T) { }, { name: "map excluded", - params: tools.Parameters{ - tools.NewMapParameterWithExcludedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), + params: parameters.Parameters{ + parameters.NewMapParameterWithExcludedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), }, in: map[string]any{ "my_map": map[string]any{"key1": "val1"}, @@ -1318,13 +1318,13 @@ func TestParametersParse(t *testing.T) { }, { name: "map not excluded", - params: tools.Parameters{ - tools.NewMapParameterWithExcludedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), + params: parameters.Parameters{ + parameters.NewMapParameterWithExcludedValues("my_map", "a map", []any{map[string]any{"key1": "val1"}}, "string"), }, in: map[string]any{ "my_map": map[string]any{"key1": "val2"}, }, - want: tools.ParamValues{tools.ParamValue{Name: "my_map", Value: map[string]any{"key1": "val2"}}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_map", Value: map[string]any{"key1": "val2"}}}, }, } for _, tc := range tcs { @@ -1345,7 +1345,7 @@ func TestParametersParse(t *testing.T) { } wantErr := len(tc.want) == 0 // error is expected if no items in want - gotAll, err := tools.ParseParams(tc.params, m, make(map[string]map[string]any)) + gotAll, err := parameters.ParseParams(tc.params, m, make(map[string]map[string]any)) if err != nil { if wantErr { return @@ -1365,7 +1365,7 @@ func TestParametersParse(t *testing.T) { } func TestAuthParametersParse(t *testing.T) { - authServices := []tools.ParamAuthService{ + authServices := []parameters.ParamAuthService{ { Name: "my-google-auth-service", Field: "auth_field", @@ -1376,26 +1376,26 @@ func TestAuthParametersParse(t *testing.T) { }} tcs := []struct { name string - params tools.Parameters + params parameters.Parameters in map[string]any claimsMap map[string]map[string]any - want tools.ParamValues + want parameters.ParamValues }{ { name: "string", - params: tools.Parameters{ - tools.NewStringParameterWithAuth("my_string", "this param is a string", authServices), + params: parameters.Parameters{ + parameters.NewStringParameterWithAuth("my_string", "this param is a string", authServices), }, in: map[string]any{ "my_string": "hello world", }, claimsMap: map[string]map[string]any{"my-google-auth-service": {"auth_field": "hello"}}, - want: tools.ParamValues{tools.ParamValue{Name: "my_string", Value: "hello"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_string", Value: "hello"}}, }, { name: "not string", - params: tools.Parameters{ - tools.NewStringParameterWithAuth("my_string", "this param is a string", authServices), + params: parameters.Parameters{ + parameters.NewStringParameterWithAuth("my_string", "this param is a string", authServices), }, in: map[string]any{ "my_string": 4, @@ -1404,19 +1404,19 @@ func TestAuthParametersParse(t *testing.T) { }, { name: "int", - params: tools.Parameters{ - tools.NewIntParameterWithAuth("my_int", "this param is an int", authServices), + params: parameters.Parameters{ + parameters.NewIntParameterWithAuth("my_int", "this param is an int", authServices), }, in: map[string]any{ "my_int": 100, }, claimsMap: map[string]map[string]any{"other-auth-service": {"other_auth_field": 120}}, - want: tools.ParamValues{tools.ParamValue{Name: "my_int", Value: 120}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_int", Value: 120}}, }, { name: "not int", - params: tools.Parameters{ - tools.NewIntParameterWithAuth("my_int", "this param is an int", authServices), + params: parameters.Parameters{ + parameters.NewIntParameterWithAuth("my_int", "this param is an int", authServices), }, in: map[string]any{ "my_int": 14.5, @@ -1425,19 +1425,19 @@ func TestAuthParametersParse(t *testing.T) { }, { name: "float", - params: tools.Parameters{ - tools.NewFloatParameterWithAuth("my_float", "this param is a float", authServices), + params: parameters.Parameters{ + parameters.NewFloatParameterWithAuth("my_float", "this param is a float", authServices), }, in: map[string]any{ "my_float": 1.5, }, claimsMap: map[string]map[string]any{"my-google-auth-service": {"auth_field": 2.1}}, - want: tools.ParamValues{tools.ParamValue{Name: "my_float", Value: 2.1}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_float", Value: 2.1}}, }, { name: "not float", - params: tools.Parameters{ - tools.NewFloatParameterWithAuth("my_float", "this param is a float", authServices), + params: parameters.Parameters{ + parameters.NewFloatParameterWithAuth("my_float", "this param is a float", authServices), }, in: map[string]any{ "my_float": true, @@ -1446,19 +1446,19 @@ func TestAuthParametersParse(t *testing.T) { }, { name: "bool", - params: tools.Parameters{ - tools.NewBooleanParameterWithAuth("my_bool", "this param is a bool", authServices), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithAuth("my_bool", "this param is a bool", authServices), }, in: map[string]any{ "my_bool": true, }, claimsMap: map[string]map[string]any{"my-google-auth-service": {"auth_field": false}}, - want: tools.ParamValues{tools.ParamValue{Name: "my_bool", Value: false}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_bool", Value: false}}, }, { name: "not bool", - params: tools.Parameters{ - tools.NewBooleanParameterWithAuth("my_bool", "this param is a bool", authServices), + params: parameters.Parameters{ + parameters.NewBooleanParameterWithAuth("my_bool", "this param is a bool", authServices), }, in: map[string]any{ "my_bool": 1.5, @@ -1467,19 +1467,19 @@ func TestAuthParametersParse(t *testing.T) { }, { name: "username", - params: tools.Parameters{ - tools.NewStringParameterWithAuth("username", "username string", authServices), + params: parameters.Parameters{ + parameters.NewStringParameterWithAuth("username", "username string", authServices), }, in: map[string]any{ "username": "Violet", }, claimsMap: map[string]map[string]any{"my-google-auth-service": {"auth_field": "Alice"}}, - want: tools.ParamValues{tools.ParamValue{Name: "username", Value: "Alice"}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "username", Value: "Alice"}}, }, { name: "expect claim error", - params: tools.Parameters{ - tools.NewStringParameterWithAuth("username", "username string", authServices), + params: parameters.Parameters{ + parameters.NewStringParameterWithAuth("username", "username string", authServices), }, in: map[string]any{ "username": "Violet", @@ -1488,12 +1488,12 @@ func TestAuthParametersParse(t *testing.T) { }, { name: "map", - params: tools.Parameters{ - tools.NewMapParameterWithAuth("my_map", "a map", "string", authServices), + params: parameters.Parameters{ + parameters.NewMapParameterWithAuth("my_map", "a map", "string", authServices), }, in: map[string]any{"my_map": map[string]any{"key1": "val1"}}, claimsMap: map[string]map[string]any{"my-google-auth-service": {"auth_field": map[string]any{"authed_key": "authed_val"}}}, - want: tools.ParamValues{tools.ParamValue{Name: "my_map", Value: map[string]any{"authed_key": "authed_val"}}}, + want: parameters.ParamValues{parameters.ParamValue{Name: "my_map", Value: map[string]any{"authed_key": "authed_val"}}}, }, } for _, tc := range tcs { @@ -1512,7 +1512,7 @@ func TestAuthParametersParse(t *testing.T) { t.Fatalf("unable to unmarshal: %s", err) } - gotAll, err := tools.ParseParams(tc.params, m, tc.claimsMap) + gotAll, err := parameters.ParseParams(tc.params, m, tc.claimsMap) if err != nil { if len(tc.want) == 0 { // error is expected if no items in want @@ -1531,7 +1531,7 @@ func TestAuthParametersParse(t *testing.T) { func TestParamValues(t *testing.T) { tcs := []struct { name string - in tools.ParamValues + in parameters.ParamValues wantSlice []any wantMap map[string]interface{} wantMapOrdered map[string]interface{} @@ -1539,7 +1539,7 @@ func TestParamValues(t *testing.T) { }{ { name: "string", - in: tools.ParamValues{tools.ParamValue{Name: "my_bool", Value: true}, tools.ParamValue{Name: "my_string", Value: "hello world"}}, + in: parameters.ParamValues{parameters.ParamValue{Name: "my_bool", Value: true}, parameters.ParamValue{Name: "my_string", Value: "hello world"}}, wantSlice: []any{true, "hello world"}, wantMap: map[string]interface{}{"my_bool": true, "my_string": "hello world"}, wantMapOrdered: map[string]interface{}{"p1": true, "p2": "hello world"}, @@ -1587,109 +1587,109 @@ func TestParamValues(t *testing.T) { func TestParamManifest(t *testing.T) { tcs := []struct { name string - in tools.Parameter - want tools.ParameterManifest + in parameters.Parameter + want parameters.ParameterManifest }{ { name: "string", - in: tools.NewStringParameter("foo-string", "bar"), - want: tools.ParameterManifest{Name: "foo-string", Type: "string", Required: true, Description: "bar", AuthServices: []string{}}, + in: parameters.NewStringParameter("foo-string", "bar"), + want: parameters.ParameterManifest{Name: "foo-string", Type: "string", Required: true, Description: "bar", AuthServices: []string{}}, }, { name: "int", - in: tools.NewIntParameter("foo-int", "bar"), - want: tools.ParameterManifest{Name: "foo-int", Type: "integer", Required: true, Description: "bar", AuthServices: []string{}}, + in: parameters.NewIntParameter("foo-int", "bar"), + want: parameters.ParameterManifest{Name: "foo-int", Type: "integer", Required: true, Description: "bar", AuthServices: []string{}}, }, { name: "float", - in: tools.NewFloatParameter("foo-float", "bar"), - want: tools.ParameterManifest{Name: "foo-float", Type: "float", Required: true, Description: "bar", AuthServices: []string{}}, + in: parameters.NewFloatParameter("foo-float", "bar"), + want: parameters.ParameterManifest{Name: "foo-float", Type: "float", Required: true, Description: "bar", AuthServices: []string{}}, }, { name: "boolean", - in: tools.NewBooleanParameter("foo-bool", "bar"), - want: tools.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: true, Description: "bar", AuthServices: []string{}}, + in: parameters.NewBooleanParameter("foo-bool", "bar"), + want: parameters.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: true, Description: "bar", AuthServices: []string{}}, }, { name: "array", - in: tools.NewArrayParameter("foo-array", "bar", tools.NewStringParameter("foo-string", "bar")), - want: tools.ParameterManifest{ + in: parameters.NewArrayParameter("foo-array", "bar", parameters.NewStringParameter("foo-string", "bar")), + want: parameters.ParameterManifest{ Name: "foo-array", Type: "array", Required: true, Description: "bar", AuthServices: []string{}, - Items: &tools.ParameterManifest{Name: "foo-string", Type: "string", Required: true, Description: "bar", AuthServices: []string{}}, + Items: ¶meters.ParameterManifest{Name: "foo-string", Type: "string", Required: true, Description: "bar", AuthServices: []string{}}, }, }, { name: "string default", - in: tools.NewStringParameterWithDefault("foo-string", "foo", "bar"), - want: tools.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewStringParameterWithDefault("foo-string", "foo", "bar"), + want: parameters.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "int default", - in: tools.NewIntParameterWithDefault("foo-int", 1, "bar"), - want: tools.ParameterManifest{Name: "foo-int", Type: "integer", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewIntParameterWithDefault("foo-int", 1, "bar"), + want: parameters.ParameterManifest{Name: "foo-int", Type: "integer", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "float default", - in: tools.NewFloatParameterWithDefault("foo-float", 1.1, "bar"), - want: tools.ParameterManifest{Name: "foo-float", Type: "float", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewFloatParameterWithDefault("foo-float", 1.1, "bar"), + want: parameters.ParameterManifest{Name: "foo-float", Type: "float", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "boolean default", - in: tools.NewBooleanParameterWithDefault("foo-bool", true, "bar"), - want: tools.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewBooleanParameterWithDefault("foo-bool", true, "bar"), + want: parameters.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "array default", - in: tools.NewArrayParameterWithDefault("foo-array", []any{"foo", "bar"}, "bar", tools.NewStringParameter("foo-string", "bar")), - want: tools.ParameterManifest{ + in: parameters.NewArrayParameterWithDefault("foo-array", []any{"foo", "bar"}, "bar", parameters.NewStringParameter("foo-string", "bar")), + want: parameters.ParameterManifest{ Name: "foo-array", Type: "array", Required: false, Description: "bar", AuthServices: []string{}, - Items: &tools.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, + Items: ¶meters.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, }, }, { name: "string not required", - in: tools.NewStringParameterWithRequired("foo-string", "bar", false), - want: tools.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewStringParameterWithRequired("foo-string", "bar", false), + want: parameters.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "int not required", - in: tools.NewIntParameterWithRequired("foo-int", "bar", false), - want: tools.ParameterManifest{Name: "foo-int", Type: "integer", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewIntParameterWithRequired("foo-int", "bar", false), + want: parameters.ParameterManifest{Name: "foo-int", Type: "integer", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "float not required", - in: tools.NewFloatParameterWithRequired("foo-float", "bar", false), - want: tools.ParameterManifest{Name: "foo-float", Type: "float", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewFloatParameterWithRequired("foo-float", "bar", false), + want: parameters.ParameterManifest{Name: "foo-float", Type: "float", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "boolean not required", - in: tools.NewBooleanParameterWithRequired("foo-bool", "bar", false), - want: tools.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: false, Description: "bar", AuthServices: []string{}}, + in: parameters.NewBooleanParameterWithRequired("foo-bool", "bar", false), + want: parameters.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: false, Description: "bar", AuthServices: []string{}}, }, { name: "array not required", - in: tools.NewArrayParameterWithRequired("foo-array", "bar", false, tools.NewStringParameter("foo-string", "bar")), - want: tools.ParameterManifest{ + in: parameters.NewArrayParameterWithRequired("foo-array", "bar", false, parameters.NewStringParameter("foo-string", "bar")), + want: parameters.ParameterManifest{ Name: "foo-array", Type: "array", Required: false, Description: "bar", AuthServices: []string{}, - Items: &tools.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, + Items: ¶meters.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}}, }, }, { name: "map with string values", - in: tools.NewMapParameter("foo-map", "bar", "string"), - want: tools.ParameterManifest{ + in: parameters.NewMapParameter("foo-map", "bar", "string"), + want: parameters.ParameterManifest{ Name: "foo-map", Type: "object", Required: true, @@ -1700,8 +1700,8 @@ func TestParamManifest(t *testing.T) { }, { name: "map not required", - in: tools.NewMapParameterWithRequired("foo-map", "bar", false, "string"), - want: tools.ParameterManifest{ + in: parameters.NewMapParameterWithRequired("foo-map", "bar", false, "string"), + want: parameters.ParameterManifest{ Name: "foo-map", Type: "object", Required: false, @@ -1712,8 +1712,8 @@ func TestParamManifest(t *testing.T) { }, { name: "generic map (additionalProperties true)", - in: tools.NewMapParameter("foo-map", "bar", ""), - want: tools.ParameterManifest{ + in: parameters.NewMapParameter("foo-map", "bar", ""), + want: parameters.ParameterManifest{ Name: "foo-map", Type: "object", Required: true, @@ -1736,49 +1736,49 @@ func TestParamManifest(t *testing.T) { func TestParamMcpManifest(t *testing.T) { tcs := []struct { name string - in tools.Parameter - want tools.ParameterMcpManifest + in parameters.Parameter + want parameters.ParameterMcpManifest wantAuthParam []string }{ { name: "string", - in: tools.NewStringParameter("foo-string", "bar"), - want: tools.ParameterMcpManifest{Type: "string", Description: "bar"}, + in: parameters.NewStringParameter("foo-string", "bar"), + want: parameters.ParameterMcpManifest{Type: "string", Description: "bar"}, wantAuthParam: []string{}, }, { name: "int", - in: tools.NewIntParameter("foo-int", "bar"), - want: tools.ParameterMcpManifest{Type: "integer", Description: "bar"}, + in: parameters.NewIntParameter("foo-int", "bar"), + want: parameters.ParameterMcpManifest{Type: "integer", Description: "bar"}, wantAuthParam: []string{}, }, { name: "float", - in: tools.NewFloatParameter("foo-float", "bar"), - want: tools.ParameterMcpManifest{Type: "number", Description: "bar"}, + in: parameters.NewFloatParameter("foo-float", "bar"), + want: parameters.ParameterMcpManifest{Type: "number", Description: "bar"}, wantAuthParam: []string{}, }, { name: "boolean", - in: tools.NewBooleanParameter("foo-bool", "bar"), - want: tools.ParameterMcpManifest{Type: "boolean", Description: "bar"}, + in: parameters.NewBooleanParameter("foo-bool", "bar"), + want: parameters.ParameterMcpManifest{Type: "boolean", Description: "bar"}, wantAuthParam: []string{}, }, { name: "array", - in: tools.NewArrayParameter("foo-array", "bar", tools.NewStringParameter("foo-string", "bar")), - want: tools.ParameterMcpManifest{ + in: parameters.NewArrayParameter("foo-array", "bar", parameters.NewStringParameter("foo-string", "bar")), + want: parameters.ParameterMcpManifest{ Type: "array", Description: "bar", - Items: &tools.ParameterMcpManifest{Type: "string", Description: "bar"}, + Items: ¶meters.ParameterMcpManifest{Type: "string", Description: "bar"}, }, wantAuthParam: []string{}, }, { name: "map with string values", - in: tools.NewMapParameter("foo-map", "bar", "string"), - want: tools.ParameterMcpManifest{ + in: parameters.NewMapParameter("foo-map", "bar", "string"), + want: parameters.ParameterMcpManifest{ Type: "object", Description: "bar", AdditionalProperties: map[string]any{"type": "string"}, @@ -1787,8 +1787,8 @@ func TestParamMcpManifest(t *testing.T) { }, { name: "generic map (additionalProperties true)", - in: tools.NewMapParameter("foo-map", "bar", ""), - want: tools.ParameterMcpManifest{ + in: parameters.NewMapParameter("foo-map", "bar", ""), + want: parameters.ParameterMcpManifest{ Type: "object", Description: "bar", AdditionalProperties: true, @@ -1811,7 +1811,7 @@ func TestParamMcpManifest(t *testing.T) { } func TestMcpManifest(t *testing.T) { - authServices := []tools.ParamAuthService{ + authServices := []parameters.ParamAuthService{ { Name: "my-google-auth-service", Field: "auth_field", @@ -1822,25 +1822,25 @@ func TestMcpManifest(t *testing.T) { }} tcs := []struct { name string - in tools.Parameters - wantSchema tools.McpToolsSchema + in parameters.Parameters + wantSchema parameters.McpToolsSchema wantAuthParam map[string][]string }{ { name: "all types", - in: tools.Parameters{ - tools.NewStringParameterWithDefault("foo-string", "foo", "bar"), - tools.NewStringParameter("foo-string2", "bar"), - tools.NewStringParameterWithAuth("foo-string3-auth", "bar", authServices), - tools.NewIntParameter("foo-int2", "bar"), - tools.NewFloatParameter("foo-float", "bar"), - tools.NewArrayParameter("foo-array2", "bar", tools.NewStringParameter("foo-string", "bar")), - tools.NewMapParameter("foo-map-int", "a map of ints", "integer"), - tools.NewMapParameter("foo-map-any", "a map of any", ""), + in: parameters.Parameters{ + parameters.NewStringParameterWithDefault("foo-string", "foo", "bar"), + parameters.NewStringParameter("foo-string2", "bar"), + parameters.NewStringParameterWithAuth("foo-string3-auth", "bar", authServices), + parameters.NewIntParameter("foo-int2", "bar"), + parameters.NewFloatParameter("foo-float", "bar"), + parameters.NewArrayParameter("foo-array2", "bar", parameters.NewStringParameter("foo-string", "bar")), + parameters.NewMapParameter("foo-map-int", "a map of ints", "integer"), + parameters.NewMapParameter("foo-map-any", "a map of any", ""), }, - wantSchema: tools.McpToolsSchema{ + wantSchema: parameters.McpToolsSchema{ Type: "object", - Properties: map[string]tools.ParameterMcpManifest{ + Properties: map[string]parameters.ParameterMcpManifest{ "foo-string": {Type: "string", Description: "bar"}, "foo-string2": {Type: "string", Description: "bar"}, "foo-string3-auth": {Type: "string", Description: "bar"}, @@ -1849,7 +1849,7 @@ func TestMcpManifest(t *testing.T) { "foo-array2": { Type: "array", Description: "bar", - Items: &tools.ParameterMcpManifest{Type: "string", Description: "bar"}, + Items: ¶meters.ParameterMcpManifest{Type: "string", Description: "bar"}, }, "foo-map-int": { Type: "object", @@ -1974,7 +1974,7 @@ func TestFailParametersUnmarshal(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - var got tools.Parameters + var got parameters.Parameters // parse map to bytes data, err := yaml.Marshal(tc.in) if err != nil { @@ -2036,7 +2036,7 @@ func TestConvertArrayParamToString(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got, _ := tools.ConvertArrayParamToString(tc.in) + got, _ := parameters.ConvertArrayParamToString(tc.in) if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect array param conversion: diff %v", diff) } @@ -2069,7 +2069,7 @@ func TestFailConvertArrayParamToString(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - _, err := tools.ConvertArrayParamToString(tc.in) + _, err := parameters.ConvertArrayParamToString(tc.in) errStr := err.Error() if errStr != tc.err { t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err) @@ -2082,56 +2082,56 @@ func TestGetParams(t *testing.T) { tcs := []struct { name string in map[string]any - params tools.Parameters - want tools.ParamValues + params parameters.Parameters + want parameters.ParamValues }{ { name: "parameters to include and exclude", - params: tools.Parameters{ - tools.NewStringParameter("my_string_inc", "this should be included"), - tools.NewStringParameter("my_string_inc2", "this should be included"), + params: parameters.Parameters{ + parameters.NewStringParameter("my_string_inc", "this should be included"), + parameters.NewStringParameter("my_string_inc2", "this should be included"), }, in: map[string]any{ "my_string_inc": "hello world A", "my_string_inc2": "hello world B", "my_string_exc": "hello world C", }, - want: tools.ParamValues{ - tools.ParamValue{Name: "my_string_inc", Value: "hello world A"}, - tools.ParamValue{Name: "my_string_inc2", Value: "hello world B"}, + want: parameters.ParamValues{ + parameters.ParamValue{Name: "my_string_inc", Value: "hello world A"}, + parameters.ParamValue{Name: "my_string_inc2", Value: "hello world B"}, }, }, { name: "include all", - params: tools.Parameters{ - tools.NewStringParameter("my_string_inc", "this should be included"), + params: parameters.Parameters{ + parameters.NewStringParameter("my_string_inc", "this should be included"), }, in: map[string]any{ "my_string_inc": "hello world A", }, - want: tools.ParamValues{ - tools.ParamValue{Name: "my_string_inc", Value: "hello world A"}, + want: parameters.ParamValues{ + parameters.ParamValue{Name: "my_string_inc", Value: "hello world A"}, }, }, { name: "exclude all", - params: tools.Parameters{}, + params: parameters.Parameters{}, in: map[string]any{ "my_string_exc": "hello world A", "my_string_exc2": "hello world B", }, - want: tools.ParamValues{}, + want: parameters.ParamValues{}, }, { name: "empty", - params: tools.Parameters{}, + params: parameters.Parameters{}, in: map[string]any{}, - want: tools.ParamValues{}, + want: parameters.ParamValues{}, }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got, _ := tools.GetParams(tc.params, tc.in) + got, _ := parameters.GetParams(tc.params, tc.in) if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect get params: diff %v", diff) } @@ -2143,21 +2143,21 @@ func TestFailGetParams(t *testing.T) { tcs := []struct { name string - params tools.Parameters + params parameters.Parameters in map[string]any err string }{ { name: "missing the only parameter", - params: tools.Parameters{tools.NewStringParameter("my_string", "this was missing")}, + params: parameters.Parameters{parameters.NewStringParameter("my_string", "this was missing")}, in: map[string]any{}, err: "missing parameter my_string", }, { name: "missing one parameter of multiple", - params: tools.Parameters{ - tools.NewStringParameter("my_string_inc", "this should be included"), - tools.NewStringParameter("my_string_exc", "this was missing"), + params: parameters.Parameters{ + parameters.NewStringParameter("my_string_inc", "this should be included"), + parameters.NewStringParameter("my_string_exc", "this was missing"), }, in: map[string]any{ "my_string_inc": "hello world A", @@ -2167,7 +2167,7 @@ func TestFailGetParams(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - _, err := tools.GetParams(tc.params, tc.in) + _, err := parameters.GetParams(tc.params, tc.in) errStr := err.Error() if errStr != tc.err { t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err) @@ -2179,15 +2179,15 @@ func TestFailGetParams(t *testing.T) { func TestResolveTemplateParameters(t *testing.T) { tcs := []struct { name string - templateParams tools.Parameters + templateParams parameters.Parameters statement string in map[string]any want string }{ { name: "single template parameter", - templateParams: tools.Parameters{ - tools.NewStringParameter("tableName", "this is a string template parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("tableName", "this is a string template parameter"), }, statement: "SELECT * FROM {{.tableName}}", in: map[string]any{ @@ -2197,9 +2197,9 @@ func TestResolveTemplateParameters(t *testing.T) { }, { name: "multiple template parameters", - templateParams: tools.Parameters{ - tools.NewStringParameter("tableName", "this is a string template parameter"), - tools.NewStringParameter("columnName", "this is a string template parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("tableName", "this is a string template parameter"), + parameters.NewStringParameter("columnName", "this is a string template parameter"), }, statement: "SELECT * FROM {{.tableName}} WHERE {{.columnName}} = 'Hilton'", in: map[string]any{ @@ -2210,9 +2210,9 @@ func TestResolveTemplateParameters(t *testing.T) { }, { name: "standard and template parameter", - templateParams: tools.Parameters{ - tools.NewStringParameter("tableName", "this is a string template parameter"), - tools.NewStringParameter("hotelName", "this is a string parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("tableName", "this is a string template parameter"), + parameters.NewStringParameter("hotelName", "this is a string parameter"), }, statement: "SELECT * FROM {{.tableName}} WHERE name = $1", in: map[string]any{ @@ -2223,8 +2223,8 @@ func TestResolveTemplateParameters(t *testing.T) { }, { name: "standard parameter", - templateParams: tools.Parameters{ - tools.NewStringParameter("hotelName", "this is a string parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("hotelName", "this is a string parameter"), }, statement: "SELECT * FROM hotels WHERE name = $1", in: map[string]any{ @@ -2235,7 +2235,7 @@ func TestResolveTemplateParameters(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got, _ := tools.ResolveTemplateParams(tc.templateParams, tc.statement, tc.in) + got, _ := parameters.ResolveTemplateParams(tc.templateParams, tc.statement, tc.in) if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect resolved template params: diff %v", diff) } @@ -2246,15 +2246,15 @@ func TestResolveTemplateParameters(t *testing.T) { func TestFailResolveTemplateParameters(t *testing.T) { tcs := []struct { name string - templateParams tools.Parameters + templateParams parameters.Parameters statement string in map[string]any err string }{ { name: "wrong param name", - templateParams: tools.Parameters{ - tools.NewStringParameter("tableName", "this is a string template parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("tableName", "this is a string template parameter"), }, statement: "SELECT * FROM {{.missingParam}}", in: map[string]any{}, @@ -2262,8 +2262,8 @@ func TestFailResolveTemplateParameters(t *testing.T) { }, { name: "incomplete param template", - templateParams: tools.Parameters{ - tools.NewStringParameter("tableName", "this is a string template parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("tableName", "this is a string template parameter"), }, statement: "SELECT * FROM {{.tableName", in: map[string]any{ @@ -2273,8 +2273,8 @@ func TestFailResolveTemplateParameters(t *testing.T) { }, { name: "undefined function", - templateParams: tools.Parameters{ - tools.NewStringParameter("tableName", "this is a string template parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("tableName", "this is a string template parameter"), }, statement: "SELECT * FROM {{json .tableName}}", in: map[string]any{ @@ -2284,8 +2284,8 @@ func TestFailResolveTemplateParameters(t *testing.T) { }, { name: "undefined method", - templateParams: tools.Parameters{ - tools.NewStringParameter("tableName", "this is a string template parameter"), + templateParams: parameters.Parameters{ + parameters.NewStringParameter("tableName", "this is a string template parameter"), }, statement: "SELECT * FROM {{.tableName .wrong}}", in: map[string]any{ @@ -2296,7 +2296,7 @@ func TestFailResolveTemplateParameters(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - _, err := tools.ResolveTemplateParams(tc.templateParams, tc.statement, tc.in) + _, err := parameters.ResolveTemplateParams(tc.templateParams, tc.statement, tc.in) errStr := err.Error() if errStr != tc.err { t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err) @@ -2339,7 +2339,7 @@ func TestCheckParamRequired(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - got := tools.CheckParamRequired(tc.required, tc.defaultV) + got := parameters.CheckParamRequired(tc.required, tc.defaultV) if got != tc.want { t.Fatalf("got %v, want %v", got, tc.want) } diff --git a/internal/util/util.go b/internal/util/util.go index 79c634c933..9b0f269ce7 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -17,6 +17,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "strings" @@ -162,3 +163,5 @@ func InstrumentationFromContext(ctx context.Context) (*telemetry.Instrumentation } return nil, fmt.Errorf("unable to retrieve instrumentation") } + +var ErrUnauthorized = errors.New("unauthorized") diff --git a/tests/bigtable/bigtable_integration_test.go b/tests/bigtable/bigtable_integration_test.go index c0106f959c..12246cf398 100644 --- a/tests/bigtable/bigtable_integration_test.go +++ b/tests/bigtable/bigtable_integration_test.go @@ -30,7 +30,7 @@ import ( "cloud.google.com/go/bigtable" "github.com/google/uuid" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/googleapis/genai-toolbox/tests" ) @@ -295,8 +295,8 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT TO_INT64(cf['age']) as age, TO_INT64(cf['id']) as id, CAST(cf['name'] AS string) as name, FROM {{.tableName}};", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ @@ -304,9 +304,9 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT TO_INT64(cf['age']) as age, TO_INT64(cf['id']) as id, CAST(cf['name'] AS string) as name, FROM {{.tableName}} WHERE TO_INT64(cf['id']) = @id;", - "parameters": []tools.Parameter{tools.NewIntParameter("id", "the id of the user")}, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "parameters": []parameters.Parameter{parameters.NewIntParameter("id", "the id of the user")}, + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ @@ -314,9 +314,9 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT {{array .fields}}, FROM {{.tableName}};", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("fields", "The fields to select from", tools.NewStringParameter("field", "A field that will be returned from the query.")), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("fields", "The fields to select from", parameters.NewStringParameter("field", "A field that will be returned from the query.")), }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ @@ -324,10 +324,10 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT TO_INT64(cf['age']) as age, TO_INT64(cf['id']) as id, CAST(cf['name'] AS string) as name, FROM {{.tableName}} WHERE {{.columnFilter}} = @name;", - "parameters": []tools.Parameter{tools.NewStringParameter("name", "the name of the user")}, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewStringParameter("columnFilter", "some description"), + "parameters": []parameters.Parameter{parameters.NewStringParameter("name", "the name of the user")}, + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewStringParameter("columnFilter", "some description"), }, } config["tools"] = toolsMap diff --git a/tests/clickhouse/clickhouse_integration_test.go b/tests/clickhouse/clickhouse_integration_test.go index b39c812cfd..0e81402c6a 100644 --- a/tests/clickhouse/clickhouse_integration_test.go +++ b/tests/clickhouse/clickhouse_integration_test.go @@ -29,11 +29,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/clickhouse" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" clickhouseexecutesql "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouseexecutesql" clickhouselistdatabases "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouselistdatabases" clickhouselisttables "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouselisttables" clickhousesql "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhousesql" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/googleapis/genai-toolbox/tests" "go.opentelemetry.io/otel/trace/noop" ) @@ -194,9 +194,9 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK "source": "my-instance", "description": "Create table tool with template parameters", "statement": "CREATE TABLE {{.tableName}} ({{array .columns}}) ORDER BY id", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("columns", "The columns to create", tools.NewStringParameter("column", "A column name that will be created")), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("columns", "The columns to create", parameters.NewStringParameter("column", "A column name that will be created")), }, } toolsMap["insert-table-templateParams-tool"] = map[string]any{ @@ -204,10 +204,10 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK "source": "my-instance", "description": "Insert table tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("columns", "The columns to insert into", tools.NewStringParameter("column", "A column name that will be returned from the query.")), - tools.NewStringParameter("values", "The values to insert as a comma separated string"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("columns", "The columns to insert into", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), + parameters.NewStringParameter("values", "The values to insert as a comma separated string"), }, } toolsMap["select-templateParams-tool"] = map[string]any{ @@ -215,8 +215,8 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK "source": "my-instance", "description": "Select table tool with template parameters", "statement": "SELECT id AS \"id\", name AS \"name\", age AS \"age\" FROM {{.tableName}} ORDER BY id", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ @@ -224,11 +224,11 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK "source": "my-instance", "description": "Select table tool with combined template parameters", "statement": tmplSelectCombined, - "parameters": []tools.Parameter{ - tools.NewIntParameter("id", "the id of the user"), + "parameters": []parameters.Parameter{ + parameters.NewIntParameter("id", "the id of the user"), }, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ @@ -236,8 +236,8 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK "source": "my-instance", "description": "Select specific fields tool with template parameters", "statement": "SELECT name AS \"name\" FROM {{.tableName}} ORDER BY id", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ @@ -245,12 +245,12 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK "source": "my-instance", "description": "Select table tool with filter template parameters", "statement": tmplSelectFilterCombined, - "parameters": []tools.Parameter{ - tools.NewStringParameter("name", "the name to filter by"), + "parameters": []parameters.Parameter{ + parameters.NewStringParameter("name", "the name to filter by"), }, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewStringParameter("columnFilter", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewStringParameter("columnFilter", "some description"), }, } // Firebird uses simple DROP TABLE syntax without IF EXISTS @@ -259,8 +259,8 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK "source": "my-instance", "description": "Drop table tool with template parameters", "statement": "DROP TABLE {{.tableName}}", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } config["tools"] = toolsMap @@ -403,7 +403,7 @@ func TestClickHouseSQLTool(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - result, err := tool.Invoke(ctx, tools.ParamValues{}, "") + result, err := tool.Invoke(ctx, parameters.ParamValues{}, "") if err != nil { t.Fatalf("Failed to invoke tool: %v", err) } @@ -425,8 +425,8 @@ func TestClickHouseSQLTool(t *testing.T) { Source: "test-clickhouse", Description: "Test parameterized query", Statement: fmt.Sprintf("SELECT * FROM %s WHERE age > ? ORDER BY id", tableName), - Parameters: tools.Parameters{ - tools.NewIntParameter("min_age", "Minimum age"), + Parameters: parameters.Parameters{ + parameters.NewIntParameter("min_age", "Minimum age"), }, } @@ -440,7 +440,7 @@ func TestClickHouseSQLTool(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "min_age", Value: 28}, } @@ -466,8 +466,8 @@ func TestClickHouseSQLTool(t *testing.T) { Source: "test-clickhouse", Description: "Test query with no results", Statement: fmt.Sprintf("SELECT * FROM %s WHERE id = ?", tableName), - Parameters: tools.Parameters{ - tools.NewIntParameter("id", "Record ID"), + Parameters: parameters.Parameters{ + parameters.NewIntParameter("id", "Record ID"), }, } @@ -481,7 +481,7 @@ func TestClickHouseSQLTool(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "id", Value: 999}, // Non-existent ID } @@ -519,7 +519,7 @@ func TestClickHouseSQLTool(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - _, err = tool.Invoke(ctx, tools.ParamValues{}, "") + _, err = tool.Invoke(ctx, parameters.ParamValues{}, "") if err == nil { t.Error("Expected error for invalid SQL, got nil") } @@ -570,7 +570,7 @@ func TestClickHouseExecuteSQLTool(t *testing.T) { ) ENGINE = Memory `, tableName) - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "sql", Value: createSQL}, } @@ -608,7 +608,7 @@ func TestClickHouseExecuteSQLTool(t *testing.T) { } insertSQL := fmt.Sprintf("INSERT INTO %s (id, data) VALUES (1, 'test1'), (2, 'test2')", tableName) - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "sql", Value: insertSQL}, } @@ -646,7 +646,7 @@ func TestClickHouseExecuteSQLTool(t *testing.T) { } selectSQL := fmt.Sprintf("SELECT * FROM %s ORDER BY id", tableName) - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "sql", Value: selectSQL}, } @@ -684,7 +684,7 @@ func TestClickHouseExecuteSQLTool(t *testing.T) { } dropSQL := fmt.Sprintf("DROP TABLE IF EXISTS %s", tableName) - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "sql", Value: dropSQL}, } @@ -722,7 +722,7 @@ func TestClickHouseExecuteSQLTool(t *testing.T) { } // Pass empty SQL parameter - this should cause an error - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "sql", Value: ""}, } @@ -754,7 +754,7 @@ func TestClickHouseExecuteSQLTool(t *testing.T) { // Try to execute multiple statements (should fail or execute safely) injectionSQL := "SELECT 1; DROP TABLE system.users; SELECT 2" - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "sql", Value: injectionSQL}, } @@ -803,7 +803,7 @@ func TestClickHouseEdgeCases(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "sql", Value: longQuery}, } @@ -862,7 +862,7 @@ func TestClickHouseEdgeCases(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - result, err := tool.Invoke(ctx, tools.ParamValues{}, "") + result, err := tool.Invoke(ctx, parameters.ParamValues{}, "") if err != nil { t.Fatalf("Failed to select null values: %v", err) } @@ -891,8 +891,8 @@ func TestClickHouseEdgeCases(t *testing.T) { Source: "test-clickhouse", Description: "Test concurrent queries", Statement: "SELECT number FROM system.numbers LIMIT ?", - Parameters: tools.Parameters{ - tools.NewIntParameter("limit", "Limit"), + Parameters: parameters.Parameters{ + parameters.NewIntParameter("limit", "Limit"), }, } @@ -912,7 +912,7 @@ func TestClickHouseEdgeCases(t *testing.T) { go func(n int) { defer func() { done <- true }() - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "limit", Value: n + 1}, } @@ -1054,7 +1054,7 @@ func TestClickHouseListDatabasesTool(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - params := tools.ParamValues{} + params := parameters.ParamValues{} result, err := tool.Invoke(ctx, params, "") if err != nil { @@ -1166,7 +1166,7 @@ func TestClickHouseListTablesTool(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "database", Value: testDBName}, } @@ -1232,7 +1232,7 @@ func TestClickHouseListTablesTool(t *testing.T) { t.Fatalf("Failed to initialize tool: %v", err) } - params := tools.ParamValues{} + params := parameters.ParamValues{} _, err = tool.Invoke(ctx, params, "") if err == nil { diff --git a/tests/cloudmonitoring/cloud_monitoring_integration_test.go b/tests/cloudmonitoring/cloud_monitoring_integration_test.go index f7f9a8d427..b976cb3570 100644 --- a/tests/cloudmonitoring/cloud_monitoring_integration_test.go +++ b/tests/cloudmonitoring/cloud_monitoring_integration_test.go @@ -22,8 +22,8 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools/cloudmonitoring" + "github.com/googleapis/genai-toolbox/internal/util/parameters" ) func TestTool_Invoke(t *testing.T) { @@ -50,13 +50,13 @@ func TestTool_Invoke(t *testing.T) { Name: "test-cloudmonitoring", Kind: "cloud-monitoring-query-prometheus", Description: "Test Cloudmonitoring Tool", - AllParams: tools.Parameters{}, + AllParams: parameters.Parameters{}, BaseURL: server.URL, Client: &http.Client{}, } // Define the test parameters - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "projectId", Value: "test-project"}, {Name: "query", Value: "up"}, } @@ -94,13 +94,13 @@ func TestTool_Invoke_Error(t *testing.T) { Name: "test-cloudmonitoring", Kind: "clou-monitoring-query-prometheus", Description: "Test Cloudmonitoring Tool", - AllParams: tools.Parameters{}, + AllParams: parameters.Parameters{}, BaseURL: server.URL, Client: &http.Client{}, } // Define the test parameters - params := tools.ParamValues{ + params := parameters.ParamValues{ {Name: "projectId", Value: "test-project"}, {Name: "query", Value: "up"}, } diff --git a/tests/common.go b/tests/common.go index 7164ba250d..0f0ad50d3e 100644 --- a/tests/common.go +++ b/tests/common.go @@ -29,7 +29,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmysql" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/jackc/pgx/v5/pgxpool" ) @@ -280,9 +280,9 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS "source": "my-instance", "description": "Create table tool with template parameters", "statement": "CREATE TABLE {{.tableName}} ({{array .columns}})", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("columns", "The columns to create", tools.NewStringParameter("column", "A column name that will be created")), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("columns", "The columns to create", parameters.NewStringParameter("column", "A column name that will be created")), }, } toolsMap["insert-table-templateParams-tool"] = map[string]any{ @@ -290,10 +290,10 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS "source": "my-instance", "description": "Insert tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("columns", "The columns to insert into", tools.NewStringParameter("column", "A column name that will be returned from the query.")), - tools.NewStringParameter("values", "The values to insert as a comma separated string"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("columns", "The columns to insert into", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), + parameters.NewStringParameter("values", "The values to insert as a comma separated string"), }, } toolsMap["select-templateParams-tool"] = map[string]any{ @@ -301,8 +301,8 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS "source": "my-instance", "description": "Create table tool with template parameters", "statement": selectAll, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ @@ -310,9 +310,9 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS "source": "my-instance", "description": "Create table tool with template parameters", "statement": tmplSelectCombined, - "parameters": []tools.Parameter{tools.NewIntParameter("id", "the id of the user")}, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "parameters": []parameters.Parameter{parameters.NewIntParameter("id", "the id of the user")}, + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ @@ -320,9 +320,9 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT {{array .fields}} FROM {{.tableName}} ORDER BY id", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("fields", "The fields to select from", tools.NewStringParameter("field", "A field that will be returned from the query.")), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("fields", "The fields to select from", parameters.NewStringParameter("field", "A field that will be returned from the query.")), }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ @@ -330,10 +330,10 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS "source": "my-instance", "description": "Create table tool with template parameters", "statement": tmplSelectFilterCombined, - "parameters": []tools.Parameter{tools.NewStringParameter("name", "the name of the user")}, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewStringParameter("columnFilter", "some description"), + "parameters": []parameters.Parameter{parameters.NewStringParameter("name", "the name of the user")}, + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewStringParameter("columnFilter", "some description"), }, } toolsMap["drop-table-templateParams-tool"] = map[string]any{ @@ -341,8 +341,8 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS "source": "my-instance", "description": "Drop table tool with template parameters", "statement": "DROP TABLE IF EXISTS {{.tableName}}", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } config["tools"] = toolsMap diff --git a/tests/firebird/firebird_integration_test.go b/tests/firebird/firebird_integration_test.go index 0bcb3c3765..af0246d11c 100644 --- a/tests/firebird/firebird_integration_test.go +++ b/tests/firebird/firebird_integration_test.go @@ -26,7 +26,7 @@ import ( "github.com/google/uuid" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/googleapis/genai-toolbox/tests" _ "github.com/nakagami/firebirdsql" ) @@ -362,9 +362,9 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin "source": "my-instance", "description": "Create table tool with template parameters", "statement": "CREATE TABLE {{.tableName}} ({{array .columns}})", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("columns", "The columns to create", tools.NewStringParameter("column", "A column name that will be created")), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("columns", "The columns to create", parameters.NewStringParameter("column", "A column name that will be created")), }, } toolsMap["insert-table-templateParams-tool"] = map[string]any{ @@ -372,10 +372,10 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin "source": "my-instance", "description": "Insert table tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("columns", "The columns to insert into", tools.NewStringParameter("column", "A column name that will be returned from the query.")), - tools.NewStringParameter("values", "The values to insert as a comma separated string"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("columns", "The columns to insert into", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), + parameters.NewStringParameter("values", "The values to insert as a comma separated string"), }, } toolsMap["select-templateParams-tool"] = map[string]any{ @@ -383,8 +383,8 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin "source": "my-instance", "description": "Select table tool with template parameters", "statement": "SELECT id AS \"id\", name AS \"name\", age AS \"age\" FROM {{.tableName}}", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ @@ -392,11 +392,11 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin "source": "my-instance", "description": "Select table tool with combined template parameters", "statement": tmplSelectCombined, - "parameters": []tools.Parameter{ - tools.NewIntParameter("id", "the id of the user"), + "parameters": []parameters.Parameter{ + parameters.NewIntParameter("id", "the id of the user"), }, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ @@ -404,8 +404,8 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin "source": "my-instance", "description": "Select specific fields tool with template parameters", "statement": "SELECT name AS \"name\" FROM {{.tableName}}", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ @@ -413,12 +413,12 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin "source": "my-instance", "description": "Select table tool with filter template parameters", "statement": tmplSelectFilterCombined, - "parameters": []tools.Parameter{ - tools.NewStringParameter("name", "the name to filter by"), + "parameters": []parameters.Parameter{ + parameters.NewStringParameter("name", "the name to filter by"), }, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewStringParameter("columnFilter", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewStringParameter("columnFilter", "some description"), }, } // Firebird uses simple DROP TABLE syntax without IF EXISTS @@ -427,8 +427,8 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin "source": "my-instance", "description": "Drop table tool with template parameters", "statement": "DROP TABLE {{.tableName}}", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } config["tools"] = toolsMap diff --git a/tests/http/http_integration_test.go b/tests/http/http_integration_test.go index faa239d2e6..dcaab03011 100644 --- a/tests/http/http_integration_test.go +++ b/tests/http/http_integration_test.go @@ -29,7 +29,7 @@ import ( "time" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/googleapis/genai-toolbox/tests" ) @@ -510,14 +510,14 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "method": "GET", "path": "/tool1", "description": "some description", - "queryParams": []tools.Parameter{ - tools.NewIntParameter("id", "user ID")}, + "queryParams": []parameters.Parameter{ + parameters.NewIntParameter("id", "user ID")}, "requestBody": `{ "age": 36, "name": "{{.name}}" } `, - "bodyParams": []tools.Parameter{tools.NewStringParameter("name", "user name")}, + "bodyParams": []parameters.Parameter{parameters.NewStringParameter("name", "user name")}, "headers": map[string]string{"Content-Type": "application/json"}, }, "my-tool-by-id": map[string]any{ @@ -526,8 +526,8 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "method": "GET", "path": "/tool1id", "description": "some description", - "queryParams": []tools.Parameter{ - tools.NewIntParameter("id", "user ID")}, + "queryParams": []parameters.Parameter{ + parameters.NewIntParameter("id", "user ID")}, "headers": map[string]string{"Content-Type": "application/json"}, }, "my-tool-by-name": map[string]any{ @@ -536,8 +536,8 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "method": "GET", "path": "/tool1name", "description": "some description", - "queryParams": []tools.Parameter{ - tools.NewStringParameterWithRequired("name", "user name", false)}, + "queryParams": []parameters.Parameter{ + parameters.NewStringParameterWithRequired("name", "user name", false)}, "headers": map[string]string{"Content-Type": "application/json"}, }, "my-query-param-tool": map[string]any{ @@ -546,10 +546,10 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "method": "GET", "path": "/toolQueryTest", "description": "Tool to test optional query parameters.", - "queryParams": []tools.Parameter{ - tools.NewStringParameterWithRequired("reqId", "required ID", true), - tools.NewStringParameterWithRequired("page", "optional page number", false), - tools.NewStringParameterWithRequired("filter", "optional filter string", false), + "queryParams": []parameters.Parameter{ + parameters.NewStringParameterWithRequired("reqId", "required ID", true), + parameters.NewStringParameterWithRequired("page", "optional page number", false), + parameters.NewStringParameterWithRequired("filter", "optional filter string", false), }, }, "my-auth-tool": map[string]any{ @@ -559,9 +559,9 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "path": "/tool2", "description": "some description", "requestBody": "{}", - "queryParams": []tools.Parameter{ - tools.NewStringParameterWithAuth("email", "some description", - []tools.ParamAuthService{{Name: "my-google-auth", Field: "email"}}), + "queryParams": []parameters.Parameter{ + parameters.NewStringParameterWithAuth("email", "some description", + []parameters.ParamAuthService{{Name: "my-google-auth", Field: "email"}}), }, }, "my-auth-required-tool": map[string]any{ @@ -582,21 +582,21 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "headers": map[string]string{ "X-Custom-Header": "example", }, - "pathParams": []tools.Parameter{ - &tools.StringParameter{ - CommonParameter: tools.CommonParameter{Name: "path", Type: "string", Desc: "path param"}, + "pathParams": []parameters.Parameter{ + ¶meters.StringParameter{ + CommonParameter: parameters.CommonParameter{Name: "path", Type: "string", Desc: "path param"}, }, }, - "queryParams": []tools.Parameter{ - tools.NewIntParameter("id", "user ID"), tools.NewStringParameter("country", "country"), + "queryParams": []parameters.Parameter{ + parameters.NewIntParameter("id", "user ID"), parameters.NewStringParameter("country", "country"), }, "requestBody": `{ "place": "zoo", "animals": {{json .animalArray }} } `, - "bodyParams": []tools.Parameter{tools.NewArrayParameter("animalArray", "animals in the zoo", tools.NewStringParameter("animals", "desc"))}, - "headerParams": []tools.Parameter{tools.NewStringParameter("X-Other-Header", "custom header")}, + "bodyParams": []parameters.Parameter{parameters.NewArrayParameter("animalArray", "animals in the zoo", parameters.NewStringParameter("animals", "desc"))}, + "headerParams": []parameters.Parameter{parameters.NewStringParameter("X-Other-Header", "custom header")}, }, }, } diff --git a/tests/spanner/spanner_integration_test.go b/tests/spanner/spanner_integration_test.go index 77c485209c..d54fabdda6 100644 --- a/tests/spanner/spanner_integration_test.go +++ b/tests/spanner/spanner_integration_test.go @@ -32,7 +32,7 @@ import ( "cloud.google.com/go/spanner/admin/database/apiv1/databasepb" "github.com/google/uuid" "github.com/googleapis/genai-toolbox/internal/testutils" - "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/googleapis/genai-toolbox/tests" ) @@ -334,10 +334,10 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Insert tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("columns", "The columns to insert into", tools.NewStringParameter("column", "A column name that will be returned from the query.")), - tools.NewStringParameter("values", "The values to insert as a comma separated string"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("columns", "The columns to insert into", parameters.NewStringParameter("column", "A column name that will be returned from the query.")), + parameters.NewStringParameter("values", "The values to insert as a comma separated string"), }, } toolsMap["select-templateParams-tool"] = map[string]any{ @@ -345,8 +345,8 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT * FROM {{.tableName}}", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ @@ -354,9 +354,9 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT * FROM {{.tableName}} WHERE id = @id", - "parameters": []tools.Parameter{tools.NewIntParameter("id", "the id of the user")}, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), + "parameters": []parameters.Parameter{parameters.NewIntParameter("id", "the id of the user")}, + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ @@ -364,9 +364,9 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT {{array .fields}} FROM {{.tableName}}", - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewArrayParameter("fields", "The fields to select from", tools.NewStringParameter("field", "A field that will be returned from the query.")), + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewArrayParameter("fields", "The fields to select from", parameters.NewStringParameter("field", "A field that will be returned from the query.")), }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ @@ -374,10 +374,10 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = @name", - "parameters": []tools.Parameter{tools.NewStringParameter("name", "the name of the user")}, - "templateParameters": []tools.Parameter{ - tools.NewStringParameter("tableName", "some description"), - tools.NewStringParameter("columnFilter", "some description"), + "parameters": []parameters.Parameter{parameters.NewStringParameter("name", "the name of the user")}, + "templateParameters": []parameters.Parameter{ + parameters.NewStringParameter("tableName", "some description"), + parameters.NewStringParameter("columnFilter", "some description"), }, } config["tools"] = toolsMap